1. 用freedos的缘由
读书不仔细,检讨。
列子chapter3.1-a,编译后,.bin大小为149bytes,将第2章中的a.img和bochsrc复制过来继续使用,可用。
因为代码量小于512字节,且末2字节仍然为0xAA55(没有被覆盖掉),所以引导扇区有效,可以作为引导磁盘使用。
看作者介绍freedos时没有仔细看,当时还疑问作者为什么要无故介绍这个。在学习3.2时,在经历一番痛苦后终于明了,读书不仔细是要吃亏的。
因为chapter3.2-b,编译后,.bin大小远远超过512bytes,将其写入a.img直接导致软盘的0面0道1扇区的512字节的末2字节被覆盖,于是运行bochs会提示找不到可引导盘。
经历几番折腾后,突然想起是不是0xAA55没有了,是不是代码量超过了512bytes,哦,明白了。
2. 关于“逻辑地址”、“线性地址”和“物理地址”
实模式下:
一个地址(即物理地址)由“段值:偏移”确定。“段值”为16位的cs、ds等段寄存器,“偏移”可由16位的寄存器或常数(符号标识)给出。物理地址的计算公式为:
物理地址(Physical Address ) = 段值(Segment)x 16 + 偏移(Offset)
保护模式下:
逻辑地址:由“段值:偏移”确定。“段值”仍旧是16位的段寄存器,叫做选择子(Selector),作为查找段描述符表的索引,“偏移”可为32位的寄存器或常数。
线性地址:根据逻辑地址中的选择子找到段基址,然后加上偏移值,即为线性地址。
物理地址:当不启用分页机制时,线性地址 = 物理地址;如果启用了分页机制,则需要从线性地址得到页目录和页表,转换后才能得到物理地址。这个还不懂,以后补充。
3. 实模式跳到保护模式步骤
step 1: 准备GDT。在定义时,通常只定义了段界限和段属性,段基址常常需要通过代码重新赋值。
step 2: 用lgdt加载gdtr寄存器。gdtr为48位寄存器,高32位为GDT表的段基址,低16位为GDT界限,即长度。
step 3:打开A20地址线
step 4:置cr0的PE位,进入保护模式
step 5:跳转,运行保护模式的代码
4. 关于mov [LABEL_GO_BACK_TO_REAL + 3], ax 这句话
刚开始看了好久,一直在用单片机的思维想,这不是自己修改自己代码吗,code存放在flash里,怎么可能可以自己修改呢?!
良久,才想起来,这段代码虽然存放在软盘中,后来不是被BIOS加载到7c00h内存中去了吗,前面运行的代码修改后面内存中的内容,当然可以啊。顿悟!