2019-05-28 | UNLOCK

2019-5-28-自己动手写操作系统(1)

前言

期末了,学校的操作系统课需要提交课程设计,想想这学期课程做的五个实验,dhcp、dns、web、ftp、email服务器搭建,实在不知道学校在教什么,所以决定自学写一个操作系统,自己写一个操作系统应该也是很多新手程序员的浪漫理想吧,接下来就是针对《自己动手写操作系统》的学习笔记,全书分为7章。

第一天:第一章-马上动手写一个最小的“操作系统”

开发环境:
win10
VM14+ubuntu16.04

之后是实验步骤

1、准备汇编编译器编译 nasm

sudo apt-get install nasm

2、编译boot.asm

在windows上用notepad++直接写一个boot.asm然后复制到ubuntu中(懒得安装中文输入法了)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
	org 07c00h			;告速编译器程序加载到7c00处
mov ax,cs
mov ds,ax
mov es,ax
call DispStr ;调用显示字符串例程
jmp $ ;无限循环,$表示当前地址,也就是jmp $的地址,这一步能防止代码进入数据区
DispStr:
mov ax,BootMessage
mov bp,ax ;es:bp = 串地址
mov cx,16 ;cx = 串长度
mov ax,01301h ;ah = 13, al = 01h
mov bx,000ch ;页号为0(bh = 0)黑底红字(b1=0Ch,高亮)
mov dl,0
int 10h ;10h 号中断
ret
BootMessage: db "Hello, OS world!"
times 510-($-$$) db 0 ;填充剩下的空间,使生成的二进制代码恰好为512字节
;$$表示当前节(section)起始地址
;在这个只有一节的程序中就是org 07c00h的地址
;所以$$-$就是该段程序从起始到time 510-($-$$)的长度
;加上最后的dw 0xaa55就是512字节
dw 0xaa55 ;结束标志

然后编译

1
nasm boot.asm -o boot.bin

3、制作软盘(系统启动盘)

空白软盘 这种上古玩意大概只有老师才有了,如今可以使用dd命令制作虚拟软盘

1
dd if=boot.bin of=boot.img

参数含义:
if=文件名:输入文件名,缺省为标准输入。即指定源文件。< if=input file >
of=文件名:输出文件名,缺省为标准输出。即指定目的文件。< of=output file >
更多参数可以参考https://www.cnblogs.com/jikexianfeng/p/6103500.html
将得到的boot.img从虚拟机复制到windows中

4、通过VM的空白虚拟机加载boot.img

在VM中创建空白的虚拟机,虚拟机类型我选择其它
avatar
随后在设置中把cd/dvd和网络适配器的自动连接去掉
avatar
之后添加软盘驱动器
avatar
最后在使用软盘映像文件中选择boot.img
avatar
打开虚拟机,实验成功!我们踏出了第一步
avatar

在编译过程中可能遇到 label or instruction expected at start of line,基本是格式或者编码的问题,自己手打一遍代码,注意空格和tab是不一样的。

以上实验步骤参考了
https://blog.csdn.net/zashizhi3299/article/details/80870073 中的空白虚拟机加载虚拟软盘
https://blog.csdn.net/YuDale/article/details/65644241 中的虚拟软盘创建

关于boot.asm的汇编解析(int 10h)

BIOS的10H中断的13号中断用于显示字符串,参数为:

1、AH=13H

2、AL=显示方式

如果AL=0,表示目标字符串仅仅包含字符,属性在BL中包含,不移动光标

如果AL=1,表示目标字符串仅仅包含字符,属性在BL中包含,移动光标

如果AL=2,表示目标字符串包含字符和属性,不移动光标

如果AL=3,表示目标字符串包含字符和属性,移动光标

总之,可以归纳为:    

     |BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0| AL

       BIT0为0表示不移动光标,为1表示移动光标

       BIT1为0表示字符串仅包含字符,为1表示字符串包含属性

       BIT2~BIT7未使用

3、BH表示视频区页数

4、如果AL的BIT1为0,则BL表示显示属性。属性为:

|BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0| BL

   BIT7:背景是否闪烁。0不闪烁,1闪烁

   BIT6~BIT4为背景色,分别为RGB,000为黑色,111为白色

   BIT3为1,则前景色加亮,为0则不加亮

   BIT2-BIT0为前景色,意义同背景色

5、CX为字符串长度

6、DH表示在第几行显示(0为第一行)

7、DL表示在第几列显示(0为第一列)

8、ES:BP指向字符串
参考自https://blog.csdn.net/pdcxs007/article/details/43378229

在王爽的《汇编语言》第三版第九章也有关于显示字符的实验,不过不是通过int 10h中断实现的,而是通过在内存地址B8000H-BFFFFH的空间内写入数据,这样会直接在屏幕上显示字符。

关于boot.asm的汇编解析(org 07c00h)

大部分程序是不需要org的,因为程序装载的时候通常会装载到xxxxH:0000H的位置,也就是偏移0
而org xxxx的含义是它告诉汇编器,把所有对内存的地址引用全都加上xxxx,这在程序被强制加载到非0000h偏移时很有用
一般编程不加org,因为程序默认加载地址的偏移就是0000h,可写引导扇区时,程序会被加载到0000段,偏移7c00,偏移不是0000,所以用org让所有的内存引用全都加上7c00h。于是,在引导扇区程序里,我们开头会看到这么一句 org 7c00h,因为汇编里十六进制要以数字开头,所以应该这么写org 07c00h。

参考自:https://blog.csdn.net/mirage1993/article/details/29908929

评论加载中