简析linux内核的内核执行流程图
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
简析linux核的执行流程
----从bootsect.s到main.c(核版本0.11)Linux启动的第一阶段(从开机到main.c)
3个任务:
A、启动BIOS,准备实模式下的中断向量表和中断服务程序。
B、从启动盘加载操作系统程序到存。
C、为执行32的main函数做过渡准备。
存变化如下:
①、0xFE000到0xFFFFF是BIOS启动块,其中上电后第一条指令在0xFFFF0。
②、而后0x00000到0x003FF总共1KB存放中断向量表,而接下去的地址到0x004FF共256B存放BIOS数据,从0x0E05B 开始的约8KB的存中存放中断服务程序。
③、利用BIOS中断0x19h把硬盘的第一扇区bootsect.s的代码加载到存中,即0x07c00处,后转到该处执行。
④、将bootsect.s的代码复制到0x90000处。
⑤、利用中断0x13h将setup.s程序加载到存0x90200处。
⑥、再将剩余的约240个扇区的容加载到0x10000~0x2EFFF 处。
⑦、开始转到setup.s处执行,第一件事就利用BIOS提供的中断服务程序从设备上获取核运行的所需系统数据并存在0x90000的地址处,这时将原来bootsect.s的代码覆盖得只剩2Byte的空间。
⑧、关中断并将系统代码复制到0x00000处,将原来放在这里的中断向量表与BIOS数据区覆盖掉,地址围是
0x00000~0x1EFFF。同时制作两表与两寄存器。
⑨开地址线A20,寻址空间达到4GB,后对8259重新编程,改变中断号。
⑩、转到head.s(大小是25K+184B)执行,执行该程序完后是这样的:
0x00000~0x04FFF:页目录与4个页表,每一项是4KB,共20KB;0x05000~0x05400:共1KB的空间是软盘缓冲区;
0x05401~0x054b8:共184B没用;
0x054b9~0x05cb8:共2KB的空间存中断描述符表;
0x05cb9~0x064b8:共2KB的空间存全局描述符表;
之后就是main函数的代码了!
第二阶段、从main.c函数到系统准备完毕阶段。
第一步:创建进程0,并让进程0具备在32位保护模式下载主机中的运算能力。流程是:
复制根设备和硬盘参数表(main.c中的102、110、111行)
物理存规划格局(main.c的112行~126行,其中有
rd_init函数定义在kernel/ramdisk.c中,此函数用于虚拟盘初始化;而mem_init函数是用于存管理结构初始化,定义在mem/memory.c中,该函数页面使用
虚拟盘设置与初始化次数均设置成100,然后再依据主存的
起始位置和终止位置将处于主存的所有页面的使
用次数全部清零,系统以后把使用次数为0的页面视为空闲页面。)
存管理结构mem_map初始化
异常处理类中断服务程序挂接(在main.c的127行,trap()函数定义
kernel/trap.c,目的是将各种中断与中断描述符表挂
接。)
初始化块设备与字符设备请求项结构(在main.c的128、129行,
blk_dev_init() 定义在
kernel/blk_dev/ll_rw_blk.c,
chr_dev_init()定义在
kernel/chr_dev/tty_io.c)
将串口与显示器外设的中断服务程序挂接(在main.c的130行,
tty_init()定义在kernel/chr_dev/tty_io.c)
开启时间设置(在main.c的131行,time_init()定义于main.c函数
76行startup_time)
系统开始激活进程0(在main.c的131行,sched_init()定义在kernel/
sched.c函数中,该函数实现进程相关事务设置
依据时钟中断设置,系统调用服务程序挂接。系
统调用函数是对用户程序的最基本支持,利用的是进程相关事务初始化设置系统调用软中断,详细见下面讲
的。)
时钟中断设置
系统调用服务程序挂接
初始化缓冲区管理结构(在main.c中133行,
buffer_init(buffer_memory_end)定义
fs/buffer.c)
初始化硬、软盘(main.c中134、135行,hd_init与floppy_init 定义于kernel/blk_drv/hd.c和
kernel/blk_drv/floppy.c)
开中断(main.c中136行,sti())
第二步:以进程0为母本创建进程1,使进程1不仅仅具备进程0所拥有的能力,而且还能以文件的形式与外设进行数据交互。流程是:操作系统为进程0创建进程1做准备main.c中137行,move_to_
user_mode()定义在include/asm/system.h,实现从
核态到用户态。进程0正式开始执行,而后
执行main.c的138行的“if(!fork())”,开始创建在进程槽中为进程1申请一个空闲位置并获取进程号
进程1,此时将执行unisted.h中的syscall0宏函数
,得到一个编号,对于fork函数,其值是2,具体
在这个程序中的第62行有定义,然后执行软中断复制进程0的信息之前,先将一些数据压栈
,进入系统调用阶段,跳到核态,执行
kernel/system_call.s中的代码,将一些寄存器的