[书]操作系统真象还原 -- 第6章 mbr、loader、C语言

FILE_01:mbr.asm

1)mbr, Master Boot Record,512字节,位于0x7c00

2)将loader从磁盘读取到内存中,并跳转到loader

function: read_hard_disk_0

======================================================================

FILE_02:loader.asm

1)调用BIOS中断0x15获取内存大小

2)进入保护模式:

>>    2-1 构建全局描述符表GDT(gdt的第0项不可用),lgdt加载基地址和界限值;

>>    2-2 打开地址线A20,否则还是只能访问1MB内存(实模式下,只能使用20根地址线);

>>    2-3 将控制寄存器CR0的PE位置1(Protection Enable),清空流水线、重新加载段寄存器。

3)将kernel从磁盘读取到内存中(这里为了简单,选择了在开启分页之前加载)

4)开启分页机制:

>>    4-1 创建页目录PD和页表PT(每页4KB);低3G为用户空间、高1G为内核空间;gdt也已位于内核空间,重新lgdt;

>>    4-2 将控制寄存器CR3赋值为页目录表基地址;

>>    4-3 将控制寄存器CR0的PG位置1(Page位);从此,段部件产生的地址就不再被看成物理地址,而是要送往页部件进行变换,以得到真正的物理地址。

5)解析kernel的ELF,并跳转过去(跳转地址为编译C代码时指定的地址)。

    将ELF文件中的段segment拷贝到各段自己被编译的虚拟地址处,将这些段单独提取到内存中,这就是所谓的内存中的程序映像。

function: read_hard_disk_0; setup_page创建页目录及页表;kernel_init解析内核ELF;mem_cpy逐字节拷贝

======================================================================

FILE_03:main.c

C语言代码:while(1);

//  gcc -m32 -I lib/ -c -o main.o main.c
//  ld -m elf_i386 -Ttext 0xc0001500 -e main -o kernel.bin main.o lib/print.o

======================================================================

FILE_04:print.asm

用汇编实现打印函数,供C语言调用。

put_char,打印一个字符,该字符通过栈传入

put_str,打印字符串,字符串首地址通过栈传入,逐字节读取字符串并压入栈,调用put_char

put_int,以十六进制形式打印32位二进制数

======================================================================

GITHUB:https://github.com/trb331617/os_elephant/tree/master/chapter_6

运行截图:

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章