Linux系统内核的执行流程总结

2020-06-03 15:46

目前Linux系统已经变得非常复杂,所以如果我们想学习Linux,当然我们必须从最简单的版本开始。此时,内核启动过程并不像现在这样复杂,而且也很容易理解。

工具/原材料Linux系统方法/步骤1 Linux启动的第一阶段(从启动到主要阶段)3个任务:

A.启动基本输入输出系统,在实际模式下准备中断向量表和中断服务程序。

引导盘将操作系统程序加载到内存中。

C.准备过渡以执行32的主要功能。

内存变化如下:

① 0xFE000至0xFFFF为基本输入输出系统启动模块,上电后第一条指令为0xFFFF0。

(2)在0x00000到0x003FF之后,总共1KB存储中断向量表,而在0x004FF以下的地址,总共256B存储基本输入输出系统数据,并且从0x0E05B开始的大约8KB的存储器存储中断服务程序。

(3)使用BIOS中断0x19h将硬盘的第一个扇区bootsect.s的代码加载到内存中,即0x07c00,然后转移到内存中执行。

(4)将引导代码复制到0x90000。

⑤用中断0x13h将setup.s程序加载到存储器0x90200中。

⑥将剩余240个扇区的内容加载到0x10000 ~ 0x2EFFF。

首先要做的是使用基本输入输出系统提供的中断服务程序,从设备和地址0x90000中获取内核运行所需的系统数据。此时,原始的bootsect.s代码只包含2字节。

⑧关闭中断,将系统代码复制到0x00000,覆盖原来放置在此的中断向量表和基本输入输出系统数据区,地址范围为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的空间;

之后是主要功能的代码!

第二阶段,从主. c功能到系统准备阶段。

步骤1:创建进程0,让进程0在32位保护模式下载主机中拥有计算能力。过程是:

复制根设备和硬盘参数表(main.c中的第102、110和111行)

物理内存规划模式(主要c 112 ~126行,包括

rd_init函数在内核/ramdisk中定义,该函数用于虚拟磁盘初始化。mem_init函数用于初始化内存管理结构。它在MEM/内存中定义。使用虚拟磁盘的功能页面的设置和初始化时间都设置为100。然后,根据主存储器的起始位置和结束位置,完全清除主存储器中所有页面的激活次数。系统将来会将使用次数为0的页面视为空闲页面。)

内存管理结构内存映射初始化

异常处理类中断服务程序钩子(在main.c,trap()函数定义的第127行

内核/trap.c,目的是用中断描述符表挂钩各种中断。)

初始化块设备和字符设备请求项结构(在main.c的第128和129行中,blk_dev_init()在内核/blk_dev/ll_rw_blk.c中定义,

Chr_dev_init()在内核/chr_dev/tty_io.c)中定义

将串行端口与显示外设的中断服务程序连接(在主控制器的第130行,

Tty_init()在内核/chr_dev/tty_io.c)中定义

打开时间设置(在main.c的第131行,time_init()在main.c函数中定义

76行启动时间)

系统开始激活进程0(在main.c的第131行,sched_init()在内核/中定义

在sched.c函数中,此函数实现与流程相关的事务设置。

根据时钟中断设置,系统调用服务程序钩子。系统调用功能是对用户程序最基本的支持。它使用与进程相关的事务初始化来设置系统调用软中断。详情见下文。)

时钟中断设置

系统呼叫服务程序挂钩

初始化缓冲区管理结构(在main.c中有133行,buffer_init(buffer_memory_end)定义fs/buffer.c)

初始化硬盘和软盘(main.c hd_init和floppy_init中的第134行和第135行在kernel/blk_drv/hd.c和kernel/blk_drv/floppy.c中定义)

断开中断(主电路中的136条线路,sti())

步骤2:创建进程1,进程0作为母进程,这样进程1不仅具有进程0所拥有的功能,还可以以文件的形式与外围设备交互。过程是:

操作系统准备进程0来创建进程1。main.c中有137行,move _ to _

User_mode()在include/asm/system.h中定义,用于从内核状态到用户状态的实现。进程0正式开始执行,然后执行138行的“如果(!idspninfopath)文件。Fork()),将创建进程1。此时,unisted.h中的syscall0宏函数将被执行以获取一个数字。对于fork函数,它的值是2,在程序的第62行定义,然后将执行软中断。

在复制进程0的信息之前,将一些数据推入系统调用阶段,跳转到内核状态,执行内核/system_call.s中的代码,将一些寄存器的值推入堆栈,并在unisted.h中为eax分配一个值。

设置进程1管理结构的2偏移值,初步在系统调用sys_call_table中找到sys_fork函数,并跳转到该函数的执行。进入后,首先申请一个空闲位置并获得流程号。

这也发生在由system_call.s函数中的sys_fork进程0创建进程1的过程中。时钟中断中的_find_copy_process发生,然后跳转到内核/fork.c,在那里定义函数,然后返回sys_fork。在从中断返回复制过程信息之前,一些数据被推到堆栈上。此时,有一个寄存器的值与前一个不同,即eax,此时为1,来自taskLinux系统内核的执行流程总结END

联系我们

天津市西青区中北镇云锦世家南门55号
4007181001
30998@qq.com

庆典活动

商务会议

企业年会

展会展览