bios阶段
(1)硬件电路初始化设置PC =0xFFFF0,物理实现是设置CS,IP寄存器的值为CS=0xFFFF IP = 0x0000,然后CPU开始取址,执行。PC这段ROM称为BIOS,其放置的是基本硬件测试代码。
(2)硬件检测完成后,由BIOS的输入功能,将启动磁盘上启动扇区中的内容读到内存的0x7C00处,设置CS=0x07C0 IP = 0x0000。通常将这个启动扇区中存放的程序文件命名为bootsect.c。
boostsect.s
(1)调用BIOS 0x13中断,由BIOS从磁盘中读入setup.s文件到内存(内存起始地址0x90200)。
(2)调用0x10中断,在屏幕上输出信息"Loading System ..."。
(3)调用BIOS 0x13中断,从磁盘中读入system模块到内存(内存起始地址0x10000)。
(4)jmpi 0,SETUPSEG 跳转到内存0x90200处,setup模块准备执行。
setup
(1)获取内存大小,磁盘大小等硬件信息。从位置0x90000放入
(2)从0x10000位置复制0x80000个字节到0x0000位置(复制的是system模块)。
! 每个循环移动0x10000个字节,移动八个循环,共移动0x80000个字节
do_move:
mov es,ax ! destination segment
add ax,#0x1000
cmp ax,#0x9000
jz end_move
mov ds,ax ! source segment
sub di,di
sub si,si
mov cx,#0x8000
rep
movsw
jmp do_move
(3)完成gdt表的构建和初始化工作。
(4)开启32位寻址模式。32位保护模式的寻址方式为,用段寄存器作为索引,在对应地址表(GDT表)中找到32位基址。再和EIP相加完成寻址。
(5)jmpi 0,8 根据gdt表可知,跳转到了0x0000处开始执行。0x0000处(system模块)开始执行。
head.s
(1)设置IDT表和GDT表。lgdt/lidt指明表的起始地址和长度限制。
call setup_idt
call setup_gdt
(2)设置页表
(3)从汇编代码跳转到C语言程序(main函数)
lss stack_start,%esp /* 设置栈地址*/
after_page_tables: #压栈 head->c main执行
pushl $0 # These are the parameters to main :-)
pushl $0
pushl $0
pushl $L6 # return address for main, if it decides to.
jmp $main # 跳到main后 ,main正常执行永远不会返回。若返回则执行死循环L6
L6:
jmp L6 # L6是死循环,当main返回时,即死机
main
(1)初始化各种管理软硬件资源的数据结构
(2)操作系统开始正常运转