自制操作系统(四)

这回说如何将C语言文件放入二进制映像中。

我们不得不讲一下c编译器了,c编译器与汇编编译器不同,汇编编译器是直接将汇编代码编译成二进制可执行程序,而c编译器是首先将c语言编译器编译成汇编代码,然后再将汇编代码编译成一个二进制中间文件,然后再将这个二进制中间文件进行链接,就是多个中间文件组合到一起,最后形成一个中间文件。

倘若这个c语言文件不依赖其他的c语言文件,就没什么链接一说了。

首先声明几点:

1. 0xb800是显存的开始地址,像显存中输入字符,就会显示字符。

2. 每一个输入字符包括两部分,ascii值和它的属性,所以要一连输入两个字节才能显示一个字符。

3. BIOS的13H中断,是将数据从软盘传送至内存中。

4. BIOS的10H中断,是在屏幕上显示一个信息。

5. 80386有4个32位控制寄存器,名字分别为CR0,CR1,CR2,CR3,CR0中包含系统的控制标志,在此,我们关注CR0寄存器的PE位控制,它负责实模式和保护模式的切换。

6. GDT,描述符表,段寄存器实际上是指向这个表的指针,我们需要自己创建一个GDT,来定义数据段,代码段什么的,在保护模式中,段长是任意的,最高可达4GB。

7. LDT,是局部段描述表,每一个操作系统都必须定义一个GDT,而每一个正在运行的任务都会有一个相应的LDT,每一个描述符的长度是8字节。当使用段寄存器的时候,段基地址就会从相应的表中获得。

8.  因此,我们在进入32位之前(把PE设为1),至少定义好段寄存器,而且,我们还需要执行跳转以清除在实模式下读取的任何指令。

9. 在nasm中,任何不带[]的标签或变量名都被认为是地址,访问标签中的内容必须用[]

我用nasm+gcc来进行操作,具体为:

    nasm -f elf32 API.asm -o API.o
    gcc -c -elf32 main.c -o main.o
    ld main.o API.o -o main.elf
    objcopy -S -O binary main.elf main.bin
    nasm -f bin boot.asm -o boot.bin

最后得到两个文件boot.bin和main.bin,然后依次存入映像中,开机,出现重绘的画面了:

自制操作系统(四)

自制操作系统(四)

完美。