Linux内核学习日记

本文详细记录了Linux内核从引导启动程序到系统初始化的全过程,包括bootsect.s、setup.s、head.s的执行,以及init程序的初始化设置。介绍了硬件中断、软件中断的处理,系统调用的实现,以及调度处理、输出管理和设备驱动程序。内容涵盖内存管理、文件系统和内核代码的关键部分,为理解Linux内核提供了深入见解。
摘要由CSDN通过智能技术生成

参考资料

  • 《Linux内核完全注释》
  • linux 0.11源码
  • B站视频
  • CSDN博客
    !!以下图片来自《Linux内核完全注释 修正版V3.0》!!

日记1:系统总体流程

liunx0.11内核源码目录结构
图1 位于P177

  • 系统从boot开始动作,把内核从启动盘装到正确的位置。进行一些基本的初始化,如检测内存,保护模式相关,建立页目录和内存页表,GDT表,IDT表。

  • 进入init,在main中进行初始化设置。main完成系统各个模块要用到的所有数据结构和外部设备的初始化,使得系统可以正常的工作。

  • 切换至用户模式。执行fork()生成用于运行init()的子进程,运行shell,接受并执行用户命令。

  • 至此,整个系统建立起来了,OS就处于被动状态,靠中断和系统调用来完成每一项服务。

     暂无
    

日记2:(boot)引导启动程序

引导流程
图2 位于P192

–1.bootsect.s

  • bootsect.s编译生成一个512byte(一个扇区)镜像。
  • 这段代码必须写入到启动盘的启动扇区,也就是第一个物理扇区上。(机器启动后,BIOS会自动把它加载到0x7c00处并跳到那里开始执行)
  • bootsect将自己移动到0x90000处,并跳至那里相应位置执行。
  • 随后利用BIOS中断将setup直接加载到自己的后面,并将system模块加载到地址0x10000处。
  • 最后跳到setup开始处继续执行。

–2.setup.s

  • 利用BIOS中断把系统参数(如显卡、硬盘参数)保存到内存0x90000开始的位置,即覆盖原bootsect所在的内存位置。
  • 随后把整个system模块移动到0x00000处。
  • 加载GDT表和IDT表,这里的GDT表是临时的,保存了两个描述符,即内核代码、内核数据段描述符,其段基地址为0。
  • 开启A20 地址线开启扩展内存。
  • 重新设置8259中断码0x20~0x2f。
  • 进入32位保护模式,并跳转到system模块中的head.s中开始处继续执行。

–3.head.s

head.s执行结束后的内存映像
图3 P231

  • 从这里开始内核完成都是在保护模式下运行。

  • 加载各个数据寄存器,设置系统堆栈为_stack_start,重新设置中断描述符表IDT以及GDT表。

  • 设置好管理内存的分页处理机制。

  • 最后,利用返回指令将预先放置在堆栈中的/init/main.c的入口地址弹出,去运行main()程序。

     细节:描述符表、保护模式、分页处理机制
     问题:
     	a.描述符表有什么用?怎么用?为什么这样设计?
     	b.保护模式是什么?有什么用?
     	c.分页处理机制怎么管理内存?代码如何实现?
    

日记3:(init)初始化程序

内核初始化程序流程
图4 P236
init目录下仅有main.c一个文件

  • 对主内存进行划分和分配,调用各模块相应的初始化函数完成相应的初始化设置。

  • 进入用户模式(把自己“手工”移动到进程0中运行),创建进程1执行init(),常驻进程0死循环执行pause()。

  • 进程1加载根文件系统,设置终端标准IO,创建进程2。

  • 进程2以/etc/rc为标准输入文件执行shell,完成rc文件中的命令,然后退出并回到进程1。

  • 进程1创建子进程,建立新会话,设置标准IO终端,并运行用户登录shell程序(/bin/sh),以创建用户交互shell环境。

  • 至此,Linux系统开机完毕。其它的动作由用户在shell下执行命令,产生系统调进行工作。

     细节:初始化、多进程、shell
     问题:
     	a.内核各部分数据结构的建立、初始化、操作是怎样进行的?
     	b.进程的相关代码是怎样设计的?
     	c.shell的实现
    
'''
#至此,我对liunx系统的建立有了基本的了解
#后续的日记不用按顺序阅读,可以先挑你中意的内容开始
'''

————————————————————————————————————————————

日记4:(kernel)内核代码

kernel代码目录
图5 P252

–日记4.0:(mktime.c)

  • 该程序仅供内核使用。
  • 其中仅有的函数kernel_mktime()的功能是计算从1970年1月1日0时起到开机当日经过的秒数。

–日记4.1:中断处理

'''中断简述
当设备向处理器提出服务请求(IRQ)时
(0)处理器在执行完当前的一条指令后立刻应答设备请求
(1)并转而执行该设备的相关服务程序(ISR)
(2)当服务程序执行完成后,处理器会接着执行之前被中断的程序
'''
  • 按中断信号可分为:硬件中断和软件中断(系统调用)。
  • asm.s主要涉及对Intel保留中断int0-int16的处理。
  • system_call.s处理中断int128(即int0x80)。
  • 中断int17-int31由Intel公司留作今后扩展使用。
  • 中断int32-int47的16个中断对应处理分别在各个硬件(如时钟、键盘、软盘等)的初始化程序中。

—日记4.1.1:硬件中断(asm.s+traps.c)

asm.s用于处理大部分硬件异常引起的中断,主要实现中断的处理流程。
其他硬件中断(如时钟中断等)另作处理,但也极为重要!
traps.c用于实现asm.s的中断处理过程中调用的C语言程序。

一般硬件中断处理流程
图6 P253

—日记4.1.2:软件中断(system_call.s+调用的.c)

在linux0.11中,用户使用中断调用int128和放在寄存器eax中的功能号来使用内核提供的各种功能服务(即系统调用)。
通常用户并不能直接使用系统调用中断,而是通过函数库(例如libc)中提供的接口函数来调用。

一般软件中断处理流程
图7 P269

----1.signal.c
  • 该程序涉及内核中所有有关信号处理的函数。
----2.exit.c
  • 主要描述进程终止和退出的有关处理事宜。
----3.fork.c
  • 主要描述进程创建有关处理事宜。
----4.sys.c
  • 含有很多系统调用功能的实现函数。

–日记4.2:调度处理(schedule.c)

  • 有关任务(进程)调度管理的程序。

–日记4.3:输出处理(vsprintf.c+printk.c+panic.c)

  • vsprintf,格式化处理

  • printk,打印(显示)信息

  • panic,显示错误信息

     细节:处理信号识别、数学协处理器、进程状态
    

–日记4.4:设备驱动程序

OS的所有设备可粗略的分为块设备和字符设备。
块设备以固定大小的数据块进行操作。如:硬盘、软盘等。
字符设备以字符流作为操作对象。如:打印机、网络接口、键盘等。

—日记4.4.1:块设备驱动程序(blk_drv)

块设备目录结构
图片7 P345

—日记4.4.2:字符设备驱动程序(chr_drv)

字符设备目录结构
图片8 P419

–日记4.5:数学协处理器(math)

日记5:(fs)文件系统

  • Linux把所有设备都做为文件来看待,提供统一的打开,关闭,读写系统调用接口。
  • MINX文件系统
  • 高速缓冲区、文件系统底层函数、文件中数据的访问操作、文件和目录管理系统调用

日记6:(mm)内存管理

  • 分页管理方式

日记7:(tools)建构工具

编译建构
图片9 P797

————————————————————————————————————————————

	该文章为第一次速览《linux内核完全注释》的总结
	留有许多疑问和细节等待补充,继续加油!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值