系统启动时候要设置GDTR和LDTR,它们使用的是线性地址还是物理地址呢?如果是物理地址,是不是说启动到这个时候,分页机制并没有开启,也就是说先转换到32位保护模式,不过是段式的?如果是线性地址的话,是不是说之前就要先设置好页目录和页表,然后装入它们,开启32位保护模式就是直接开启了分页机制?
|
系统开机时,进入的实模式,这个时候如果想进入保护模式,必须先设置GDT表,所以首先是在实模式设置GDT表
为进入保护模式做准备,这个时候当然用的都是物理地址,但进入保护模式后,分段启用,那些设置的物理地址
就被当成线性地址使用了,所以GDT要设置成使得物理地址和线性地址等价,就linux来说,进入保护模式后利用
实模式设置的那个临时GDT,开启分页,以后又再次重新设置了新的GDT,这个GDT就全用的线性地址了。
|
实模式何须要GDT/LDT等内存管理/分页分段的产物。
但是,GDT(boot_GDT)的建立是在实模式阶段进行的。
当然,GDT register里面的是线性地址了。
当real mode to protected mode时候,需要设定PDBR(cr3)的值,加载gdt(线性地址)。
每个process有一个gdt的copy,then they everyone can seperately modify their copy gdt.
ldt is build up after gdt.
the following codes are the codes what the real mode to protected mode.
real_to_prot:
.code16
cli
/* load the GDT register *///*************************/
DATA32ADDR32lgdtgdtdesc //load line address
/* turn on protected mode */
movl%cr0, %eax
orl$GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax
movl%eax, %cr0
/* jump to relocation, flush prefetch queue, and reload %cs */
DATA32ljmp$GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
.code32
protcseg:
/* reload other segment registers */
movw$GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
movw%ax, %ds
movw%ax, %es
movw%ax, %fs
movw%ax, %gs
movw%ax, %ss
/* put the return address in a known safe location */
movl(%esp), %eax
movl%eax, GRUB_MEMORY_MACHINE_REAL_STACK
/* get protected mode stack */
movlprotstack, %eax
movl%eax, %esp
movl%eax, %ebp
/* get return address onto the right stack */
movlGRUB_MEMORY_MACHINE_REAL_STACK, %eax
movl%eax, (%esp)
/* zero %eax */
xorl%eax, %eax
/* return on the old (or initialized) stack! */
ret