从头写一个操作系统 05

in cn •  6 years ago 

lesson 6
你可能需要google这个概念:segmentation

目标: 学习16位实模式下的内存寻址

如果非常了解segmentation,可以跳过这节课。

lesson3中我们用[org]定义了segmentation,其实它就是所有数据的偏移量。

CPU提供了几个特殊的寄存器:csdssses,对应着代码段,数据段,堆栈以及其他段(用户指定)。

注意:它们由CPU隐式调用的,所以当你给ds赋值后,所有内存的访问都会以ds的值为偏移量。

进一步的说,计算真实地址并不能简单的将两个地址相加(地址与偏移量),而是用segment << 4 + address这样的方式处理。比如如果ds 的值为 0x4d, 查询 [0x20] 地址的值实际上是查询 0x4d0 + 0x20 = 0x4f0

理论讲的足够了,看一看代码,亲手试试。

注: 不能mov一个字面量到上面的寄存器,需要使用通用寄存器来mov

lesson 7

你可能需要google一下:hard disk, cylinder, head, sector, carry bit

目标:令引导区加载硬盘数据,从而启动内核

我们的系统不可能只有512字节那么小,所以肯定需要从硬盘里读数据,以启动内核。

幸运的是,我们不用自己去写硬盘驱动控制盘片转动与停止,只需要调用BIOS的例程,就像之前将字符打印到屏幕上一样。这样做:赋值0x02al(别的寄存器存储有关cylinder, head and sector的信息),然后调用int 0x13 中断。

13中断可以查阅 a detailed int 13h guide here

这里,我们第一次遇见carry bit,它在寄存器计算中表示数据超出寄存器的存储范围,其实就是进位,比如寄存器最大能够存储256这个数字(1111 1111),如果再加一个1,就变为了257(1 0000 0000),此时carry bit中就会是1,寄存器中是0。

mov ax, 0xFFFF
add ax, 1 ; ax = 0x0000 and carry = 1

carry bit 不能直接访问,只能作为别的操作指令判断依据,比如 jc (当进位被设置时跳转)。

BIOS将al的值设置为需要读取的扇区数,应该通常会比较它们的值是否一致。

Code

仔细看看 boot_sect_disk.asm中读取硬盘的指令与流程。

boot_sect_main.asm中设置了读取硬盘(disk_load)所需的参数。注意我们写了一些不属于引导区的数据。

启动引导区实际上是hdd 0 的 head 0 的 cylinder 0 的 sector 1。

所以,在512字节后的512字节数据就是hdd 0 的 head 0 的 cylinder 0 的 sector 2。

main程序写入了一些简单数据,然后让引导区读取它们。

注意:如果一直报错并且代码没什么问题,请确保qemu的启动磁盘的参数是正确的,并且dl设置的是正确的。

BIOS 启动引导程序前,会将启动盘的编号写入dl中,不过当我从hdd启动qemu时遇到了一些问题

这里有两个解决办法:

  1. qemu -fda boot_sect_main.bin ,加入-fda使dl的值为0x00 ,貌似可以工作。
  2. qemu boot_sect_main.bin -boot c-boot会将dl设置为0x80,让引导程序读取数据。
Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Hello,

In order to prevent identity theft, identity deception of all types, and content theft we like to encourage users that have an online identity, post for a website or blog, are creators of art and celebrities of all notoriety to verify themselves. Verified users tend to receive a better reception from the community.

In order to confirm your authorship of the content, please make a mention of Steemit or add a hyperlink to Steemit in your blog:

https://www.jianshu.com/u/758ca9f35408

You can remove this mention from your website, once we confirm the authorship.

Thank you.

More Info: Introducing Identity/Content Verification Reporting & Lookup

I have maked a mention in my blog("https://www.jianshu.com/u/758ca9f35408")
,the mention's link is "https://www.jianshu.com/p/09a4ad055ae1"。
Thanks for this mention , and I hope all can be confirmed.

Thank you. The blog has been verified.

Congratulations @geyu! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You got more than 100 replies. Your next target is to reach 200 replies.

You can view your badges on your Steem Board and compare to others on the Steem Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

The Steem blockchain survived its first virus plague!
Vote for @Steemitboard as a witness to get one more award and increased upvotes!