摘要:通常编写一个操作系统内核是一项浩大的工程。但我今天的目标是制作一个简单的内核,用比较方便的方法在虚拟机上验证它能够被grub装载和运行,并且可通过gdb进行调试,为接下去的工作创造一个基础环境。首先,为了方便运行和调试我们需要一个虚拟机。虚拟机有很多选择,这里用最简单的qemu。先用dd创建一个文件作为虚拟盘,100MB就可以了:$ dd if=/dev/zero of=disk.img count=204800 bs=512然后对这个虚拟磁盘进行分区:$ fdisk -c=dos disk.img用命令n创建一个分区就可以了。通常情况下分区的起始扇区是2048(不带选项-c=dos),如果用
阅读全文
摘要:接上一篇kernel.img由startup.S以及一堆c文件编译而成。这是一个ELF格式的文件。(其实前面的boot.img、 diskboot.img、lzma_decompress.img本来也都是ELF格式文件,但是经过了精简。)kernel.img链接时,目标装载地址是0x9000,这是在Makefile.core.dep中定义的:i386_pc_ldflags= '$(TARGET_IMG_BASE_LDOPT),0x9000';但是现在kernel.img被加载到了0x100000,startup.S里的代码开始执行。所以开头的几个指令首先是把startup_ra
阅读全文
摘要:接上一篇从地址0x8200开始的是lzma_decompress.img。这是由startup_raw.S编译生成的。这个文件稍微复杂点。首先一开始就是个跳转指令:ljmp $0, $ABS(LOCAL (codestart)) /* 机器码:ea 1c 82 */ 跳转到0x821c,这里是真正的开始代码。0x8203到0x821b之间存放的是一些特殊数据,如压缩数据前后的长度、冗余数据的长度等,由GRUB安装时填写,后面会用到。接下来设置实模式堆栈后,切换到保护模式:DATA32 call real_to_prot然后打开Gate A20,即第21根地址线的控制线: call grub_g
阅读全文
摘要:GRUB是目前较流行启动引导程序。其第二版被主流Linux发行版所包括。本文将探索和分析GRUB的设计和实现机制。boot.S是第一个研究对象,因为boot.S将被编译成boot.img(512字节),安装时安装在0号扇区,即主引导扇区(MBR)。BIOS引导时会把主引导扇区装载到0x7c00开始的512字节内存区域,并设置CS:IP为0x0000:7c00。接着CPU会执行0x7c00处的指令,即boot.img(boot.S)中的第一条指令: jmp LOCAL(after_BPB) /* 机器码: eb 63 */ ,跳转到偏移量0x65的地方。 接下去的代码检查并设置正确的引导驱动器号
阅读全文