GDTR和LDTR中放置的是物理地址还是线性地址?

ygb913 2008-11-06 02:59:02
系统启动时候要设置GDTR和LDTR,它们使用的是线性地址还是物理地址呢?如果是物理地址,是不是说启动到这个时候,分页机制并没有开启,也就是说先转换到32位保护模式,不过是段式的?如果是线性地址的话,是不是说之前就要先设置好页目录和页表,然后装入它们,开启32位保护模式就是直接开启了分页机制?
...全文
1020 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
artszhao 2008-11-13
  • 打赏
  • 举报
回复
and, after the stack is init and started, again lgdt the gdt descriptor.

you can refer to the setup.s of bootloader and entry_32.s of linux. or dxinit.asm of winNT codes.


thanks

artszhao 2008-11-13
  • 打赏
  • 举报
回复
From here you can consider that the address in gdt is line address.
<------------------------------------------------------------->
/*
* Set segments to known values.
*/
lgdt pa(boot_gdt_descr) //here, gdt address to pa address.
movl $(__BOOT_DS),%eax
movl %eax,%ds
movl %eax,%es
movl %eax,%fs
movl %eax,%gs
<------------------------------------------------------------->


and, for pgd, (pmd), pte, are set up after the segment set, bss clear, and bootup parameter to be copy out of the ram.
so, its init is back far from the gdt configurations.


thanks
artszhao 2008-11-13
  • 打赏
  • 举报
回复
实模式何须要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 *///*************************/
DATA32 ADDR32 lgdt gdtdesc //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 */
DATA32 ljmp $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 */
movl protstack, %eax
movl %eax, %esp
movl %eax, %ebp

/* get return address onto the right stack */
movl GRUB_MEMORY_MACHINE_REAL_STACK, %eax
movl %eax, (%esp)

/* zero %eax */
xorl %eax, %eax

/* return on the old (or initialized) stack! */
ret
<------------------------------------------------------------------------------>

zkuang82 2008-11-07
  • 打赏
  • 举报
回复
好。。谢了。^_^
campuspuzzle 2008-11-07
  • 打赏
  • 举报
回复
应该是的
zkuang82 2008-11-07
  • 打赏
  • 举报
回复
也就是说我把保护模式的概念用再分页上了,其实它是段管理上的?
campuspuzzle 2008-11-07
  • 打赏
  • 举报
回复
没有GDT进不了保护模式啊
zkuang82 2008-11-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 campuspuzzle 的回复:]
难得周末这么晚还在关注技术,呵呵,这个你可以看看《情景分析》下册的启动过程。
[/Quote]

不懂的东西太多,不得不努力。。^_^
zkuang82 2008-11-07
  • 打赏
  • 举报
回复
如果是这样,为什么不在分页建立以后才去初始化GDT呢?
campuspuzzle 2008-11-07
  • 打赏
  • 举报
回复
分页前和分页后设置了两次
campuspuzzle 2008-11-07
  • 打赏
  • 举报
回复
难得周末这么晚还在关注技术,呵呵,这个你可以看看《情景分析》下册的启动过程。
zkuang82 2008-11-07
  • 打赏
  • 举报
回复
恩,似乎我搞错了保护模式的概念。。
无妨。。。。如果两者无关,那么跟段页的讨论也没有什么关系。撇开保护模式,还是能回到原来的讨论上来。
那么问题应该是:
GDT是在分页建立以后初始化的还是在分页建立之前初始化的?
ittechbay 2008-11-07
  • 打赏
  • 举报
回复
在CUP硬件机制上:
开机进入实模式,要想进入保护模式只需设置的第0位(PE)置位,要想启用分页机制只需将CR0寄存器的第31为(PG)位置位。

另外保护模式与启用分页机制是两个不同的概念

参考资料The Intel® 64 and IA-32 Architectures Software Developer's Manual(Volume 3A System Programming Guide)
zkuang82 2008-11-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 campuspuzzle 的回复:]
系统开机时,进入的实模式,这个时候如果想进入保护模式,必须先设置GDT表,所以首先是在实模式设置GDT表
为进入保护模式做准备,这个时候当然用的都是物理地址,但进入保护模式后,分段启用,那些设置的物理地址
就被当成线性地址使用了,所以GDT要设置成使得物理地址和线性地址等价,就linux来说,进入保护模式后利用
实模式设置的那个临时GDT,开启分页,以后又再次重新设置了新的GDT,这个GDT就全用的线性地址了。
[/Quote]

这个概念是不是搞错了?
GDT本身是用于把逻辑地址映射到线性地址空间的,真正把线性地址映射到这个跟Page_table。所以我不明白的是为什么进入保护模式前必须设置GDT呢?似乎只需要把Page_table设置好,就已经可以进入保护模式了,也就是分页机制已经启用。所以,似乎真正要设置成使得物理地址我线性地址等价的应该是Page_table的内容,而不是GDT。这个过程再Understanding Linux Kernel的第三版说明的比较详细,但似乎没有提到GDT的初始化时机。

不知道我有没有搞错。^_^
campuspuzzle 2008-11-07
  • 打赏
  • 举报
回复
系统开机时,进入的实模式,这个时候如果想进入保护模式,必须先设置GDT表,所以首先是在实模式设置GDT表
为进入保护模式做准备,这个时候当然用的都是物理地址,但进入保护模式后,分段启用,那些设置的物理地址
就被当成线性地址使用了,所以GDT要设置成使得物理地址和线性地址等价,就linux来说,进入保护模式后利用
实模式设置的那个临时GDT,开启分页,以后又再次重新设置了新的GDT,这个GDT就全用的线性地址了。
ygb913 2008-11-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 elfirex 的回复:]
既然是放线性地址,为什么不延后到Page_table初始化完成之后在设置GDT呢?在这个过程当中应该还没有用到GDT吧,这样做应该是安全的。也就是问题转化成:GDT是在实模式下初始化的还是在保护模式下初始化的。
[/Quote]
嗯呐,就是说,系统初始化时候,设置GDT时候,有没有设置页表,稍微看了一下,貌似刚开始时候还没有页表的时候就已经初始化GDTR了,所以这个时候应该是物理地址,当分页开启以后,GDTR所使用的就是线性地址了,我这样理解对吗?
zkuang82 2008-11-07
  • 打赏
  • 举报
回复
既然是放线性地址,为什么不延后到Page_table初始化完成之后在设置GDT呢?在这个过程当中应该还没有用到GDT吧,这样做应该是安全的。也就是问题转化成:GDT是在实模式下初始化的还是在保护模式下初始化的。
campuspuzzle 2008-11-06
  • 打赏
  • 举报
回复
确切的说是放的线性地址,在实模式下可以设置GDT,当然用的是物理地址,但切换进保护模式后,要保证那个
物理地址变为线性地址还能正确寻址,这是通过正确设置GDT实现的,不过多半是把基地址设置成0.
ygb913 2008-11-06
  • 打赏
  • 举报
回复
如果根本没有启动分页的话,不知道i386能不能在32位模式下仅仅启用分段管理,如果这样的话,就是物理地址了吧
zhoujianhei 2008-11-06
  • 打赏
  • 举报
回复
是线性地址

4,468

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧