设为首页 收藏本站
查看: 1373|回复: 0

[经验分享] Xen源代码分析(二)——trampoline.s

[复制链接]

尚未签到

发表于 2015-4-13 12:22:48 | 显示全部楼层 |阅读模式
  汇编文件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、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-56656-1-1.html 上篇帖子: Xen入门系列二【使用 virt-install 安装虚拟机】 下篇帖子: xen,xen关闭
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表