Linux
This presentation is the property of its rightful owner.
Sponsored Links
1 / 45

Linux 内核源代码导读 PowerPoint PPT Presentation


  • 122 Views
  • Uploaded on
  • Presentation posted in: General

Linux 内核源代码导读. 中国科学技术大学计算机系 陈香兰( 0551 - 3606864 ) [email protected] Spring 2009. 回顾编译得到的 bzImage 的结构 Setup.bin+vmlinux.bin (具有自解压能力). head_32.o+misc.o+piggy.o. vmlinux. Head-y + init-y + main. 基于 I386 的 Linux 的启动. 计算机是如何启动的. BIOS 软盘启动 硬盘启动 Grub Lilo 启动协议. 特殊的几个地址

Download Presentation

Linux 内核源代码导读

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Linux

Linux内核源代码导读

中国科学技术大学计算机系

陈香兰(0551-3606864)

[email protected]

Spring 2009


Linux

  • 回顾编译得到的bzImage的结构

  • Setup.bin+vmlinux.bin(具有自解压能力)

head_32.o+misc.o+piggy.o

vmlinux

Head-y + init-y + main


I386 linux

基于I386的Linux的启动


Linux

计算机是如何启动的

  • BIOS

  • 软盘启动

  • 硬盘启动

  • Grub

  • Lilo

  • 启动协议


Linux

  • 特殊的几个地址

  • BIOS:第一个扇区0x07c0

  • 第一个扇区的内容是什么?

    • 观察setup.ld

      • 了解第一个扇区的内容


Linux

关键:

阅读: documentation/i386/boot.txt

  • 实模式

  • 保护模式

  • 分页模式

    • 页表

  • GDT表

  • IDT表


Linux

I386内核从实模式开始运行

首先看一下什么是实模式

  • 实模式是为了兼容早期的CPU而设置的

  • i386系统总是始于实模式

  • 实模式下

    • 地址总线:20位

    • 内存范围:0~1MB

    • 逻辑地址 = 段地址 + 段内偏移

      • 段地址 = 段寄存器中的值*16 (或左移4位)

      • 段寄存器长度:16bit

    • 段寄存器有:

      • cs/ds/es/fs/gs


Linux

  • 保护模式下,

    • 地址总线32位,访存范围为4GB

    • 原来的段寄存器现在被称作段选择子,与GDT表配合使用

      • GDT表由gdtr指示其位置和长度

      • 使用特殊的指令进行操作:sgdt/lgdt


Linux

Interrupt Descriptor

Table

descriptor

Global Descriptor

Table

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

descriptor

GDTR

descriptor

descriptor

descriptor

descriptor

IDTR

图示


Linux

  • 一般装载gdt和idt之后,要重新装载段寄存器

    • cs、ds、es、fs、gs

    • cs通常通过一条长跳转指令装载

    • 其他数据段寄存器直接设置


Control registers

控制寄存器(Control Registers)

  • CR0

  • CR1

  • CR2

  • CR3

  • CR4(扩展相关,忽略)

  • 与内存相关


Linux

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


Cr1 cr2 cr3

CR1、CR2、CR3

  • CR1:保留

  • CR2:在缺页异常的时候,记录缺页地址

  • CR3:记录页目录所在的物理地址和两个标记(PCD & PWT)


Documentation i386 boot txt

阅读documentation/i386/boot.txt

  • 对于i386平台,由于一些历史的原因,因此Linux的启动比较复杂

  • 这个文档包含如下内容

    1、Linux/i386的启动协议(10个+)

    2、内存布局图(大内核,小内核)

    3、实模式下的内核头结构(即setup header)以及各参数的解释

    4、内核的命令行(command line)


Linux

5、实模式代码的内存布局

6、启动配置示例

7、装载Linux的剩余部分

8、特殊的命令行参数

9、运行内核

10、高级启动回调函数

  • 关于其中的一些内容,我们将在合适的时候说明


Linux

加载I386内核的内存布局图

  • zImage/Image的内核加载器所使用的经典的内存布局(1M=0x100000)为


Header s

Header.S分析

  • 前512个字节的内容


Msg loop

关于msg_loop输出的字符串

??不支持软盘启动???


Header s1

Header.S分析

  • 关于512字节的最后(setup header)

在setup.ld中

在Head.S中


Header s2

Header.S分析

  • 第二个扇区开始

  • 接下来仍然是setup header参数部分,直到start_of_setup


Linux

  • start_of_setup

    • 设置堆栈

    • 检查setup中的标签

    • 清除BSS段

    • 调用C入口main

_start(512处)

start_of_setup

main


Main c

Main.c分析

main

重点:

go_to_protected_mode

=?


Go to protected mode

关于go_to_protected_mode

  • 关键

move_kernel_around

setup_idt

重点:

setup_gdt

protected_mode_jump:参见pmjump.S


Protected mode jump

关于protected_mode_jump

  • 关键

    • 进入保护模式

      • 通过设置cr0

    • 进入32位代码

      • 通过一条手工设置的代码

    • 最后进入setup header中指定的code32_start


Boot params hdr code32 start

关于boot_params.hdr.code32_start

  • 对boot_params.hdr的赋值之处:copy_boot_params

  • Hdr的定义之处

在Head.S中


Linux

  • code32_start在setup header的第二部分

  • 此处对应于压缩映像的head_32.S


Head 32 s

解压缩头中的head_32.S

  • 32位代码

  • 关键1:调用decompress_kernel

  • 关键2:跳转到vmlinux的头head_32.S

  • 阅读此目录下的vmlinux_32.lds

    • 了解入口处的代码


Head 32 s relocated

关于解压缩head_32.S中的relocated相关

  • 即“.text”部分

    • Clear BSS

    • Setup the stack for the decompressor

    • Do the decompression, and jump to the new kernel..


Vmlinux head

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

startup_32

最后

i386_start_kernel

重点

start_kernel

重点


Linux

关于页表的初始化

  • 观察default_entry后的代码,忽略PAE

    • 页目录:swapper_pg_dir:参见head_32.S

      • 第一个页表:pg0:参见vmlinux_32.lds


Swapper pg dir

swapper_pg_dir


Linux

pg0

pg0

高地址

内核BSS段

swapper_pg_dir

内核数据段

内核代码段

低地址


Linux

初始化页目录和页表

物理地址

空间低端4M

对应线性地址3GB

1024项

对应线性地址0

swapper_pg_dir

pg0


Linux

打开分页机制


Linux

关于GDT

  • 1)boot_gdt

  • 2)per_cpu__gdt_page


Stack start

关于堆栈stack_start


Setup idt

关于setup_idt

  • 在idt表中,填写ignore_int

  • 几个特殊的项:

输出如下信息:

输出如下信息:


Gdt idt 3g

装载GDT、IDT,进入3G地址空间


Start kernel

关于start_kernel

  • 对Linux内核的各个部分进行初始化

  • Start_kernel属于手工初始化的第一个进程(0号进程),该进程最后执行cpu_idle,成为idle进程

  • 系统创建的第一个进程(1号进程)

    • 该进程最后找到一个init程序进行Linux运行环境的初始化


Upstart ubuntu

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/中删去即可


Thanks

Thanks!

The end.


  • Login