文章目录
- 前言
- mbs.S代码
- 实验操作
前言
本博客记录《操作系统真象还原》第二章最后一节的实验操作~
实验需要安装Bochs软件,具体可食用Bochs下载安装博客。
实验环境:ubuntu18.04+VMware
实验内容:在屏幕上打印字符串“1 MBR”,背景为黑色,前景为绿色。
实验原理(重点):计算机开机后,首先运行BIOS软件(计算机系统的控制权 [CPU的使用权] 交接的第一棒就是BIOS啦!),BIOS会检查各种设备的情况,并且建立中断向量表。然后MBR找机会想把处理器使用权交出去。下一个接棒选手就是 主引导记录(MBR,Master Boot Record),BIOS知道MBR在0盘0道1扇区,因此它会将0盘0道1扇区中的MBR引导程序加载到物理地址0x7c00,然后继而跳去执行。这样BIOS就将处理器的使用权交给MBR。
本人理解:这样的话,我们只需要把想运行的代码放到0x7c00地址,这样程序成为了MBR程序,就会执行我们编写的代码并输出想要的内容。
mbs.S代码
mbr.S
;主引导程序
;------------------------------------------------------------
SECTION MBR vstart=0x7c00 mov ax,cs ;由于BIOS是通过jmp 0:0x7c00跳转到MBR,故cs为0 mov ds,axmov es,axmov ss,axmov fs,axmov sp,0x7c00 ;初始化栈指针 ; 清屏 利用0x06号功能,上卷全部行,则可清屏。
; -----------------------------------------------------------
;INT 0x10 功能号:0x06 功能描述:上卷窗口
;------------------------------------------------------
;输入:
;AH 功能号= 0x06
;AL = 上卷的行数(如果为0,表示全部)
;BH = 上卷行属性
;(CL,CH) = 窗口左上角的(X,Y)位置
;(DL,DH) = 窗口右下角的(X,Y)位置
;无返回值:mov ax, 0x600mov bx, 0x700mov cx, 0 ; 左上角: (0, 0)mov dx, 0x184f ; 右下角: (80,25),; VGA文本模式中,一行只能容纳80个字符,共25行。; 下标从0开始,所以0x18=24,0x4f=79int 0x10 ; int 0x10;;;;;;;;; 下面这三行代码是获取光标位置 ;;;;;;;;;
;.get_cursor获取当前光标位置,在光标位置处打印字符.mov ah, 3 ; 输入: 3号子功能是获取光标位置,需要存入ah寄存器mov bh, 0 ; bh寄存器存储的是待获取光标的页号int 0x10 ; 输出: ch=光标开始行,cl=光标结束行; dh=光标所在行号,dl=光标所在列号;;;;;;;;; 获取光标位置结束 ;;;;;;;;;;;;;;;;;;;;;;;;; 打印字符串 ;;;;;;;;;;;;还是用10h中断,不过这次是调用13号子功能打印字符串mov ax, message mov bp, ax ; es:bp 为串首地址, es此时同cs一致,; 开头时已经为sreg初始化; 光标位置要用到dx寄存器中内容,cx中的光标位置可忽略mov cx, 5 ; cx 为串长度,不包括结束符0的字符个数mov ax, 0x1301 ; 子功能号13是显示字符及属性,要存入ah寄存器,; al设置写字符方式 ah=01: 显示字符串,光标跟随移动mov bx, 0x2 ; bh存储要显示的页号,此处是第0页,; bl中是字符属性, 属性黑底绿字(bl = 02h)int 0x10 ; 执行BIOS 0x10 号中断
;;;;;;;;; 打字字符串结束 ;;;;;;;;;;;;;;;jmp $ ; 使程序悬停在此message db "1 MBR"times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节db 0x55,0xaa ; 结束标志
代码说明:
- 第 3 行
vstart=0x7c00
:表示本程序在编译时,告诉编译器,把我的起始地址编译为 0x7c00。 - 第4~8行是用cs寄存器的值去初始化其他寄存器 ,由于 BIOS 是通过
jmp 0: 0x7c00
跳转到 MBR 的,故cs的值为0。 - 第9 行是初始化栈指针。查<实模式下内存布局>表格可知,这部分区域可以使用。
- 第11~28 行的功能是清屏。
- 第30~35 行是做打印前的工作,先获取光标位置,目的是避免打印字符混乱,覆盖别人的输出 。
- 第38~52 行是往光标处打印字符。
- 第55 行执行了个死循环,
$
是本行指令的地址,这属于伪指令,是汇编器在编译期间分配的地址。 - 第57行是定义打印字符。
- 第58行是 填充剩下的空间,使生成的二进制代码恰好为512字节。
【补充】nasm中的$
和$$
的含义
$表示"此处的地址"。
$$表示"当前段的起始地址"。
因此$-$$表示"当前节的大小"。
实验操作
操作思路:
- 首先我们先创建汇编文件并将其编译成bin后缀的文件
- 创建一个硬盘,接着将编译后的文件(bin后缀)存储到0盘0道1扇区中成为MBR
- 最后启动Bochs
开始动手操作 ( ^ _ ^ )
- 创建编译mbr.S文件
(base) user@ubuntu:/home/cooiboi/bochs/bin$ sudo vim mbr.S
(base) user@ubuntu:/home/cooiboi/bochs/bin$ sudo nasm -o mbr.bin mbr.S
(base) user@ubuntu:/home/cooiboi/bochs/bin$ ls -lb mbr.bin
-rw-r--r-- 1 root root 512 Jan 4 05:56 mbr.bin
- 创建硬盘
sudo ./bximage
(base) user@ubuntu:/home/cooiboi/bochs/bin$ sudo ./bximage
========================================================================bximageDisk Image Creation / Conversion / Resize and Commit Tool for Bochs$Id: bximage.cc 12690 2015-03-20 18:01:52Z vruppert $
========================================================================1. Create new floppy or hard disk image
2. Convert hard disk image to other format (mode)
3. Resize hard disk image
4. Commit 'undoable' redolog to base image
5. Disk image info0. QuitPlease choose one [0] 1Create imageDo you want to create a floppy disk image or a hard disk image?
Please type hd or fd. [hd] hdWhat kind of image should I create?
Please type flat, sparse, growing, vpc or vmware4. [flat] flatEnter the hard disk size in megabytes, between 10 and 8257535
[10] 60What should be the name of the image?
[c.img] hd60M.imgCreating hard disk image 'hd60M.img' with CHS=121/16/63The following line should appear in your bochsrc:ata0-master: type=disk, path="hd60M.img", mode=flat
dd if=mbr.bin of=hd60M.img bs=512 count=1 conv=notrunc
- 将bin文件(mbr.bin)写入硬盘(hd60M.img)中
输入文件是刚刚编译出来的 mbr.bin ,输出是我们虚拟出来的硬盘 hd60M.img ,块大小指定为 512 字节,只操作 1 块,即总共 1*512=512 字节。
(base) user@ubuntu:/home/cooiboi/bochs/bin$ sudo dd if=mbr.bin of=hd60M.img bs=512 count=1 conv=notrunc
1+0 records in
1+0 records out
512 bytes copied, 0.000325151 s, 1.6 MB/s
mbr.bin 己经写进 hd60M.img 的第 0 块了
- 启动Bochs
(base) user@ubuntu:/home/cooiboi/bochs/bin$ sudo ./bochs -f bochsrc.disk
输入6
,然后再输入c
。紧接着,屏幕上显示绿色的1 MBR
.
【注意】:这里需要编写bochsrc.disk文件
megs : 512#注意路径 必须是你安装的路径 别弄错了
romimage: file=/home/cooiboi/bochs/share/bochs/BIOS-bochs-latest
vgaromimage: file=/home/cooiboi/bochs/share/bochs/VGABIOS-lgpl-latestboot: disklog: bochs.outmouse:enabled=0
keyboard:keymap=/home/cooiboi/bochs/share/bochs/keymaps/x11-pc-us.mapata0:enabled=1,ioaddr1=0x1f0,ioaddr2=0x3f0,irq=14ata0-master: type=disk, path="hd60M.img", mode=flat,cylinders=121,heads=16,spt=63
#ata0-master: type=disk, path="/home/cooiboi/bochs/bin/./hd60M.img", mode=flat, cylinders=121, heads=16, spt=63#gdbstub:enabled=1,port=1234,text_base=0,data_base=0,bss_base=0
具体可以食用Bochs下载安装
参考资料
- 《操作系统真象还原》
- Bochs下载安装
- 《操作系统真象还原》第二章 ---- 编写MBR主引导记录 初尝编写的快乐 雏形已显!