OS HelloWorld
1. 电脑上电之后的故事
- 当点击电源按钮之后通常我门的电脑主板BIOS就被启动检查基本的硬件环境, 然后由BIOS将磁盘的0磁道0扇区的512Byte数据加载到内存地址0X7C00处, 最后交出CPU控制权将CS设置为0X0000并且IP设置为0x7c00
- 解释:
- 整个过程BIOS就加载了0磁道0扇区的512Byte数据,也就是如果我们写的OS代码想让BIOS加载就必须把我们的代码放到磁盘的0道0区
- 内存地址是线性的, 如果总共1M内存,那么地址标识范围0X0000 - 0XFFFFF
- CS和IP是汇编语言中的两个寄存器,cpu执行指令的依据就是去找CS:IP对应内存处的指令
2. HelloWorld编写
-
使用语言:汇编语言, 具体含义见注释, 文件名:helloWorld.asm
org 0x7c00 ;当前程序执行是第一行代码的虚拟起始地址 mov ax,cs ; BIOS交控制权时cs = 0x0 mov ds,ax ; 数据段地址 ds = 0x0 mov es,ax ; 扩展段地址 ds = 0x0 mov ss,ax ; 栈段地址 ds = 0x0 mov fs,ax mov sp,0x7c00 ; 栈指针指向栈底 ;--------------------------利用int 10中断清屏--------------------------- mov ax, 0x600 mov bx, 0x700 mov cx, 0 ; 左上角: (0, 0) mov dx, 0x184f ; 右下角: (80,25), 下标从0开始,所以0x18=24,0x4f=79 int 0x10 ; int 0x10 ;--------------------------设置光标到左上角--------------------- mov ax, 0200h mov bx, 0000h ;BH=显示页码 mov dx, 0000h ;DH=行(Y坐标),DL= 列(X坐标) int 10h ;--------------------------打印字符串--------------------- mov ax, message mov bp, ax ; es:bp 为串首地址, es此时同cs一致 mov ax, 0x1301 ; 子功能号13是显示字符及属性,要存入ah寄存器,al设置写字符方式 ah=01: 显示字符串,光标跟随移动 mov bx, 0x0002 ; bh存储要显示的页号,此处是第0页,bl中是字符属性, 属性黑底绿字(bl = 02h) mov cx, 0xa ; cx 为串长度,不包括结束符0的字符个数 mov dx, 0 ; (dh, dl)位行列号 int 0x10 ; 执行BIOS 0x10 号中断 hlt ; 使程序悬停在此 message db "helloWorld" times 510-($-$$) db 0 db 0x55,0xaa
2.1 int 10 中断解释
-
int 0x10中断解释
- 主要利用了10号中断的6号功能, 其可以向上卷动实现清屏
清屏 利用0x06号功能,上卷全部行,则可清屏。 输入: AH 功能号= 0x06 AL = 上卷的行数(如果为0,表示全部) BH = 上卷行属性 (CL,CH) = 窗口左上角的(X,Y)位置 (DL,DH) = 窗口右下角的(X,Y)位置 无返回值:
- 设置光标位置
功能描述:用文本坐标下设置光标位置 输入: AH=02H BH=显示页码 DH=行(Y坐标) DL= 列(X坐标) 无返回值:
- 打印字符串位0x13号中断
功能描述:显示字符串 输入: AH=13H AL=显示输出方式(可选值0,1,2,3, 含义在下方) BH=页码当前默认0 BL=属性 CX=显示字符串长度(如果想自定义字符串则需要写对应字符长度在此处) (DH、DL)=坐标(行、列) ES:BP=显示字符串的地址 0—— 字符串中只含显示字符,其显示属性在BL中。显示后,光标位置不变 1——字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变 2 ——字符串中含显示字符和显示属性。显示后,光标位置不变 3——字符串中含显示字符和显示属性。显示后,光标位置改变 无返回值:
3. 创建软盘镜像
- 作用: 软盘镜像可以理解为我们通常理解的系统盘, 类似我们重装操作系自制的U盘;软盘也就是我们上面代码的载体
3.1 制作步骤
# 利用bochs提供的工具bximage
bximage
# 可获得以下提示信息
========================================================================
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
# 在输入框输入 1
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 代表创建软盘
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]
# 直接回车 代表创建的软盘大小为1.44M
# 在接下来的提示框输入镜像名字 helloWorld.img
What should be the name of the image?
[a.img] helloWorld.img
# 最后当前文件夹下即可查看到镜像文件helloWorld.img
4. 编译代码
- 利用nasm将汇编代码编译为机器码, 生成文件名helloWorld.bin
nasm helloWorld.asm -o helloWorld.bin
5. 将代码写入软盘
- 将代码写入软盘0磁道0扇区
dd if=helloWorld.bin of=helloWorld.img bs=512 count=1 conv=notrunc
6. 利用bochs加载镜像
-
bochs配置文件
-
创建bochs配置文件, 文件名为bochsConf,内容如下, 如果你得镜像名不是helloWorld需要修改第三行
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest vgaromimage: file=/usr/local/share/bochs/VGABIOS-lgpl-latest floppya: 1_44=helloWorld.img, status=inserted boot: floppy
-
-
启动命令
# 命令行输入, 此时会弹出一个黑窗口,可以将次黑窗口理解为启动的电脑 bochs -f bochsConf # 直接回车选择6 # 回到命令行输入 c 即可看到打印效果
2.1 此处直接回车
2.2 在命令行输入c后回车
2.3 最终效果