Download presentation
Presentation is loading. Please wait.
1
Linux 内核源代码导读 中国科学技术大学计算机系 陈香兰( 0551 - 3606864 ) xlanchen@ustc.edu.cn Spring 2009
2
回顾编译得到的 bzImage 的结构 Setup.bin+vmlinux.bin (具有自解压能力) head_32.o+misc.o+piggy.o vmlinux Head-y + init-y + main
3
基于 I386 的 Linux 的启动
4
计算机是如何启动的 BIOS 软盘启动 硬盘启动 Grub Lilo 启动协议
5
特殊的几个地址 BIOS :第一个扇区 0x07c0 第一个扇区的内容是什么? 观察 setup.ld 了解第一个扇区的内容
7
关键: 实模式 保护模式 分页模式 页表 GDT 表 IDT 表 阅读: documentation/i386/boot.txt
8
I386 内核从实模式开始运行 首先看一下什么是实模式 实模式是为了兼容早期的 CPU 而设置的 i386 系统总是始于实模式 实模式下 地址总线: 20 位 内存范围: 0~1MB 逻辑地址 = 段地址 + 段内偏移 段地址 = 段寄存器中的值 *16 (或左移 4 位) 段寄存器长度: 16bit 段寄存器有: cs/ds/es/fs/gs
9
保护模式下, 地址总线 32 位,访存范围为 4GB 原来的段寄存器现在被称作段选择子,与 GDT 表配合 使用 GDT 表由 gdtr 指示其位置和长度 使用特殊的指令进行操作: sgdt/lgdt
10
图示 descriptor Interrupt Descriptor Table Global Descriptor Table GDTR IDTR
11
一般装载 gdt 和 idt 之后,要重新装载段寄存器 cs 、 ds 、 es 、 fs 、 gs cs 通常通过一条长跳转指令装载 其他数据段寄存器直接设置
12
控制寄存器( Control Registers ) CR0 CR1 CR2 CR3 CR4 (扩展相关,忽略) 与内存相关
13
CR0 CR0, MSW register (Machine Status Word, 32-bit version) 包含系统控制位,用于控制操作模式和状态 Instruction: lmsw LINUX’ setup.S: movw $1, %ax lmsw %ax jmp flush_instr // why? flush_instr: To turn on the PE-bit (enables protected-mode), PE-bit (Protection Enabled) 0 CPU is in real-mode, 1 CPU is in protected-mode
14
CR1 、 CR2 、 CR3 CR1 :保留 CR2 :在缺页异常的时候,记录缺页地址 CR3 :记录页目录所在的物理地址和两个标记 (PCD & PWT)
15
阅读 documentation/i386/boot.txt 对于 i386 平台,由于一些历史的原因,因此 Linux 的启动比较复杂 这个文档包含如下内容 1 、 Linux/i386 的启动协议( 10 个 + ) 2 、内存布局图(大内核,小内核) 3 、实模式下的内核头结构(即 setup header )以及各参 数的解释 4 、内核的命令行( command line )
16
5 、实模式代码的内存布局 6 、启动配置示例 7 、装载 Linux 的剩余部分 8 、特殊的命令行参数 9 、运行内核 10 、高级启动回调函数 关于其中的一些内容,我们将在合适的时候说明
17
加载 I386 内核的内存布局图 zImage/Image 的内核加载器所使用的经 典的内存布局( 1M=0x100000 )为
18
Header.S 分析 前 512 个字节的内容
20
关于 msg_loop 输出的字符串 ??不支持软盘启动???
21
Header.S 分析 关于 512 字节的最后( setup header ) 在 setup.ld 中 在 Head.S 中 …
22
Header.S 分析 第二个扇区开始 接下来仍然是 setup header 参数部分,直到 start_of_setup
23
start_of_setup 设置堆栈 检查 setup 中的标签 清除 BSS 段 调用 C 入口 main start_of_setup _start(512 处 ) main
24
Main.c 分析 main go_to_protected_mode =? 重点:
25
关于 go_to_protected_mode 关键 move_kernel_around setup_idt setup_gdt protected_mode_jump :参见 pmjump.S 重点:
26
关于 protected_mode_jump 关键 进入保护模式 通过设置 cr0 进入 32 位代码 通过一条手工设置的代码 最后进入 setup header 中指定的 code32_start
27
关于 boot_params.hdr.code32_start 对 boot_params.hdr 的赋值之处: copy_boot_params Hdr 的定义之处 在 Head.S 中 …
28
code32_start 在 setup header 的第二部分 此处对应于压缩映像的 head_32.S
29
解压缩头中的 head_32.S 32 位代码 关键 1 :调用 decompress_kernel 关键 2 :跳转到 vmlinux 的头 head_32.S 阅读此目录下的 vmlinux_32.lds 了解入口处的代码
30
关于解压缩 head_32.S 中的 relocated 相关 即 “.text” 部分 Clear BSS Setup the stack for the decompressor Do the decompression, and jump to the new kernel..
31
Vmlinux 中的 head 观察 vmlinux.lds 观察 “.text.head” 、 “.text” 、 “.data” 等 .text.head Set segments to known values. Clear BSS first so that there are no surprises... Copy bootup parameters out of the way. Initialize page tables. Enable paging Set up the stack pointer Initialize eflags. call setup_idt check if it is 486 or 386. call check_x87 装载 GDT 、 IDT ,进入 3G 地址空间 jmp i386_start_kernel i386_start_kernel start_kernel startup_32 最后 重点
32
关于页表的初始化 观察 default_entry 后的代码,忽略 PAE 页目录: swapper_pg_dir :参见 head_32.S 第一个页表: pg0 :参见 vmlinux_32.lds
34
swapper_pg_dir
35
pg0 内核代码段 内核数据段 内核 BSS 段 低地址 高地址 pg0 swapper_pg_dir
36
初始化页目录和页表 对应线性地址 0 对应线性地址 3GB 1024 项 pg0swapper_pg_dir 物理地址 空间低端 4M … …
37
打开分页机制
38
关于 GDT 1 ) boot_gdt 2 ) per_cpu__gdt_page
39
关于堆栈 stack_start
40
关于 setup_idt 在 idt 表中,填写 ignore_int 几个特殊的项: 输出如下信息:
41
装载 GDT 、 IDT ,进入 3G 地址空间
42
关于 start_kernel 对 Linux 内核的各个部分进行初始化 Start_kernel 属于手工初始化的第一个进程( 0 号 进程),该进程最后执行 cpu_idle ,成为 idle 进程 系统创建的第一个进程( 1 号进程) 该进程最后找到一个 init 程序进行 Linux 运行环境的初 始化
44
upstart 管理的 ubuntu 启动过程: 1, 内核启动 init 2,init 找到 /etc/event.d/rc-default 文件,确定默认运行级别 (X) 3, 触发相应的 runlevel 事件,开始运行 /etc/event.d/rcX 4,rcX 运行 /etc/init.d/rc ,传入参数 X 5,/etc/init.d/rc 脚本进行一系列设置,最后运行相应的 /etc/rcX.d/ 中的脚本 6,/etc/rcX.d/ 中的脚本按事先设定的优先级依次启动,直至 最后给出登录画面 ( 启动 X 服务器和 GDM) 若不想启动某程序,只要把相应的符号链接从 /etc/rc2.d/ 中删去即可
45
Thanks ! The end.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.