嵌入式操作系统 [email protected] xlanchen email: [email protected]@ustc.edu.cn...
Post on 20-Dec-2015
374 views
TRANSCRIPT
嵌入式操作系统[email protected]
http://staff.ustc.edu.cn/~xlanchen
Email: [email protected]
Phone: 0551-3606864-83
[email protected] Embedded Operating Systems 4
源代码来源 Linux-2.4.18 加压缩后,建立 SourceInsigt 工程 阅读 linux 目录下的 README
关于 Linux 的介绍 该版本内核支持的体系结构 如何配置、编译、安装
[email protected] Embedded Operating Systems 5
考虑 Arch为 i386
在 arch/i386 下存在如下目录
I386 的启动源代码文件目录I386 的核心源代码文件目录I386 的库源代码文件目录I386 的数学仿真源代码文件目录I386 的内存管理源代码文件目录
I386 的配置文件I386 的体系相关部分的 Makefile
I386 的 Linux 内核的链接描述文件
[email protected] Embedded Operating Systems 6
I386的启动代码文件 在 arch/i386/boot 目录下
在 arch/i386/boot/compressed 目录下
I386 的体系结构相关部分的启动代码都采用汇编码写的
启动扇区中的启动代码,其目标码必然是 512 字节
I386 初始化
内核解压缩
[email protected] Embedded Operating Systems 7
在 arch/i386/kernel 目录下的 .S 文件
在 init 目录下
32 位启动代码
这是体系结构无关部分, i386 体系结构相关部分的启动,其目的就是进入 main.c 中的 start_kernel 处执行
[email protected] Embedded Operating Systems 8
阅读 documentation/i386/boot.txt
对于 i386 平台,由于一些历史的原因,因此 Linux 的启动比较复杂
这个文档包含如下内容1 、 Linux/i386 的启动协议( 4 个)2 、内存布局图3 、实模式下的内核头结构4 、内核的命令行( command line )
[email protected] Embedded Operating Systems 9
5 、启动配置示例6 、装载 Linux 的剩余部分7 、特殊的命令行参数8 、运行内核9 、高级启动回调函数
关于其中的一些内容,我们将在合适的时候说明
[email protected] Embedded Operating Systems 11
找到 vmlinux 找到 vmlinux 所依赖的各个文件或者目标
可以看到 vmlinux 包含如下内容 i386/kernel/head.S + init/main.c + init/version.o + CORE_FILES + DRIVERS + NETWORKS + LIBS
[email protected] Embedded Operating Systems 12
若 make install 在 i386 的 Makefile 中有 install 规则
若 make boot/bzImage/zImage 等等,则要找到对应的目标然后进行 make boot 在顶层的 Makefile 中可以找到 boot 规则 bzImage/zImage 可以在 i386 的 Makefile 中找到相
应规则 其他的 zXXX/bzXXX 也都依赖于 boot 下的 zImage/
bzImage 它们最终都找到 i386/boot 的 Makefile
[email protected] Embedded Operating Systems 13
i386/boot的Makefile
看 i386/boot 的 Makefile
z 代表压缩; b 代表大内核
可见 compressed 下的 vmlinux/bvmlinux 为 compressed/head.S + 压缩后的顶层目录下的 vml
inux zImage 为 bootsect + setup + compressed/vmlinu
x bzImage 为
bbootsect + bsetup + compressed/bvmlinux
[email protected] Embedded Operating Systems 14
下面根据在 bzImage/zImage 中的顺序,我们依次看启动相关的源代码和相关概念 arch/i386/boot/bootsect.S arch/i386/boot/setup.S arch/i386/boot/compressed/head.S arch/i386/kernel/head.S
最后进入 kernel/main.C
[email protected] Embedded Operating Systems 15
I386内核的启动 启动方式
软盘启动 硬盘启动
软盘启动从 arch/i386/boot/bootsect.S 开始运行
在进入 bootsect.S 的源代码讲解之前,我们先看一下加载 i386 内核的内存布局图
[email protected] Embedded Operating Systems 16
硬件角度:I386实模式下的内存布局图
RAM1-MB
ROM-BIOS
VIDEO-BIOS
VRAM0xA0000
0xC0000
0xF0000
0x00000
[email protected] Embedded Operating Systems 17
I386内核从实模式开始运行
首先看一下什么是实模式
实模式是为了兼容早期的 CPU 而设置的 i386 系统总是始于实模式 实模式下
地址总线: 20 位 内存范围: 0~1MB 逻辑地址 = 段地址 + 段内偏移
段地址 = 段寄存器中的值 *16 (或左移 4 位) 段寄存器长度: 16bit
[email protected] Embedded Operating Systems 18
加载 I386内核的内存布局图 zImage/Image 的内核加载器所使用的经
典的内存布局( 1M=0x100000 )为
[email protected] Embedded Operating Systems 19
软盘启动, bootsect.S
0x7c000x90000 0x7c00, BIOS 0x90000, lilo
堆栈, 0x3ff4(0x4000-12), 向下增长 磁盘参数表, 12Bytes , 0x3ff4~0x4000 显示“ Loading” Setup0x90200 系统
小内核, 0x10000 ( 64KB 处),低装载 大内核, 0x100000 ( 1MB 处),高装载
setup
[email protected] Embedded Operating Systems 20
硬盘启动,两阶段引导
装载 LILO ( LInuxLOader ) 第一个扇区 …
装载 LINUX Bootsect.S0x90000 Setup.S0x90200 系统
0x10000 0x100000
跳转到 setup
[email protected] Embedded Operating Systems 21
启动第一步,小结 总之,在跳转到 setup 的时候,内存里面的代
码布局为 0x90000 : bootsect 0x90200 : setup 低装载: 0x10000 :带解压的 vmlinux 高装载: 0x100000 :带解压的 bvmlinux
实模式下的内核头结构 包括 bootsect 的最后和 setup 开始的位置 从 bootsect 的偏移 0x1F1 开始,具体描述参见 do
cumentation/i386/boot.txt
[email protected] Embedded Operating Systems 22
Setup: 0x90200
初始化硬件设备并为内核程序的执行建立环境 内存检测 键盘 视频 磁盘控制器 IBM微通道总线 MCA PS/2 设备(总线鼠标) APM BIOS
若低装载,将系统移动到 0x1000 处( 4KB 处)否则,不必
临时 IDT 和临时 GDT FPU PIC, 16 个硬件中断中断
向量 32~47 实模式保护模式 Startup_32
[email protected] Embedded Operating Systems 23
在 compressed/head.S 和 head.S 中都定义了 startup_32
但是 head.S 中,被压缩在 vmlinux 中还没有解压缩 只有 compressed/head.S 的 startup_32 是可用的
zImage 中,在 0x1000 处 bzImage 中,在 0x100000 处
[email protected] Embedded Operating Systems 24
Compressed/head.S
Startup_32 初始化段寄存器和一个临时堆栈 初始化 BSS 段 解压缩
高装载或低装载解压缩 0x100000 ( 1MB ) 跳转到 0x100000 处
[email protected] Embedded Operating Systems 25
解压缩后, vmlinux 在 0x100000 处 根据 vmlinux.lds , vmlinux 的地址被链接为 0xc00
00000+0x100000 处 如何正确运行呢?
此时仍然是实模式,还没有进入保护模式、分页、映射好
没有长跳转,只使用采用相对地址的近距离跳转
[email protected] Embedded Operating Systems 26
Head.S
Startup_32 初始化段寄存器 建立进程 0 的内核堆栈 Setup_idt 拷贝系统参数 识别处理器 GDT 、 IDT Start_kernel
[email protected] Embedded Operating Systems 27
与内存相关的一些概念 在实模式下,地址总线 20 位,访存范围为 1M
B , 物理地址使用段址:偏移的方式表示 段址保存在段寄存器中,段寄存器有:
cs/ds/es/fs/gs 16 位寄存器,偏移也是 16 位,因此最大段长为 21
6=0x10000=64KB 物理地址 = 段寄存器 ×16+ 偏移
[email protected] Embedded Operating Systems 28
保护模式下,地址总线 32 位,访存范围为 4GB
原来的段寄存器现在被称作段选择子,与 GDT 表配合使用 GDT 表由 gdtr指示其位置和长度 使用特殊的指令进行操作: sgdt/lgdt
[email protected] Embedded Operating Systems 29
图示
descriptordescriptordescriptordescriptordescriptordescriptordescriptor
descriptordescriptordescriptordescriptordescriptordescriptordescriptor
descriptordescriptordescriptordescriptordescriptordescriptor
Interrupt Descriptor Table
Global Descriptor Table
GDTR
IDTR
[email protected] Embedded Operating Systems 30
查看 setup.S 和 head.S 中的 gdt/ldt 一般装载 gdt 和 idt 之后,要重新装载段寄存
器 cs 、 ds 、 es 、 fs 、 gs
cs通常通过一条长跳转指令装载 其他数据段寄存器直接设置
[email protected] Embedded Operating Systems 32
CR0 CR0, MSW register (Machine Status Word, 32-bit versio
n) 包含系统控制位,用于控制操作模式和状态
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
[email protected] Embedded Operating Systems 33
CR1、 CR2、 CR3 CR1 :保留 CR2 :在缺页异常的时候,记录缺页地址
CR3 :记录页目录所在的物理地址和两个标记 (PCD & PWT)
[email protected] Embedded Operating Systems 34
作业 4
i386 实模式下是如何解决 20 位地址空间和 16位段寄存器之间的不匹配问题的?
i386保护模式下的段寄存器的内容与实模式下段寄存器的内容一样么?如何解释?