a.首先,x86 CPU加电,初始化自己进入16位实模式,然后跳转到0xFFFF0,BIOS地址,调用显卡Bios初始化显卡,进行自检,然后装载可引导设备的第一个扇区到0x7c00,然后跳转到那儿。这部分代码其实是arch\i386\boot\bootsect.S。新的内核已经不支持从bootsect启动,bootsect.S其实只是提示用户按任何键重启。因为现在的可引导设备的第一个扇区是lilo或grub,然后由他们装载lilo或grub引导代码进入0x90000,然后装载内核setup代码进入0x90200,然后装载内核剩余部分进入0x10000。
b.内核setup代码就是arch\i386\boot\setup.S,它读取硬盘参数, 检查签名0xAA55.0x5A5A, 检查是否大内核(检查标志),使用不同的方法获取内存大小,初始化设置键盘硬件。检查显卡及其参数,然后调用。video.S中的video函数。
c.video 检查内核参数,vga= 让用户选择视频模式,然后返回Setup.S。
d.然后将内核从0x10000移动到0x1000这部分代码的开始就是arch\i386
\boot\compressed\head.S。然后进入32位保护模式。然后跳转到head.S 中startup_32=0x1000。注意:以上全是汇编代码。
e.然后head.S调用arch\i386\boot\compressed\misc.c中的decompress_kernel函数(C语言代码),然后调用lib\inflate.c中的gunzip函数,将内核解压缩到0x100000(32位指针)。然后显示”Uncompressing Linux...”。最后返回head.S
f.然后进入arch\i386\kernel\head.S。(汇编语言)在这里初始化内存页表(PT),初始化(IDT)中断描述表。检查CPU类型,配置对称多处理器。接着调用start_kernel在init\main.c中这个函数永不返回。致此,开始启动内核,之后的代码都变成了C语言代码。start_kernel中才是真正的linux内核初始化,启动过程。
g.然后内核调用init函数,这个函数查找并调用
/sbin/init
/etc/init
/bin/init
直到一个成功,init命令会根据/etc/inittab中设定的运行等级决定调用的rc(/etc/inittab中列出)。
如果都不成功启动
/bin/sh
b.内核setup代码就是arch\i386\boot\setup.S,它读取硬盘参数, 检查签名0xAA55.0x5A5A, 检查是否大内核(检查标志),使用不同的方法获取内存大小,初始化设置键盘硬件。检查显卡及其参数,然后调用。video.S中的video函数。
c.video 检查内核参数,vga= 让用户选择视频模式,然后返回Setup.S。
d.然后将内核从0x10000移动到0x1000这部分代码的开始就是arch\i386
\boot\compressed\head.S。然后进入32位保护模式。然后跳转到head.S 中startup_32=0x1000。注意:以上全是汇编代码。
e.然后head.S调用arch\i386\boot\compressed\misc.c中的decompress_kernel函数(C语言代码),然后调用lib\inflate.c中的gunzip函数,将内核解压缩到0x100000(32位指针)。然后显示”Uncompressing Linux...”。最后返回head.S
f.然后进入arch\i386\kernel\head.S。(汇编语言)在这里初始化内存页表(PT),初始化(IDT)中断描述表。检查CPU类型,配置对称多处理器。接着调用start_kernel在init\main.c中这个函数永不返回。致此,开始启动内核,之后的代码都变成了C语言代码。start_kernel中才是真正的linux内核初始化,启动过程。
g.然后内核调用init函数,这个函数查找并调用
/sbin/init
/etc/init
/bin/init
直到一个成功,init命令会根据/etc/inittab中设定的运行等级决定调用的rc(/etc/inittab中列出)。
如果都不成功启动
/bin/sh