全部博文(156)
分类: LINUX
2010-11-19 19:45:36
解压后内核启动概要分析
1. 确定 processor type 和machine type信息
2. 创建页表
3. 开启mmu
4. 切换数据
5. start_kernel函数
start_kernel是所有 Linux 平台进入系统内核初始化后的入口函数,它主要完成剩余的与 硬件平台相关的初始化工作,在进行一系列与内核相关的初始化后,调用第一个用户进程-—init 进程并等待用户进程的执行,这样整个 Linux 内核便启动完毕
1) 调用 setup_arch()函数进行与体系结构相关的第一个初始化工作;
对不同的体系结构来说该函数有不同的定义。对于 ARM 平台而言,该函数定义在
arch/arm/kernel/Setup.c。它首先通过检测出来的处理器类型进行处理器内核的初始化,然后
通过 bootmem_init()函数根据系统定义的 meminfo 结构进行内存结构的初始化,最后调用
paging_init()开启 MMU,创建内核页表,映射所有的物理内存和 IO空间。
2) 创建异常向量表和初始化中断处理函数;
3) 初始化系统核心进程调度器和时钟中断处理机制;
4) 初始化串口控制台(serial-console);
ARM-Linux 在初始化过程中一般都会初始化一个串口做为内核的控制台,这样内核在
启动过程中就可以通过串口输出信息以便开发者或用户了解系统的启动进程。
5) 创建和初始化系统 cache,为各种内存调用机制提供缓存,包括;动态内存分配,虚拟文
件系统(VirtualFile System)及页缓存。
6) 初始化内存管理,检测内存大小及被内核占用的内存情况;
7) 初始化系统的进程间通信机制(IPC);
当以上所有的初始化工作结束后,start_kernel()函数会调用 rest_init()函数来进行最后的
初始化,包括创建系统的第一个进程-init 进程来结束内核的启动。Init 进程首先进行一系
列的硬件初始化,然后通过命令行传递过来的参数挂载根文件系统。最后 init 进程会执行用
户传递过来的“init=”启动参数执行用户指定的命令,或者执行以下几个进程之一:
execve("/sbin/init",argv_init,envp_init);
execve("/etc/init",argv_init,envp_init);
execve("/bin/init",argv_init,envp_init);
execve("/bin/sh",argv_init,envp_init)。
当所有的初始化工作结束后,cpu_idle()函数会被调用来使系统处于闲置(idle)状态并
等待用户程序的执行。至此,整个 Linux 内核启动完毕。