读书人

Xen源代码分析(3)x86_32.s

发布时间: 2012-11-25 11:44:31 作者: rapoo

Xen源代码分析(三)——x86_32.s

X86_32.s文件,32位下启动汇编程序的最后阶段,主要工作为装入堆栈指针, Xen会在栈顶分配一个cpu_info结构,这个结构包含很多重要的成员:1)客户系统的切换上下文2)当前运行的vcpu指针3)物理处理器编号1,IDT的处理,整个idt_table的向量入口都初始化ignore_int,这个中断处理函数打印"Unknown interrupt(cr2=XXXXXXXX)"信息后系统进入循环2,如果是BSP,跳转到__start_xen否则,跳转到start_secondary

.code32

/* Enable full CR4 features. */

mov mmu_cr4_features,%eax

mov %eax,%cr4

/* Initialise stack. */

/*在栈顶分配一个cpu_info结构(参见下图),这个结构包含很多重要的成员:

1)客户系统的切换上下文2)当前运行的vcpu指针3)物理处理器编号*/

mov stack_start,%esp

or $(STACK_SIZE-CPUINFO_sizeof),%esp

/* Reset EFLAGS (subsumes CLI and CLD). */

pushl $0

popf

lidt idt_descr/*加载中断描述符表*/

test %ebx,%ebx

jnz start_secondary

/* Initialise IDT with simple error defaults. */

lea ignore_int,%edx

mov $(__HYPERVISOR_CS << 16),%eax

mov %dx,%ax /* selector = 0x0010 = cs */

mov $0x8E00,%dx /* interrupt gate - dpl=0, present */

lea idt_table,%edi

mov $256,%ecx

1: mov %eax,(%edi)

mov %edx,4(%edi)

add $8,%edi

loop 1b

/* Pass off the Multiboot info structure to C land. */

pushl multiboot_ptr

call __start_xen/*调用该函数正式调入C代码初始化中*/

ud2 /* Force a panic (invalid opcode). */

/* This is the default interrupt handler. */

int_msg:

.asciz "Unknown interrupt (cr2=%08x)\n"

hex_msg:

.asciz " %08x"

ALIGN

ignore_int:

pusha

cld

mov $(__HYPERVISOR_DS),%eax

mov %eax,%ds

mov %eax,%es

mov %cr2,%eax

push %eax

pushl $int_msg

call printk

add $8,%esp

mov %esp,%ebp

0: pushl (%ebp)

add $4,%ebp

pushl $hex_msg

call printk

add $8,%esp

test $0xffc,%ebp

jnz 0b

1: jmp 1b

.data

ALIGN

ENTRY(stack_start)

.long cpu0_stack

/*** DESCRIPTOR TABLES ***/

ALIGN

multiboot_ptr:

.long 0

.word 0

idt_descr:

.word 256*8-1

.long idt_table

.word 0

gdt_descr:/*在第二阶段装载了*/

.word LAST_RESERVED_GDT_BYTE

.long boot_cpu_gdt_table - FIRST_RESERVED_GDT_BYTE

.align 32

ENTRY(idle_pg_table)

.long sym_phys(idle_pg_table_l2) + 0*PAGE_SIZE + 0x01, 0

.long sym_phys(idle_pg_table_l2) + 1*PAGE_SIZE + 0x01, 0

.long sym_phys(idle_pg_table_l2) + 2*PAGE_SIZE + 0x01, 0

.long sym_phys(idle_pg_table_l2) + 3*PAGE_SIZE + 0x01, 0

.section .data.page_aligned, "aw", @progbits

.align PAGE_SIZE, 0

/* NB. Rings != 0 get access up to MACH2PHYS_VIRT_END. This allows access to */

/* the machine->physical mapping table. Ring 0 can access all memory. */

#define GUEST_DESC(d) \

.long ((MACH2PHYS_VIRT_END - 1) >> 12) & 0xffff, \

((MACH2PHYS_VIRT_END - 1) >> 12) & (0xf << 16) | (d)

ENTRY(boot_cpu_gdt_table)

.quad 0x0000000000000000 /* double fault TSS */

.quad 0x00cf9a000000ffff /* 0xe008 ring 0 4.00GB code at 0x0 */

.quad 0x00cf92000000ffff /* 0xe010 ring 0 4.00GB data at 0x0 */

GUEST_DESC(0x00c0ba00) /* 0xe019 ring 1 3.xxGB code at 0x0 */

GUEST_DESC(0x00c0b200) /* 0xe021 ring 1 3.xxGB data at 0x0 */

GUEST_DESC(0x00c0fa00) /* 0xe02b ring 3 3.xxGB code at 0x0 */

GUEST_DESC(0x00c0f200) /* 0xe033 ring 3 3.xxGB data at 0x0 */

.fill (PER_CPU_GDT_ENTRY - FLAT_RING3_DS / 8 - 1), 8, 0

.quad 0x0000910000000000 /* per-CPU entry (limit == cpu) */

.align PAGE_SIZE,0

读书人网 >云计算

热点推荐