《自己动手写操作系统》是本很有意思的书。不过于渊前辈对某些内容没有给出更多的解释,让我们这些新米很难上手。
书中第3章介绍保护模式的时候,题到了GDT这个东东。在这里给出一个更浅显的介绍。
在介绍GDT这个概念前,现介绍一下segmentation这个概念。
大家还记得ORG这个汇编命令吧。书的开篇,给出的boot.asm代码的第一行就是:
ORG 0x7c00
这个ORG就是告诉CPU,程序被载入内存的0x7c00这个地方了。也就是说CPU从这个内存地址开始读取指令就OK了。
但是,现在的CPU同时执行好几个程序是很正常的事情。那么不同的程序使用的内存就有可能重叠,这样载入程序的话就会发生冲突。解决方法之一就是把把内存分成若干个段(segmentation)。每段放一个程序,这样每个程序都可以声明ORG 0了。很方便。
(另一个解决方法是paging,这个以后有机会在谈。)
为了能使用segmentation, 每个段(segment)都需要清楚的表明以下信息:
- 段(segment)的大小。
- 段在内存中的开始位置。
- 段的管理属性。比如只读,系统专用等等
CPU用8bytes(=64bits)来表示这些信息(叫做descriptor)。但是,CPU用来指定段的register只有16bits。就算是32bit的CPU,这个register也是16bits的。那怎么办呢?
方法就是每个segment给一个"编号"(正式叫做segment selector),然后在把这个编号放在register里就好了。剩下的工作就是让编号和segment一一对应起来。
大概的感觉是这样的:
1号segment的大小是4GB,从内存的0000开始。(也就是指整个内存了。)
2号segment的大小是xxKB,从内存的xxxx开始。。。。
segment的编号为0~8191。 刚才说了,segment register是16bits,按理说应该可以存放2**16 = 65536个编号。但是由于CPU设计式样的问题,最低3bits不能用,也就是只有13bits可用,刚好是2**13=8192个。
每个segment的描述需要8bytes,一共就需要8192*8=64KB。CPU里可没有这么大的空间。所以就放在内存里好了。这个64KB(可以小于这个值),记录了分段信息的数据结构就叫做GDT -- Global (segment) Descriptor Table. 我不知道这个东东的正式翻译是什么,直译过来就是一个存放了描述分段信息的表。
这次介绍了GDT的概念和这个东东是怎么来的,干什么用的。
下次介绍segment descriptor的数据结构,和如何使用。
书中第3章介绍保护模式的时候,题到了GDT这个东东。在这里给出一个更浅显的介绍。
在介绍GDT这个概念前,现介绍一下segmentation这个概念。
大家还记得ORG这个汇编命令吧。书的开篇,给出的boot.asm代码的第一行就是:
ORG 0x7c00
这个ORG就是告诉CPU,程序被载入内存的0x7c00这个地方了。也就是说CPU从这个内存地址开始读取指令就OK了。
但是,现在的CPU同时执行好几个程序是很正常的事情。那么不同的程序使用的内存就有可能重叠,这样载入程序的话就会发生冲突。解决方法之一就是把把内存分成若干个段(segmentation)。每段放一个程序,这样每个程序都可以声明ORG 0了。很方便。
(另一个解决方法是paging,这个以后有机会在谈。)
为了能使用segmentation, 每个段(segment)都需要清楚的表明以下信息:
- 段(segment)的大小。
- 段在内存中的开始位置。
- 段的管理属性。比如只读,系统专用等等
CPU用8bytes(=64bits)来表示这些信息(叫做descriptor)。但是,CPU用来指定段的register只有16bits。就算是32bit的CPU,这个register也是16bits的。那怎么办呢?
方法就是每个segment给一个"编号"(正式叫做segment selector),然后在把这个编号放在register里就好了。剩下的工作就是让编号和segment一一对应起来。
大概的感觉是这样的:
1号segment的大小是4GB,从内存的0000开始。(也就是指整个内存了。)
2号segment的大小是xxKB,从内存的xxxx开始。。。。
segment的编号为0~8191。 刚才说了,segment register是16bits,按理说应该可以存放2**16 = 65536个编号。但是由于CPU设计式样的问题,最低3bits不能用,也就是只有13bits可用,刚好是2**13=8192个。
每个segment的描述需要8bytes,一共就需要8192*8=64KB。CPU里可没有这么大的空间。所以就放在内存里好了。这个64KB(可以小于这个值),记录了分段信息的数据结构就叫做GDT -- Global (segment) Descriptor Table. 我不知道这个东东的正式翻译是什么,直译过来就是一个存放了描述分段信息的表。
这次介绍了GDT的概念和这个东东是怎么来的,干什么用的。
下次介绍segment descriptor的数据结构,和如何使用。