Xen源代码分析(二)——trampoline.s

汇编文件trampoline.s,为启动汇编程序第二阶段,主要工作为进入实模式,读取内存,磁盘,视频信息然后再次进入保护模式装入新的GDT(gdt_table),英文注释了很大部分,很容易理解。下面的代码注释中,从标号0开始运行,然后是标号1。

  1  .code16
  2 /* NB. bootsym() is only usable in real mode, or via BOOT_PSEUDORM_DS. */
  3 #undef bootsym
  4 /*bootsym(s)定义的是s的相对位置*/
  5 #define bootsym(s) ((s)-trampoline_start)
  6 
  7 #define bootsym_rel(sym, off, opnd...)     \
  8         bootsym(sym),##opnd;               \
  9 111:;                                      \
 10         .pushsection .trampoline_rel, "a"; \
 11         .long 111b - (off) - .;            \
 12         .popsection
 13 
 14 #define bootsym_segrel(sym, off)           \
 15         $0,$bootsym(sym);                  \
 16 111:;                                      \
 17         .pushsection .trampoline_seg, "a"; \
 18         .long 111b - (off) - .;            \
 19         .popsection
 20 
 21         .globl trampoline_realmode_entry
 22 trampoline_realmode_entry:
 23         mov     %cs,%ax
 24         mov     %ax,%ds
 25         movb    $0xA5,bootsym(trampoline_cpu_started)
 26         cld
 27         cli
 28         lidt    bootsym(idt_48)
 29         lgdt    bootsym(gdt_48)
 30         mov     $1,%bl                    # EBX != 0 indicates we are an AP
 31         xor     %ax, %ax
 32         inc     %ax
 33         lmsw    %ax                       # CR0.PE = 1 (enter protected mode)
 34         ljmpl   $BOOT_CS32,$bootsym_rel(trampoline_protmode_entry,6)
 35 
 36 idt_48: .word   0, 0, 0 # base = limit = 0
 37 gdt_48: .word   6*8-1
 38         .long   bootsym_rel(trampoline_gdt,4)
 39 trampoline_gdt:
 40         /* 0x0000: unused */
 41         .quad   0x0000000000000000
 42         /* 0x0008: ring 0 code, 32-bit mode */
 43         .quad   0x00cf9a000000ffff
 44         /* 0x0010: ring 0 code, 64-bit mode */
 45         .quad   0x00af9a000000ffff
 46         /* 0x0018: ring 0 data */
 47         .quad   0x00cf92000000ffff
 48         /* 0x0020: real-mode code @ BOOT_TRAMPOLINE */
 49         .long   0x0000ffff
 50         .long   0x00009a00
 51         /* 0x0028: real-mode data @ BOOT_TRAMPOLINE */
 52         .long   0x0000ffff
 53         .long   0x00009200
 54 
 55         .pushsection .trampoline_rel, "a"
 56         .long   trampoline_gdt + BOOT_PSEUDORM_CS + 2 - .
 57         .long   trampoline_gdt + BOOT_PSEUDORM_DS + 2 - .
 58         .popsection
 59 
 60         .globl cpuid_ext_features
 61 cpuid_ext_features:
 62         .long   0
 63 
 64         .globl trampoline_xen_phys_start
 65 trampoline_xen_phys_start:
 66         .long   0
 67 
 68         .globl trampoline_cpu_started
 69 trampoline_cpu_started:
 70         .byte   0
 71 
 72         .code32
 73         /*1: 从实模式跳转到这里运行,也就是正式进入保护模式*/
 74 trampoline_protmode_entry:
 75         /* Set up a few descriptors: on entry only CS is guaranteed good. */
 76         mov     $BOOT_DS,%eax
 77         mov     %eax,%ds
 78         mov     %eax,%es
 79 
 80         /* Set up FPU. */
 81         fninit
 82 
 83         /* Initialise CR4. */
 84         mov     $X86_CR4_PAE,%ecx
 85         mov     %ecx,%cr4
 86 
 87         /* Load pagetable base register. */
 88         mov     $sym_phys(idle_pg_table),%eax
 89         add     bootsym_rel(trampoline_xen_phys_start,4,%eax)
 90         mov     %eax,%cr3
 91 
 92         /* Set up EFER (Extended Feature Enable Register). */
 93         mov     bootsym_rel(cpuid_ext_features,4,%edi)
 94         test    $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
 95         jz      .Lskip_efer
 96         movl    $MSR_EFER,%ecx
 97         rdmsr
 98 #if CONFIG_PAGING_LEVELS == 4
 99         btsl    $_EFER_LME,%eax /* Long Mode      */
100         btsl    $_EFER_SCE,%eax /* SYSCALL/SYSRET */
101 #endif
102         btl     $20,%edi        /* No Execute?    */
103         jnc     1f
104         btsl    $_EFER_NX,%eax  /* No Execute     */
105 1:      wrmsr
106 .Lskip_efer:
107 
108         mov     $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
109         mov     %eax,%cr0
110         jmp     1f
111 1:
112 
113 #if defined(__x86_64__)
114 
115         /* Now in compatibility mode. Long-jump into 64-bit mode. */
116         ljmp    $BOOT_CS64,$bootsym_rel(start64,6)
117 
118         .code64
119 start64:
120         /* Jump to high mappings. */
121         mov     high_start(%rip),%rax
122         jmpq    *%rax
123 
124 high_start:
125         .quad   __high_start
126 
127 #else /* !defined(__x86_64__) */
128 
129         /* Install relocated selectors. */
130 lgdt    gdt_descr/*正式装载初始化后的GDT,这里装入的GDT为汇编期间最终的GDT,在x86_32.s中定义*/
131         mov     $(__HYPERVISOR_DS),%eax
132         mov     %eax,%ds
133         mov     %eax,%es
134         mov     %eax,%fs
135         mov     %eax,%gs
136         mov     %eax,%ss
137         /*长跳转到x86_32.s的入口__high_start,该变量在head.s中定义,为x86_32.s的入口,x86_32.s
138         在head.s中以包含的方式调用*/
139         ljmp    $(__HYPERVISOR_CS),$__high_start
140 
141 #endif
142 
143         .code32
144 /*0: 从head.s的ret指令跳转后首先到达这里开始执行,32位代码,此时还处在保护模式下*/
145 trampoline_boot_cpu_entry:
146         cmpb    $0,bootsym_rel(skip_realmode,5)
147         jnz     .Lskip_realmode
148 
149         /* Load pseudo-real-mode segments. */
150         mov     $BOOT_PSEUDORM_DS,%eax
151         mov     %eax,%ds
152         mov     %eax,%es
153         mov     %eax,%fs
154         mov     %eax,%gs
155         mov     %eax,%ss
156 
157         /* Switch to pseudo-rm CS, enter real mode, and flush insn queue. */
158         mov     %cr0,%eax
159         dec     %eax
160         /*通过下面两个长跳转切换到实模式*/
161         ljmp    $BOOT_PSEUDORM_CS,$bootsym(1f)
162         .code16
163 1:      mov     %eax,%cr0                 # CR0.PE = 0 (leave protected mode)
164 
165         /* Load proper real-mode values into %cs, %ds, %es and %ss. */
166         ljmp    bootsym_segrel(1f,2)
167 1:      mov     %cs,%ax
168         mov     %ax,%ds
169         mov     %ax,%es
170         mov     %ax,%ss
171 
172         /* Initialise stack pointer and IDT, and enable irqs. */
173         xor     %sp,%sp
174         lidt    bootsym(rm_idt)/*加载IDT*/
175         sti
176 
177 #if defined(__x86_64__)
178         /*
179          * Declare that our target operating mode is long mode.
180          * Initialise 32-bit registers since some buggy BIOSes depend on it.
181          */
182         movl    $0xec00,%eax      # declare target operating mode
183         movl    $0x0002,%ebx      # long mode
184         int     $0x15
185 #endif
186 
187         /*
188          * Do real-mode work:
189          *  1. Get memory map.
190          *  2. Get Enhanced Disk Drive (EDD) information.
191          *  3. Set video mode.
192          */
193          /*获得内存信息,该函数于mem.s中调用,内存信息存放于e820map变量中,
194          类似Linux内核的处理方式,调用0x15号中断*/
195         call    get_memory_map
196         /*调用于edd.s中*/
197         call    get_edd
198            /*调用于video.s中*/
199         call    video
200 
201         /* Disable irqs before returning to protected mode. */
202         cli
203 
204         /* Reset GDT and IDT. Some BIOSes clobber GDTR. */
205         lidt    bootsym(idt_48)
206         lgdt    bootsym(gdt_48)
207 
208         /* Enter protected mode, and flush insn queue. */
209         xor     %ax,%ax
210         inc     %ax
211         lmsw    %ax                       # CR0.PE = 1 (enter protected mode)
212 
213         /* Load proper protected-mode values into all segment registers. */
214         /*跳转到32位代码,为进入保护模式做准备*/
215         ljmpl   $BOOT_CS32,$bootsym_rel(1f,6)
216         .code32
217 1:      mov     $BOOT_DS,%eax
218         mov     %eax,%ds
219         mov     %eax,%es
220         mov     %eax,%fs
221         mov     %eax,%gs
222         mov     %eax,%ss
223 
224 .Lskip_realmode:
225         /* EBX == 0 indicates we are the BP (Boot Processor). */
226         xor     %ebx,%ebx
227 
228         /* Jump to the common bootstrap entry point. */
229         jmp     trampoline_protmode_entry/*跳转到保护模式入口*/
230 
231 skip_realmode:
232         .byte   0
233 
234 rm_idt: .word   256*4-1, 0, 0
235 /*这三部分的内容不再这里详细写了*/
236 #include "mem.S"
237 #include "edd.S"
238 #include "video.S"
239 #include "wakeup.S"


 

posted @ 2012-11-15 09:41  GOD!  阅读(1884)  评论(0编辑  收藏  举报