《30天自制操作系统》——从引导区到磁盘

上一篇讲了如何使用虚拟机运行我们写好的操作系统,但上一篇的操作系统其实仅仅存在于引导扇区中,接下来我们将看到程序如何从引导扇区跳到其他位置。

引导区内容的装载位置为0x00007c00-0x00007dff,规定该位置的人是当年开发IBM-PC的工程师们。0x7e00-0x9fbff是操作系统可以随便使用的内存位置。按照《30天自制操作系统》中所讲,我们把前10个磁道的数据都读入内存,内存位置从0x8000开始。因此磁盘镜像文件中,位于地址x的字符加载到内存的位置就为0x8000+x。现在设我们需要执行磁盘镜像上位于0x004200号地址的程序,那么其内存地址就为0x8000+0x4200=0xc200。

程序一、ipl.nas

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; hello-os

; TAB=8

ORG    0x7C00

; 以下的记述用于标准FAT12格式的软盘

start:

JMP    entry

DB    "HELLOIPL"    ; 启动区名称(8字节)

DW    512        ; 扇区大小(512字节)

DB    1        ; 簇大小(1扇区)

DW    1        ; FAT起始位置

DB    2        ; FAT个数

DW    224        ; 根目录大小(224项)

DW    2880        ; 磁盘大小(2880扇区)

DB    0xf0        ; 磁盘种类

DW    9        ; FAT长度

DW    18        ; 每个磁道扇区数

DW    2        ; 磁头数

DD    0        ; 不使用分区

DD    2880        ; 重写一次磁盘大小

DB    0,0,0x29    ; 意义不明

DD    0xffffffff    ; 可能是卷标号码

DB    "HELLO-OS   "    ; 磁盘名称(11字节)

DB    "FAT12   "    ; 格式名称(8字节)

RESB    18        ; 空出18字节

entry:

MOV    AX,0        ; 初始化寄存器

MOV    SS,AX

MOV    SP,0x7c00

MOV    DS,AX

MOV    ES,AX

; 读磁盘

CYLS    EQU    10

MOV    AX,0x0820

MOV    ES,AX

MOV    CH,0        ; 柱面0

MOV    DH,0        ; 磁头0

MOV    CL,2        ; 扇区2

readloop:

MOV    SI,0        ; 记录失败次数

retry:

MOV    AH,0x02        ; 读盘

MOV    AL,1        ; 1个扇区

MOV    BX,0

MOV    DL,0x00        ; A驱动器

INT    0x13        ; 调用磁盘BIOS

JNC    next        ; 没出错跳转fin

ADD    SI,1

CMP    SI,5        ; 比较SI与5

JAE    error        ; SI >= 5时,跳转到error

MOV    AH,0x00

MOV    DL,0x00

INT    0x13        ; 重置驱动器

JMP    retry

next:

MOV    AX,ES

ADD    AX,0x0020    ; 把内存地址后移0x200

MOV    ES,AX        ; 因为没有ADD ES,0x20

ADD    CL,1

CMP    CL,18

JBE    readloop    ; 如果CL <= 18,跳转至readloop

MOV    CL,1

ADD    DH,1        ; 读磁盘另一面

CMP    DH,2

JB    readloop

MOV    DH,0

ADD    CH,1

CMP    CH,CYLS        ; 读CYLS个柱面

JB    readloop

; 输出helloworld

MOV    SI,msg

putloop:

MOV    AL,[SI]

ADD    SI,1        ; 给SI加1

CMP    AL,0

JE    0xc200        ; 跳到0xc200,即hanbote.nas程序地址

MOV    AH,0x0e        ; 显示一个文字

MOV    BX,15        ; 指定字符颜色

INT    0x10        ; 调用显卡BIOS

JMP    putloop

JMP    0xc200

fin:

HLT

JMP    fin

error:

MOV    SI,errmsg

errloop:

MOV    AL,[SI]

ADD    SI,1        ; 给SI加1

CMP    AL,0

JE    fin

MOV    AH,0x0e        ; 显示一个文字

MOV    BX,15        ; 指定字符颜色

INT    0x10        ; 调用显卡BIOS

JMP    errloop

msg:

DB    0x0a, 0x0a    ; 换行2次

DB    "hello, world"

DB    0x0a        ; 换行

DB    0

errmsg:

DB    0x0a, 0x0a    ; 换行2次

DB    "disk error"

DB    0x0a        ; 换行

DB    0

marker:

RESB    0x1fe-(marker-start)

DB    0x55, 0xaa

; 以下是磁盘其他内容

DB    0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00

RESB    4600

DB    0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00

RESB    1469432

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

程序二、hanbote.nas

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; haribote-os

; TAB=8

ORG    0xc200    ; 程序开头在内存中的地址

MOV    SI,msg

putloop:

MOV    AL,[SI]

ADD    SI,1        ; 给SI加1

CMP    AL,0

JE    black

; JE    fin

MOV    AH,0x0e        ; 显示一个文字

MOV    BX,15        ; 指定字符颜色

INT    0x10        ; 调用显卡BIOS

JMP    putloop

black:

MOV    AL,0x13    ; VGA显卡

MOV    AH,0x00

INT    0x10

fin:

HLT

JMP    fin

msg:

DB    0x0d, 0x0a, 0x0a    ; 换行2次

DB    "haha"

DB    0x0a        ; 换行

DB    0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

程序3、Makefile

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

default:

make img

img: hanbote.bin ipl.bin

dd if=hanbote.bin of=ipl.img bs=512 seek=33 count=1 conv=notrunc

ipl.bin: ipl.nas

nasm -f bin ipl.nas -o ipl.img -l ipl.lst

hanbote.bin: hanbote.nas

nasm -f bin hanbote.nas -o hanbote.bin

run: img

qemu-system-i386 -fda ipl.img -boot a

clean:

rm ipl.lst

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

这样你只要在终端中输入make run就能看到运行结果了。

其中我们使用dd来把hanbote.bin写入ipl.nas中我们希望的位置。

hanbote.bin在ipl.nas中的位置从0x4200开始,因为dd以512字节为一块,所以用seek把输出文件定位到0x4200/512=0x21=33,notrunc保证ipl.img不被截断。

时间: 2024-10-15 18:06:00

《30天自制操作系统》——从引导区到磁盘的相关文章

《30天自制操作系统》读书笔记(2)hello, world

让系统跑起来 要写一个操作系统,我们首先要有一个储存系统的介质,原版书似乎是06年出版的,可惜那时候没有电脑,没想到作者用的还是软盘,现在的电脑谁有软驱?不得已我使用一张128M的SD卡来代替,而事实上你用的是U盘还是软盘对我们的操作系统没有影响,缺点是你的U盘刷入系统后容量只能是1440 MB,即当年流行的3.5英寸软盘的大小,当然不用担心,再格式化一次(用DiskGeniu),就可以恢复. 我做事情的话,总是怕自己的努力的结果白费了,害怕辛辛苦苦看完这本书但是发现做出来的东西现在根本没法用,

《30天自制操作系统》——虚拟机使用

<30天自制操作系统>是一本学习操作系统的好教材,它教我们怎么从建立引导区开始,从零实现一个操作系统.但是,实现书中例子的时候,我们需要不断将我们写好的操作系统代码写入软盘并且还要不断重启电脑来试验我们的代码,大家一定感到很头疼吧. 与其不停的重启,不如使用模拟器,向大家推荐一款模拟器qemu,它是由Fabrice Bellard编写,功能非常强大.那么下面我就来教大家使用qemu运行书中自制操作系统的方法吧. 一.安装qemu 我使用的是苹果笔记本,苹果有一个非常好用的程序管理工具叫brew

单字节的FIFO缓存(30天自制操作系统--读书笔记)

从今天起,写一些读书笔记.最近几个月都在看<30天自制操作系统这本书>,书虽说看的是电子书,但可以花钱买的正版书,既然花费了金钱,就总得有些收获. 任何人都不能总是固步自封,想要进步就得学习别人的知识,对于程序员而言,最简单的方法即是学习别人的代码. 今天的标题是“单字节的FIFO缓存”,其实就是做一个FIFO,看名字就知道了.也就4个函数和1个相关结构体,这样的小代码在嵌入式系统中很常用,也会很好用. 1.相关数据结构体 struct FIFO8 { unsigned char *buf;

《30天自制操作系统》读书笔记(4) 绘图

暑假果然是滋生懒散的温床. (╯‵□′)╯︵┻━┻ 好久不动都忘记之前做到哪里了, 上次好像做到了C语言的引入, 这一节所做的东西都相当轻松, 将会绘制出操作系统的基本界面. 绘图的原理 按照书中所说, 将值写入到显存中就能在屏幕上显示相应的像素, 在asmhead.nas 中有这一段: 1 CYLS EQU 0x0ff0 ; 设定启动区 2 LEDS EQU 0x0ff1 3 VMODE EQU 0x0ff2 ; 关于颜色数目的信息,颜色的位数 4 SCRNX EQU 0x0ff4 ; 分辨率

&lt;&lt;30天自制操作系统&gt;&gt;(1)初体验汇编程序

我们这次使用的汇编语言编译器是原书作者自己开发的,名为“nask”,很多语法和著名的汇编语言编译器nasm很像.由于原书作者没有给出有哪些不同,这里就无法给出不同了! 现在仅仅使用汇编语言中的DB指令来写个“操作系统”吧. DB指令是"define byte"的缩写,往文件里写入1个字节 超长的源代码 1 DB 0xeb, 0x4e, 0x90, 0x48, 0x45, 0x4c, 0x4c, 0x4f 2 DB 0x49, 0x50, 0x4c, 0x00, 0x02, 0x01,

《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!

<30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的装载地址 5 6 ; 以下这段是标准FAT32格式软盘专用的代码 7 8 JMP entry 9 DB 0x90 10 DB "HELLOIPL" ; freeparam 启动区的名称可以是任意的字符串(8字节) 11 DW 512 ; 每个扇区(sector)的大小(必须为512字节)

《30天自制操作系统》纸娃娃操作系统以及大多数操作系统的加载原理

最近在读<30天自制操作系统>这本书,在读到"从启动区加载操作系统"这一小节的时候卡住了,首先我的疑问是这样的:首先,磁盘映像文件img的0x2600这个地方存储着操作系统文件的名称(用二进制编辑器看),0x4200以后存储着操作系统的内容(执行代码),我们的启动区代码会被加载到内存的0x7c00这个位置,即0x7c00-0x7cff属于启动区代码所有,而书上说0x8000-0x81ff属于启动区,究竟哪段地址属于启动区,这是疑问一.我们的是从第二扇区将磁盘内容读取到内存,

《30天自制操作系统》笔记(02)——导入C语言

<30天自制操作系统>笔记(02)--导入C语言 进度回顾 在上一篇,记录了计算机开机时加载IPL程序(initial program loader,一个nas汇编程序)的情况,包括IPL代码(helloos.nas).编译生成helloos.img文件.用虚拟机QEMU加载helloos.img.制作U盘启动盘和用物理机加载helloos.img. 计算机启动时会自动加载和执行IPL程序,但IPL程序只能占用512字节.若直接用IPL写OS,空间不够用.所以IPL程序一般用于将真正的OS程序

《30天自制操作系统》读书笔记(3) 引入C语言

这一次的学习相当曲折, 主要是因为粗心, Makefile里面的错误导致了文件生成出现各种奇奇怪怪的问题, 弄得心力交瘁, 因此制作过程还是尽量按着作者的路子来吧. 作者提供的源码的注释在中文系统下是乱码, 而且代码的分隔用了两个Tab, 在这里要处理一下: :%s/;.*//g 删除所有的注释; :%s/\t\t/\t 把两个Tab替换为一个Tab; 要让作者的nas文件和asm文件拥有相同的语法规则, 在_vimrc文件的最后一行添加 au BufNewFile,BufRead *.nas