Presentation is loading. Please wait.

Presentation is loading. Please wait.

Linux 内核源代码导读 中国科学技术大学计算机系 陈香兰( 0551 - 3606864 ) Spring 2009.

Similar presentations


Presentation on theme: "Linux 内核源代码导读 中国科学技术大学计算机系 陈香兰( 0551 - 3606864 ) Spring 2009."— Presentation transcript:

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 了解第一个扇区的内容

6

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 个字节的内容

19

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

33

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 运行环境的初 始化

43

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.


Download ppt "Linux 内核源代码导读 中国科学技术大学计算机系 陈香兰( 0551 - 3606864 ) Spring 2009."

Similar presentations


Ads by Google