blovekyo 发表于 2015-4-13 12:22:48

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"
  
页: [1]
查看完整版本: Xen源代码分析(二)——trampoline.s