Notes on A x64 OS¶
一个64位操作系统的设计与实现(田宇著)。一年前,读过一本32位操作系统实现的书,好像叫 Orange’s ,大概看到保护模式那里就没法再看下去了(读不懂),现在出了新书,讲64位OS的实现,不管怎么样先读起来,然后慢慢记录叭~
notes INT 10h chapter3的第一个boot.asm里面有个清屏的操作,按照书上的代码:
mov ax, 0600h
mov bx, 0700h
mov cx, 0
mov dx, 0184h
int 10h
实现不了鸭(指如果运行在bochs里的话)。int 10h
主要是实现屏幕指定矩形区域的文字向上滚动的功能。若 al
设置成 00h
的话,是整个矩形区域的全体文字全部上移,所以书上说的若 al
设置成 00h
后面的几个参数都不需要管应该是不对的?(我的理解是至少要设置矩形区域的大小能够超过bochs显示的大小,然后把文字都向上移走,这样就实现了清屏的效果),我的代码如下所示:
mov ax, 0600h
mov bx, 0700h
mov cx, 0000h
mov dx, 0ffffh
int 10h
这里 bx
设置区域属性的背景都是黑色的,cx
设置矩形左上角坐标,dx
设置矩形右下角坐标,我给设置成了最大的 0ffffh
,因为我也不知道这个bochs的窗口到底是多大,先放最大的可以偷懒。 T^T
mistake? p45求根目录占用的扇区数,根据书中所给数据所列出来的式子是算不到14个扇区这个结果的,但是按照
这个公式算出来确实是14(怀疑是公式列错了)。
notes LBA and CHS LBA - Logical Block Addressing,CHS - Cylinder-Head-Sector。逻辑块寻址和柱面/磁头/扇区格式的磁盘扇区号之间的转换。LBA格式的很好理解应该,逻辑寻址,所以扇区号就从0开始递增就可以了。关键是柱面/磁头/扇区格式的扇区号是怎么排的。首先,磁盘会有好多个盘面,每个盘面就有点像一张光盘,然后有很多张“光盘”叠起来,每个盘面分成很多个同心圆,每个圆就叫一个 磁道 ,那因为有很多个盘面叠加,所以每个盘面上同样位置的磁道,在空间上面就好像组成了一个圆柱,每个盘面的相同位置的同心圆叠加一起形成的面叫做 柱面 ,每一个磁道会分成很多个段,每个段就叫一个 扇区 (老式的磁盘,每一个磁道所存储的数据量是一致的,这样的话越是外围的磁道密度就会越小,因为它的周长长,相反越是内部的磁道密度就会越大)。最后还有一个磁头的概念,假设我现在要开始读取一个磁道上面的内容,那就是有一个磁头,转过这个磁道的一圈,就算读取了一个磁道,那从哪个地方开始读,就是 磁头 的位置。
每个盘面都有两个面,每个面都可以存储数据,所以一个盘面应该有两个 磁头 (上下两个)。一个盘面有多少个磁道整个磁盘就有多少个 柱面 (这个应该也很好理解)。假设盘面的计数是从底下向上的,那最底下的盘,就有0号(在下面)和1号(在上面)两个盘面,这样的话,其实就是有0号和1号这两个磁头。柱面的计数是从外部向内部计数,最外面的柱面记为0,然后向里面递增。最后就是从磁头开始,转过一圈磁道,那从磁头开始,就是1号扇区,然后递增转完一圈(CHS计数里面柱面和磁头都是从0开始,好像唯独每个磁道的扇区是从1开始算的)。以书上那个1.44M的软盘算的话,设置一个磁道有18个扇区。举例:按照CHS如果是 0/0/12 这个扇区那就是,0号柱面,也就是最外面那个柱面的,0号磁头,那就是最下面那个盘面的下面的12号扇区,那就是从磁头开始转到第12个扇区。这个扇区对应的LBA扇区号就应该是11号(LBA是从0开始计数的)。如果是0/0/18,这个扇区表示的是0号柱面的0号磁头的最后一个扇区,对应LBA应该为17。0/1/1表示是还是0号柱面,但是是1号磁头,也就是变成了最底下那个盘的上面那个面, (括号内废弃,因为我rst没找到删除线标记哎quq。然后是那个面的最外面那个磁道(因为柱面是0)的第一个扇区,对应的LBA应该为18这里是划掉的是我自己理解上面出错了,所谓的柱面号,理解成磁道号或许好一点,这一个代表的是CHS里面的那个H的数值,所谓的磁头号,反而是代表了是哪一个盘面,我感觉下面那个我自己写的公式里的字母的表述好像有点倒了…)所以这样的话CHS的变化就是,先把0号整个柱面都用完,那这个柱面会有很多个盘面组成,其中每个盘面都会提供两个面,也就是两个磁头。接着就从最下面的那个磁头开始,转一圈就算用完了这个面。然后换上面那个面(也就是上面那个磁头),再继续…这样的话,第一个柱面用完了,之后就有点像整个磁头都向里面缩进一个磁道,然后再开始…,再开始的时候就是1号柱面了,得到了这样的关系就能得出LBA和CHS之间的换算关系。
其中 c , h 和 s 分别代表柱面号,磁头号和扇区号, hpc 和 sph 分别代表每柱面拥有的磁头数和每磁头(或者说每磁道)拥有的扇区数。 sph 写作 spt 或许更好(wiki上是 spt )。
mistake? 555我感觉书上的46页3-1的LBA转换为CHS的公式好像也没有写对。QuQ 噢,对不起,没有错,好像是一种不同的计算方法,我仔细看看先。Here! 在这里解释上面划掉的和书上的那个公式。(括号内废弃。书上的公式表示的 x面/x道/x扇区指的是第x个盘面的第x个磁道上的第x个扇区。这个和我上面写的区别在哪里呢,我上面的那个CHS是指第 c 个柱面(也就是第 c 个磁道)的第 h 个磁头(也就是哪个盘面)的第 s 个扇区。如果写的通顺一点那就是,第 h 个磁头(哪个盘面)上的第 c 个磁道(柱面)上的第 s 个扇区。如果我的理解正确的话,那么书上的那个x面/x道/x扇区是不符合CHS的原本的意思的。但是这两种意思都遵循同样的计算规则,也就是我上面最后说的:一定是先把一个柱面的磁道全部用完,然后再去用里面的磁道。最后,哎等等?那按照书上的写法写到INT 13h里面去是能找到的,岂不是我看的CHS的计算规则不是INT 13h采用的???)好了好了,都是一样的,(我大概是受到了一篇CSDN博客的影响,链接)来梳理一下书上的公式。首先用LBA除以每磁道扇区数(即spt),得到商Q和余数R,将商Q右移1位得到 c 的值(也就是说,把Q除以2,因为1.44的软盘hpc就是2,所以得到的 c 就是通过我们的公式算出来的,只是说计算的顺序不太一样),然后这里需要贴一下书上写的一个代码,是读取一个扇区的函数 Func_ReadOneSector
的片段:
div bl
inc ah
mov cl, ah
mov dh, al
shr al, 1
mov ch, al
and dh, 1
先说#s,#s的值就是R+1,这个应该没什么好说的,根据上面写的公式还有书上的计算顺序就很容易看出来了。重点是在1.44M下这个#h也就是磁头号的求法。下班了也没搞懂为什么#h就是Q… 啊啊啊啊啊,这个我感觉是书上真的写错了,书上写的商Q就是磁头号喔,但是代码上面却有这一句 and dh, 1
, dh
在INT 13h里面就是代表的磁头号,说明要将商Q和1做与,结果就是磁头号。敲黑板! 和1做与,是和0001与,不是1111,5555… (讲道理按照公式应该是要mod 2,mod 2和 和1做与 是一样的结果鸭,神奇的数学…)
???后面这个Loader是认真的?这是人能看懂的吗?