尝试让虚拟机跑自己写的镜像
为什么整这玩意呢?
小时候就想写个操作系统,一般上班之余,早点把工作完成,然后就去学这知识吧。以前买过一本书叫做30天制作操作系统,一直就是放着了,没有看,是时候安排上了。
从这系列的笔记上,我尽量详细地记录这个过程,尝试去整一个属于自己的操作系统。目标是跑在PC电脑上。
如何在虚拟机,比如说Virtual-Box,或者VM
尝试跑一个HelloWorld
我相信同学们凭借着自己在搜索引擎上搜索,就可以实现这个功能。
下面,记录一下我的过程。
环境准备
下载汇编编译器:
https://www.sunofbeach.net/m/1430498409688682497
看我以上这个动态吧。
下载完以后,安装,配置环境变量。这个就不用说了,程序员都会。
这样子就配置好了
汇编代码
;------------------------------
; 汇编不分大小写
; 通用寄存器:ax,bx,cx,dx
; 堆栈段寄存器和偏移指针:ss:sp
; 代码段寄存器和偏移指针:cs:ip
; 数据段寄存器ds,偏移用[偏移位],比如说:[10]就是在ds的基础上偏移10
;------------------------------
org 0x7c00 ;从0x7c00开始,为什么从这里开始呢?
;"0x7C00" is the memory address which BIOS loads MBR(Master Boot Record a first sector in hdd/fdd) into.
;OS or bootloader developer must assume that their assembler codes are loaded and start from 0x7C00.
entry:
;让ax寄存器为0,以下几个寄存器不支持直接mov内容进去
;所以先到通用寄存器,然后再给ss,ds,es进行赋值
mov ax, 0
;让堆栈段寄存器为0
mov ss, ax
;让数据段寄存器为0
mov ds, ax
;让附加段寄存器为0
mov es, ax
;让源变地址寄存器地址为地址
mov si, msg
putloop:
mov al, [si] ;读取ds:si的数据到al里
add si, 1 ;si += 1,地址偏移量加1
cmp al, 0 ;如果al里的值为尾号
je fin ;调用fin
mov ah, 0x0e ;AH=0Eh在TTY模式下写字符
mov bx, 15 ;指定颜色15是白色,14是黄色,13是淡紫色
int 0x10 ;中断:INT 10H:显示服务(Video Service)
jmp putloop ;循环读取
fin:
HLT ;结束
jmp fin ;死循环
msg: ;内容部分
db 0x0a ;换行
;显示内容
db "Hello,This is WinBuntu Boot. -- Code by TrillGates";
db 0x0a ;换行
db 0 ;尾号
endpart:
;times 510-($-$$) db 0 ;留下2个填充结尾55AA,在VM上直接不够512个字节可以跑起来
db 0x55,0xaa ;结尾
编译
我们把汇编代码编译成二进制文件
编译输出了一个boo.img
但是要直让虚拟机执行这个镜像文件(二进制文件)需要做一些修改
历史内容
原文地址:
https://www.glamenv-septzen.net/en/view/6
从前面代码可以看到
这段代码是加载到0x7c00到0x7fff这段内存中的
但是,我们编译完以后,大小并不够填满这段内存。
0x7E00-0x7C00=0x200,也就是512,就是512个字节
"0x7C00" is the memory address which BIOS loads MBR(Master Boot Record, a first sector in hdd/fdd) into. OS or bootloader developer must assume that their assembler codes are loaded and start from 0x7C00.
但是不填充够512,以55AA结尾,在VM可以。如果跑不起来就填充够512字节吧。
还不行就填充到一个软件盘的大小。
虚拟机的创建
创建就不跟大家说了,主要是如何设置镜像
我的配置如下:
运行虚拟机
运行虚拟机,然后显示了内容
关于BIOS中断
这个去查就好了,前面中断码是 0x10,需要配合什么参数、哪些寄存器使用,去查就可以了。