Linux 系统内核初始化过程
转载自: http://linux.chinaunix.net/bbs/ 一、对硬件数据结构的初始化过程。 1、系统首先调用 printk() 函数在屏幕上打印 Linux 内核版本号和编译内核所使用的 gcc 编译器版本号、启用时间等,如果这个过程失败,将显示一个参考信息给用户。 2、调用 arch/i386/kernel/setup.c 中的 setup_arch() 函数,初始化系统主板上各个集成电路控制器,最后在 command line、memory_start 和 memory_end 中返回结果。 获取外设的参数。将硬盘、鼠标、显示器、根设备的主从设备号、高级电源管理以及总线类型等参数, 写入相关的内存单元。 如果设置了 RAM盘,则把各参数写入相应的内存单元。 设置 init_task.mm 代码结构在内存中的起点和终点以及数据段的终点。 把命令行参数拷贝到 save_command_line 变量。分析、排除 “mem=”形式的命令。获取 CPU类型,以判断是否支持扩展分页,即允许页框大小为 4MB的页。调整内存边界参数 start_mem 。 调用 reguest_region() 函数为主板上的 I/O芯片申请I/O内存使用空间。这些集成芯片是 timer定时计数器、DMA控制器1、DMA控制器2以及协处理器 fpu。 3、调用 arch/i386/init.c 中的 paging_init() 函数初始化内核页表。它实现的功能如下: 调整 memory_start 按下一个可用页边界对齐。 对临时页目录表项中的第 0 个目录项清零,这样就将从 0 开始的最初 4MB 的线性地址和物理地址消除,以便使用户可使用0 到 4194303 之间的线性地址空间。 初始化页目录的第0项到768项以及各个目录项对应的页表表项。 4、调用 arch/i386/kernel/trap.c 中的 trap_init() 函数中对中断描述符表IDT进行初始化。为了使用异常处理,trap_init() 函数将处理异常的函数地址的选择符写入 IDT的陷阱门描述符中。这些门的设置时由 set_trap_gate() 和set_system_gate() 函数来完成的。 5、调用 arch/i386/kernel/irq.c 中的 init_IRQ() 函数。设置基准时...