学堂在线_操作系统_notes_第4讲_Lab1_bootloader启动ucore os _ x86启动顺序
20220629.No.1824
摘自"IA-32 Intel体系结构软件开发者手册"。
寄存器初始值
第一条指令
CS = F000H, EIP = 0000FFF0H
- 实际地址是:
CS:EIP = Base + EIP = FFFF0000H + 0000FFF0H = FFFFFFF0H
// 这是BIOS的EPROM (Erasable Programmable Read Only Memory) 所在地
- 当CS被新值加载,则地址转换规则将开始起作用。
- 通常第一条指令是一条长跳转指令(这样CS和EIP都会更新)到BIOS代码中执行。
处于实模式的段
- 段选择子(Segment Selector):
CS
, DS, SS, … - 偏移量(Offset):
EIP
从BIOS到Bootloader
- BIOS 加载存储设备(比如软盘、硬盘、光盘、USB盘)上的第一个扇区(主引导扇区,Master Boot Record, or MBR) 的512字节到内存的0x7c00 …
- 然后转跳到
@0x7c00
的第一条指令开始执行.
从bootloader到OS
- bootloader做的事情:
- 使能保护模式(protection mode)& 段机制(segment-level protection)
- 从硬盘上读取kernel in ELF 格式的ucore kernel (跟在MBR后面的扇区)并放到内存中固定位置
- 跳转到ucore OS的入口点(entry point)执行,这时控制权到了ucore OS中.
段机制
使能保护模式
- 使能保护模式(protection mode), bootloader/OS 要设置CR0的bit 0 (
PE
). - 段机制(Segment-level protection)在保护模式下是自动使能的.
加载ELF格式的ucoreOS kernel
struct elfhdr {
uint magic; // must equal ELF_MAGIC
uchar elf[12];
ushort type;
ushort machine;
uint version;
uint entry; // program entry point (in va)
uint phoff; // offset of the program header tables
uint shoff;
uint flags;
ushort ehsize;
ushort phentsize;
ushort phnum; // number of program header tables
ushort shentsize;
ushort shnum;
ushort shstrndx;
};
struct proghdr {
uint type; // segment type
uint offset; // beginning of the segment in the file
uint va; // where this segment should be placed at
uint pa;
uint filesz;
uint memsz; // size of the segment in byte
uint flags;
uint align;
};
参考资料
- Chap. 2.5 (Control Registers) ), Vol. 3, Intel® and IA-32 Architectures Software Developer’s Manual
- Chap. 3 (Protected-Mode Memory Management), Vol. 3, Intel® and IA-32 Architectures Software Developer’s Manual
- Chap. 9.l (Initialization Overview), Vol. 3, Intel® and IA-32 Architectures Software Developer’s Manual
- An introduction to ELF format: http://wiki.osdev.org/ELF