深入理解 GNU GRUB - 02 boot.S 2.5 MBR过程模拟实现
1 MBR过程模拟实现
现在,我们对系统引导的第一步已经有了一个详细的认识。为了更深一步的理解MBR和这些 BIOS调用,提供一些测试题目:
- 开机后在屏幕上输出”Hello cppgp”,并在一定时间后重复输出;
- 开机后紧跟着读取第二个扇区,并且显示整个扇区512字节到屏幕上。
实现上述功能,编译生成512字节的IMG文件,设置虚拟机通过软盘引导,选择使用软盘镜像文件,设置镜像文件为我们编译生成的IMG文件,就可进行测试。下文首先简单介绍虚拟机配置,然后实现上述的1) 、2)两个题目。
1.1 测试虚拟机配置
最新注释:Debian下安装 qemu-system-x86即可:
~$ sudo apt-get install qemu-system-x86
《自己动手写操作系统》第二章“搭建你的工作环境”,对虚拟机选择、工作平台搭建、测试引导程序等都有详细的描述。这里只简单介绍搭建Vmware Work Station V7.1.3测试虚拟机的过程(其他版本的Vmware Workstation类似)。如下: 1). 选择菜单”File”->”New”->”Virtual Machine”创建一个新的虚拟机。在安装向导的帮助下可以简单完成。其中主要的选择如下:配置选择”Custom(advanced)”,硬件兼容版本选择” Workstation 6.5-7.x”操作系统安装选择”I will install the operating system later”,客户操作系统选择”Linux”,虚拟机名称为”grub-analysis”并定制你的保存路径,处理器配置默认,内存配置默认,网络连接默认,IO控制器类别默认,选择磁盘选择”Create a new virtual disk”,磁盘类型默认,磁盘大小默认(我们不会用到的),磁盘名称默认,单击”Finish”完成。 2). 选中刚才创建的虚拟机,右键选择”Settings”,选择软盘”Floppy”,”Device Status”选择”Connect at power on”。”Connection”选择”Use floppy image file”,选择”Browse”确保选择自己生成的IMG文件。 3). 选择菜单”Vm”->”Power”->”Power On to BIOS”,在Boot配置项中选择确保有软盘驱动器且是第一引导选择。默认配置便是这样,一般不用更改。 4). 启动虚拟机,就会使用设定的IMG文件引导。
1.2 TODO "Hello cppgp"的实现
/* * boot-hello-cppgp.S */ .file "boot-hello-cppgp.S" .text .code16 .globl _start _start: jmp after_pb output: .asciz "Hello Cppgp/r/n" idle_repeat: .long 0xA0000000 after_pb: cli /* * some bogus BIOS will jump to CS:IP=0x7C00:0000 * instead of CS:IP=0x0000:0x7C00 */ ljmp $0, $real_start real_start: xorw %ax, %ax movw %ax, %ds movw %ax, %ss movw $0x200, %sp sti /* do output and change color forever */ loop_output: movw $output, %si call message /* waiting for repeating idle */ xorl %eax, %eax loop_idle: incl %eax cmpl idle_repeat, %eax jne loop_idle jmp loop_output /* message function */ 1: movb $0xE, %ah int $0x10 message: lodsb cmpb $0, %al jne 1b ret . = _start + 0x1FE magic: .byte 0x55, 0xAA
在Linux下使用GCC编译、连接,使用objcopy提取IMG。如下:
~$ gcc -Wall -W -nostdinc -fno-builtin -m32 -MD -c -o boot-hello-cppgp.o boot-hello-cppgp.S ~$ gcc -o boot-hello-cppgp.exec boot-hello-cppgp.o -m32 -Wl,--build-id=none -m32 -nostdlib -Wl,-N -Wl,-Ttext,0x7C00 ~$ objcopy -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn boot-hello-cppgp.exec boot-hello-cppgp.img
1.3 测试
~$ qemu-system-x86_64 boot-hello-cppgp.img
不依赖任何操作系统,可以看到屏幕显示:
Sea BIOS (version...) iPXE ... Booting from Hard Disk... Hello cppgp Hello cppgp _