Linux 内核加载过程

最近在研究linux的内核加载过程,对于grub是如何引导linux的内核并启动还是有点混乱,结合网上找的一些资料总结了一下大概流程,部分是摘抄别人的,算是比较清晰思路了。


arch/i386/boot

    bootsect.S 生产引导扇区的汇编代码,完成后跳转到setup.S    (3.16.2内核对应x86的合并head.S),这个跟GRUB的功能差不多,如果grub设置在了mbr区引导,应该就不用这个了。
    setup.S 将系统参数(包括内存、磁盘等)拷贝到特别内存中,后面被保护模式的代码读取 (3.16.2内核对应x86的合并head.S),如果内核是压缩的,那么先执行compressed里面的head.S建立堆栈并解压内核映像文件再转入下面的head.S,如果不是压缩的内核则直接跳转。
    arch/i386/kernel/head.S 跳到0x100000之后,就是这个里面的startup_32 它也是vmlinuz的入口,负责数据区BBS,中断描述表IDT,段描述表GDT,页表和寄存器的初始化,然后就跳转到start_kernel()中去了,此时系统运行在内核模式(0级别),start_kernel()是init/main.c中的定义的函数。
   
start_kernel()主要是初始化系统的核心数据结构,主要包括: 
setup_arch():执行与体系结构相关的设置。 
trap_init():设置各种入口地址。 
init_IRQ():初始化IRQ中断处理机制。 
sched_init():设置并启动第一个进程init_task()。 
softirq_init():对软中断子系统进行初始化。 
console_init():初始化控制台、显示器. 
init_modules():初始化kernel_module。 
fork_init():定义系统最大进程数. 
最后进入rest_init()函数并调用kernel_thread()创建init内核线程,进行系统配置。 
init内核线程占用进程描述表的第一项,由它来创建其他完成系统初始化的进程。 
init内核线程首先要锁定内核,然后调用do_basic_setup()来初始化外部设备及加载驱动程序。主 
要的初始化工作包括: 
PCI总线初始化。 
网络初始化。 
文件系统初始化。 
加载文件系统。 
在do_basic_setup()调用完成后,init()会释放初始化函数据占用的内存,并且打开/dev/console 
设备重新定向控制台,用系统调用execve来执行用户态程序/sbin/init。至此,linux的内核初始化工作完成。
下面的工作就由用户态的/sbin/init程序来完成。init程序程读取/etc/inittab文件来决定它具体的工作。在inittab中比较重要的几条是: 
id:5:initdefault 决定操作系统启动时缺省的执行级别(这里说讲的是系统的运行级别,而不同于CPU的级别) 
si:sysinit:/etc/rc.d/rc.sysinit 执行/etc/rc.d/rc.sysinit的脚本。rc.sysinit主要的工作是 激活交换分区、检查磁盘、加载硬件模块。 
1:2345:respawn:/sbin/mingetty tty1 显示登录界面


     其它关键文件:
     arch/i386/bootvideeo.S  这个应该也是包含在setup.S中,检测和设置显示器的显示模式。
       arch/i386/boot/compressed/  最初引导过程是用里面的head.S利用misc.c中定义的decompress_kernel()函数将内核vmlinuz解压到0x100000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值