能力值:
( LV6,RANK:80 )
|
-
-
2 楼
莫不是我想象力不够。?开了N多个Notepad,仅有4个TSS段描述符。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
LDT不是全局可见的,它们只对引用它们的任务可见,每个任务最多可以拥有一个LDT。另外,每一个LDT自身作为一个段存在,它们的段描述符被放在GDT中。
IA-32为LDT的入口地址也提供了一个寄存器LDTR,因为在任何时刻只能有一个任务在运行,所以LDT寄存器全局也只需要有一个。如果一个任务拥有自身的LDT,那么当它需要引用自身的LDT时,它需要通过LLDT将其LDT的段描述符装入此寄存器。LLDT指令与LGDT指令不同的时,LGDT指令的操作数是一个32-bit的内存地址,这个内存地址处存放的是一个32-bit GDT的入口地址,以及16-bit的GDT Limit。而LLDT指令的操作数是一个16-bit的选择子,这个选择子主要内容是:被装入的LDT的段描述符在GDT中的索引值——这一点和刚才所讨论的通过段积存器引用段的模式是一样的 http://zhidao.baidu.com/question/55293031.html
|
能力值:
( LV6,RANK:80 )
|
-
-
4 楼
这个解释依然没有从问题角度出发、
|
能力值:
( LV10,RANK:170 )
|
-
-
5 楼
windows的进程地址空间隔离不是用的ldt,而是用的页目录来实现的
只是兼容16位程序部分用到了ldt,
linux貌似也没有使用ldt。。。
|
能力值:
( LV10,RANK:170 )
|
-
-
6 楼
所以你说的一个进程一个ldt 本身就是错误的
|
能力值:
( LV13,RANK:388 )
|
-
-
7 楼
windows和linux都没有使用tss和ldt,任务内存的隔离使用分页机制就足够了
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
楼上两楼正解。。。windows对于tss任务状态段 也没有用。。。有些地方检测只是为了上下兼容而已,其实对于程序员没有任何意义。
|
能力值:
( LV6,RANK:80 )
|
-
-
9 楼
若没有使用那么cs当中的选择子应当从哪里获取对应的基址呢?不要告诉我不使用LDT后cs也不用了。。或者直接使用GDT,那是无法接受的。
|
能力值:
( LV6,RANK:80 )
|
-
-
10 楼
那没有使用tss进程切换时的寄存器又从哪来?…
|
能力值:
( LV5,RANK:70 )
|
-
-
11 楼
windows下段选择子使用的是GDT,
线程的寄存器列表是存在trap frame中的。
|
能力值:
( LV6,RANK:80 )
|
-
-
12 楼
1.CS、ES、DS、SS 若是GDT的牵引的话,我开了70多个程序,GDT的内容却并没有发生什么变化。
2.依靠Trap_frame进行线程现场保存,这个应该是进入门后发生的事情。
以此想象,如果依靠Trap_frame进行线程切换的话,线程切出的话可以理解,但是一个线程被切入,那么这个线程应该从哪里获得之前的寄存器值呢?
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
windows没有任务切换的概念,只有线程切换的概念。不断的切换线程而已,没有任务的概念。线程切换的时候,先构建一个Trap_frame结构体,将当前线程的所以寄存器环境保存下来,以便下次执行的时候恢复。然后切换到另外一个线程(这中间还有一些其他事情,由于篇幅不想多说)。每一个线程都拥有一个Trap_frame结构,三环的时候是CONTEXT 结构,线程从0环回到三环的时候就是用Trap_frame结构去初始化CONTEXT结构。。。。。。建议楼主好好去学习,再来一争高下。。。这些东西不是人家不愿意跟你说,是因为很复杂,不是一两句能解释的清楚。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
windows 很多实现机制并不是完全用的cpu提供的东西
|
能力值:
( LV6,RANK:90 )
|
-
-
15 楼
有待商榷,最直接的问题是,如果系统不使用tss, 那么cpu从3环跳到0环的时候,此时,内核栈的地址是从哪取得?
对了,我还想知道,windows 的进程的内核栈是怎么分配的,多大,每个进程一个还是所有进程共享?
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
你想得太复杂了,具体你可以去看一下wrk里的处理过程
内核栈是和线程有关的,每一个ring3线程拥一个内核栈和ring3栈
|
能力值:
( LV6,RANK:90 )
|
-
-
17 楼
恩,从理论上说,每个进程的的内核栈是独立的,确实也应该这么设计。
楼上的诸位说Windows 或者 Linux 没用到tss,那是不正确的,Windows我不晓得,但是Linux确实是用到了,值不过是用到了tss中很少的几个变量。
楼主的问题是 早期Linux内核 的问题。早期Linux内核的进程切换是靠jmp一个任务的tss选择子来实现任务切换,而这个任务的选择子就保存在gdt中。所以说,由于gdt的大小的限制,系统中的进程数也有限制。
而现代的操作系统都不这么干了,Linux 2.6的内核系统中之用到了一个全局 的tss,而每个进程的信息都保存在了自己的结构体中。系统中不用到tss是不可能的,因为intel手册中说,当CPU发生特权级转变的时候,会从当前的tss中取对应的栈地址给esp,比如说,从ring3 跳到ring0,那么cpu会从tss中的esp0域中取内核栈地址。
如果只使用一个tss,那么系统的 中进程数就可以突破gdt的大小的限制了。其实在进程环境切换到时候,都会重新设置一个这个全局tss中esp0的值,在Linux内核中,查查switch_to这个宏,确实也这么做了。至于ldt那不是必须的,Linux中的ldt是可以动态申请的。
|
能力值:
( LV6,RANK:80 )
|
-
-
18 楼
好的,谢谢了。终于理解了。
|
|
|