基于linux0.11的从零开始学操作系统-setup

1.setup中获取扩展内存大小:

! Get memory size (extended mem, kB)

        mov     ah,#0x88
        int     0x15
        mov     [2],ax

返回:ax=从0x100000(1M)处开始的扩展内存大小

2.保护模式

setup切换保护模式位于[0x00090348] 9020:0148

        mov     ax,#0x0001      ! protected mode (PE) bit
        lmsw    ax              ! This is it!

此时CPU已经进入32位保护模式

jmpi    0,8             ! jmp offset 0 of segment 8 (cs)

这句话在16位实模式下解释如下:

CPU跳转至cs = 8,IP = 0 即0x80处开始执行

而到了32位,CS称为选择子。此时的寻址方式为:
通过选择子配合gdt表查到一个值,把这个值重新组合作为新的地址。
此时GDTR = 0x0009035b 意味着当前gdt表起始位置在内存中的0x0009035b处。cs=8代表,以GDTR位起始位置,偏移8个字节。也就是选择‘0x00090363’。存放的东西是什么呢?

0x00090363 <bogus+       8>:    0xff    0x07    0x00    0x00    0x00    0x9a    0xc0    0x00
p.s. 为了方便起见,将低地址放到低位,高地址放到高位于是乎:
0x00090363-0x00090371: 
00C09A00000007FF

上面的东西代表的是什么意思呢?其是,它是一段LDT(Local Descriptor Table)。一共64个bit,其解释方式如下图所示:
ldt
重点关心黑色字体部分:
00C09A00000007FF
前面的就是32位保护模式下的基址,后面的就是保护模式下的偏移地址。所以,接下来CPU就到了00:000000处。
用一张图概况保护模式下的寻址方式,一定就是这样了:
gdt


2018.10/27
为了加深理解,补充一张 GDT 的图片:
gdt2
可以看到,除了 LDT 外,GDT 还包含有 TSS。而 TSS 却跟任务调度有着莫大的联系…

来源:赵炯《Linux 内核完全注释》

2019/2/2
可以这样理解,对于计算机来说,操作系统可以当作是一个庞大的进程。这个进程一方面处理用户交互(管理硬件),一方面用于支持其他的进程去运行。
分段机制让内存管理变得高效,但需要记录下来每个段的地址。这就需要有一份段表。
操作系统的段表就是 GDT,进程的段表就是 LDT

感谢稀稀拉拉的赞赏