# 关于

上一篇文章介绍了在在 Windows 10 下实现一个操作系统需要部署的环境。本文就正式开始实现一个操作系统了。

# 这篇文章讲了什么?

  • 计算机启动过程的大致介绍
  • 实现 MBR
  • Windows 10 下 Bochs-2.6.9 的配置与运行

# 计算机的启动过程

当我们按下计算机的 Power button 后,首先运行的软件是 BIOS,全称为 Basic Input & Output System,即基本输入输出系统。由于 BIOS 是第一个运行的软件,所以它只能由硬件来加载。

BIOS 启动后,便开始检测内存、显卡等外设信息,当检测通过,并初始化好硬件后,它的最后一项工作是校验启动盘中位于 0 0 1 扇区的内容。当检测到此扇区末尾的两个字节分别为 0x55 0xaaBIOS 便认为此扇区中确实存在可执行的程序(此程序就是 MBR),然后加载到物理地址 0x7c00,随后跳转到此地址上,继续执行。

MBR,主引导记录,全称是 Main Boot Record。

# 实现 MBR

# 代码如下(E:\OS\boot\mbr.S

; 主引导程序
; -----------------------------------------------
SECTION MBR vstart=0x7c00
    mov ax, cs
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov fs, ax
    mov sp, 0x7c00

; 清屏利用 0x06 号功能,上卷全部行,则可清屏。
; -----------------------------------------------
; INT 0x10 功能号 0x06 功能描述:上卷窗口
; -----------------------------------------------
; 输入:
; AH 功能号 = 0x06
; AL = 上卷的行数(如果为0,表示全部)
; BH = 上卷行属性
; (CL, CH) = 窗口左上角的(X,Y)位置
; (DL, DH) = 窗口右下角的(X,Y)位置
; 无返回值:
    mov ax, 0x600
    mov bx, 0x700
    mov cx, 0                     ; 左上角:(0,0)
    mov dx, 0x184f                ; 右下角:(80,25)
                                  ; VGA文本模式中,一行只能容纳80个字符,共25行
                                  ; 下标从0开始,所以0x18=24,0x4f=79
    int 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
    db 0x55, 0xaa

# 使用 nasm 编译 mbr.S

nasm -o mbr.bin mbr.S

# 验证 mbr.bin 的文件大小是否 512 字节

ls -lb mbr.bin

以上命令都在 Cmder 中运行。

接下来,便是要用 Bochs 测试一下

# Bochs-2.6.9 的配置与运行

  • 想要在 Bochs 中成功模拟 MBR 的执行,需要对 Bochs 进行如下三步配置

    • Bochs 根目录下 bochsrc-sample.txt 在同位置复制黏贴一份,改名为 bochsrc-sample-test.bxrc,在 Visual Studio Code 中对其进行编辑,内容如下。
    • 借助 Bochs 根目录下 bximage.exe 初始化一个 1.44M 的软盘
    • 借助 Bochs 根目录下 bximage.exe 初始化一个 60M 的硬盘

# Bochs 初始化配置

bochsrc-sample-test.bxrcD:\Program Files\Bochs-2.6.9\bochsrc-sample-test.bxrc)内容如下

# "#"是注释(comment)

# 分配内存megs参数[megs: 128 分配128MB内存,最大是2048]不被赞成使用
# 使用memory替代
# guest 分配给模拟器客户端的内存大小
# host  从guest分配给主机的内存大小,实际分配可能比guest小,如果用到了
# 更多的内存将会动态加入,但访问不能大于guest内存大小.
# memory 没有内存大小限制,限制的是CPU可访问内存最大大小(即CPU地址总线宽度)
memory: guest=32,host=32

# 配置ROM BIOS,ROM BIOS将控制计算机首次启动的功能(BIOS的固件)
# file:ROM BIOS二进制文件路径,这个参数下面不再解说
romimage: file=BIOS-bochs-latest

# VGA ROM 的映象文件  一般是被映射到内存地址0xC0000处,相当于我们的显卡
vgaromimage: file=VGABIOS-elpin-2.40

#使用软驱 floppy_ ,"_"可以是a,b,c,d...
#例子:软驱a,b 大小为1.44MB  
# 参数:status 有两种分别为
# inserted(软盘插入软驱),ejected(软盘未插入软驱)。
floppya: image="fd144.img", status=inserted


# ata是一个接口 可以是ata0,ata1,ata2,ata3,用来控制硬盘(disk)和光驱(cdrom)
#ioaddr1 分配主盘的io端口地址 ..... 
#ioaddr2 分配从盘的io端口地址 .....
#irg     中断请求号(当发生中断时,对应的中断向量)
#学过硬盘端口读写的朋友应该知道主盘对应端口(0x1f0~0x1f7)
#从盘对应对口(0x3f0~0x3f7)
ata0: enabled=1,ioaddr1=0x1f0, ioaddr2=0x3f0,irq=14

#ata[0-3]-master 定义设备类型和特征 
#type       连接设备的类型[disk(硬盘)|cdrom(光驱)]
#path       虚拟镜像路径(我用的是virtualbox虚拟机的虚拟硬盘)
#cylinders  柱面数(type为硬盘是才有这个参数)
#heads      每柱面拥有的磁道数(type为硬盘是才有这个参数)
#spt        没磁道的扇区数量(type为硬盘是才有这个参数)
ata0-master: type=disk, path="hd60M.img", mode=flat

#设置启动顺序 1.硬盘,2.软驱(配置过BIOS启动项的朋友肯定知道)
boot: disk,floppy


#日志输出 log: 日志路径
log: bochslog.txt

#设置鼠标不可用 ,如果enabled不为0那么bochs会发送鼠标事件到仿真机上
#因为是字符界面,无需鼠标
mouse: enabled=0

#设置键盘
#type 键盘类型
#keymap 键盘映射文件
keyboard: type=mf,keymap=keymaps/x11-pc-us.map

其中软盘 fd144.img

floppya: image="fd144.img", status=inserted

和硬盘 hd60M.img

ata0-master: type=disk, path="hd60M.img", mode=flat

生成方式

D:\Program Files\Bochs-2.6.9
λ bximage.exe
========================================================================
                                bximage
  Disk Image Creation / Conversion / Resize and Commit Tool for Bochs
         $Id: bximage.cc 13069 2017-02-12 16:51: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 info
0. Quit
Please choose one [0] 1
Create image
Do you want to create a floppy disk image or a hard disk image?
Please type hd or fd. [hd] fd
Choose the size of floppy disk image to create.
Please type 160k, 180k, 320k, 360k, 720k, 1.2M, 1.44M, 1.68M, 1.72M, or 2.88M.
 [1.44M]
What should be the name of the image?
[a.img] fd144.img
Creating floppy image 'fd144.img' with 2880 sectors
The following line should appear in your bochsrc:
  floppya: image="fd144.img", status=inserted
(The line is stored in your windows clipboard, use CTRL-V to paste)
Press any key to continue
D:\Program Files\Bochs-2.6.9
λ bximage.exe
========================================================================
                                bximage
  Disk Image Creation / Conversion / Resize and Commit Tool for Bochs
         $Id: bximage.cc 13069 2017-02-12 16:51: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 info
0. Quit
Please choose one [0] 1
Create image
Do you want to create a floppy disk image or a hard disk image?
Please type hd or fd. [hd]
What kind of image should I create?
Please type flat, sparse, growing, vpc or vmware4. [flat]
Enter the hard disk size in megabytes, between 10 and 8257535
[10] 60
What should be the name of the image?
[c.img] hd60M.img
Creating hard disk image 'hd60M.img' with CHS=121/16/63
The following line should appear in your bochsrc:
  ata0-master: type=disk, path="hd60M.img", mode=flat
(The line is stored in your windows clipboard, use CTRL-V to paste)
Press any key to continue
D:\Program Files\Bochs-2.6.9
λ

# 在 Bochs 中模拟运行 MBR

  • 在这里要做两件事
    • mbr.bin 写入到硬盘 hd60M.img
    • 指定配置文件运行 Bochs
E:\OS\boot
λ ls
mbr.S  mbr.bin
E:\OS\boot
λ dd if=mbr.bin of="D:\Program Files\Bochs-2.6.9\hd60M.img" bs=512 count=1 conv=notrunc
1+0 records in
1+0 records out
512 bytes copied, 0.0100447 s, 51.0 kB/s
E:\OS\boot
λ

在 Linux 下,启动 Bochs 后,输入字符 c 后,再输入回车执行。

D:\Program Files\Bochs-2.6.9
λ bochs -f "bochsrc-sample-test.bxrc"
========================================================================
                       Bochs x86 Emulator 2.6.9
               Built from SVN snapshot on April 9, 2017
                  Compiled on Apr  9 2017 at 09:32:13
========================================================================
00000000000i[      ] reading configuration from bochsrc-sample-test.bxrc
00000000000e[      ] bochsrc-sample-test.bxrc:39: ataX-master/slave CHS set to 0/0/0 - autodetection enabled
00000000000i[      ] installing win32 module as the Bochs GUI
00000000000i[      ] using log file bochslog.txt

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

ICUXIKA 微信支付

微信支付

ICUXIKA 支付宝

支付宝

ICUXIKA 贝宝

贝宝