reactos操作系统实现(13)
/*
Get GDT, IDT, PCR and TSS pointers */
    KiGetMachineBootPointers(&Gdt,
&Idt, &Pcr, &Tss);
它是代表什么意思呢?实际上是获取全局描述符表、中断描述符表、进程控制块和任务状态段的指针。那么这个函数又是怎么样实现的呢?
先来分析怎么样获取GDT和IDT的指针,它的代码如下:
#001      /* Get GDT and IDT descriptors */
#002      Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&GdtDescriptor.Limit);
#003     
Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&IdtDescriptor.Limit);
#004  
#005      /* Save IDT and GDT */
#006      *Gdt = (PKGDTENTRY)GdtDescriptor.Base;
#007      *Idt = (PKIDTENTRY)IdtDescriptor.Base;
GDT是先从GDTR寄存器里获取到全局描述符表,然后再从里面得到全局描述符表所地的基地址。相应的IDT也是从IDTR寄存器获取中断描述符表,然后从里得到IDT所指针的基地址,也就是指针地址了。
#001   /* Get TSS and FS Selectors */
#002      Ke386GetTr(Tr);
#003      if (Tr != KGDT_TSS) Tr = KGDT_TSS; //
FIXME: HACKHACK
#004      Fs = Ke386GetFs();
第2行是从任务寄存器TR里获取到任务描述符,如果这个描述符不是内核任务,就强制转换为内核任务。
第4行是获取FS段选择子,以便后面获取PCR指针。
#001   /* Get PCR Selector, mask it and get its GDT
Entry */
#002      PcrSelector =
*(PKGDTENTRY)((ULONG_PTR)*Gdt + (Fs & ~RPL_MASK));
#003  
#004      /* Get the KPCR itself */
#005      *Pcr =
(PKIPCR)(ULONG_PTR)(PcrSelector.BaseLow |
#006                                 PcrSelector.HighWord.Bytes.BaseMid
<< 16 |
#007                                
PcrSelector.HighWord.Bytes.BaseHi << 24);
这段代码第2行是获取进程序控制控制块的描述符,第5行代码是通过描述符计算出PCR所在位置。
#001   /* Get TSS Selector, mask it and get its GDT
Entry */
#002      TssSelector =
*(PKGDTENTRY)((ULONG_PTR)*Gdt + (Tr & ~RPL_MASK));
#003  
#004      /* Get the KTSS itself */
#005      *Tss = (PKTSS)(ULONG_PTR)(TssSelector.BaseLow
|
#006                               
TssSelector.HighWord.Bytes.BaseMid << 16 |
#007                               
TssSelector.HighWord.Bytes.BaseHi << 24);
这段代码,主要获取TSS的描述符,然后通过描述符计算出TSS任务所在地址。
通过上面分析,就理解怎么样获取全局重要的数据方式,学会使用它到其它地方。
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号