先说下昨天的zreladdr,定义在Makefile里。
-
arch/arm/boot/Makefile
-
-
20 # Note: the following conditions must always be true:
-
21 # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
-
22 # PARAMS_PHYS must be within 4MB of ZRELADDR
-
23 # INITRD_PHYS must be in RAM
-
24 ZRELADDR := $(zreladdr-y)
-
25 PARAMS_PHYS := $(params_phys-y)
-
26 INITRD_PHYS := $(initrd_phys-y)
-
-
-
arch/arm/mach-exynos/Makefile.boot
-
-
1 zreladdr-y := 0x40008000
-
2 params_phys-y := 0x40000100
昨天跑出early_printk
-
(XEN) DOM0: Uncompressing Linux... done, booting the kernel.
-
(XEN) uty: do_trap_data_abort_guest
-
(XEN) uty: pc=0x800081a4
-
(XEN) uty: info.gva=0x0
-
(XEN) uty: info.gpa=0x0
-
(XEN) uty: about to handle_mmio()
-
(XEN) uty: handle_mmio gpa 0x0
又到0x800081a4出错,访问0地址。
开始以为是内核解压函数解到地方和最终调用的地方不一样,0x800081a4这里的数据是0。其实是没仔细想,如果真是这样,这地址的数据是0,会是这个错误吗? 现在也还是没想清楚。
不过为了验证这个假设,找到了内核解压函数。
arch/arm/boot/compressed/head.S
-
339 /*
-
340 * The C runtime environment should now be setup sufficiently.
-
341 * Set up some pointers, and start decompressing.
-
342 * r4 = kernel execution address
-
343 * r7 = architecture ID
-
344 * r8 = atags pointer
-
345 */
-
346 mov r0, r4
-
347 mov r1, sp @ malloc space above stack
-
348 add r2, sp, #0x10000 @ 64k max
-
349 mov r3, r7
-
350 bl decompress_kernel
-
351 bl cache_clean_flush
-
352 bl cache_off
-
353 mov r0, #0 @ must be zero
-
354 mov r1, r7 @ restore architecture number
-
355 mov r2, r8 @ restore atags pointer
-
356 ARM( mov pc, r4 ) @ call kernel
-
357 THUMB( bx r4 ) @ entry point is always ARM
arch/arm/boot/compressed/misc.c
-
173 void
-
174 decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
-
175 unsigned long free_mem_ptr_end_p,
-
176 int arch_id)
-
177 {
-
178 int ret;
-
179
-
180 output_data = (unsigned char *)output_start;
-
181 free_mem_ptr = free_mem_ptr_p;
-
182 free_mem_end_ptr = free_mem_ptr_end_p;
-
183 __machine_arch_type = arch_id;
-
184
-
185 arch_decomp_setup();
-
186
-
187 putstr("Uncompressing Linux...");
-
188 ret = do_decompress(input_data, input_data_end - input_data,
-
189 output_data, error);
-
190 if (ret)
-
191 error("decompressor returned an error");
-
192 else
-
193 putstr(" done, booting the kernel.\n");
-
194 }
r4里是解压后的kernel应该在的位置。加了些输出,看了r4,可以用kphex r4, 8
-
(XEN) *** Serial input -> DOM0 (type 'CTRL-a' three times to switch input to Xen)
-
(XEN) Freed 264kB init memory.
-
(XEN) DOM0: 80008000uty test:
看来这个地址确实是kernel解压到了这里。后来我想,如果解压函数确实把内核解压到了这里,那这里的代码应该就是正确的。
这时候想到了是在0x800081a4这句上出错的。
-
[uty@localhost kernel]$ arm-eabi-objdump -d vmlinux |less
-
c0008000 :
-
c0008000: e321f0d3 msr CPSR_c, #211 ; 0xd3
-
c0008004: ee109f10 mrc 15, 0, r9, cr0, cr0, {0}
-
c0008008: eb16855a bl c05a9578 <__lookup_processor_type>
-
c000800c: e1b0a005 movs sl, r5
-
c0008010: 0a168569 beq c05a95bc <__error_p>
-
c0008014: e28f3030 add r3, pc, #48 ; 0x30
-
c0008018: e8930110 ldm r3, {r4, r8}
-
c000801c: e0434004 sub r4, r3, r4
-
c0008020: e0888004 add r8, r8, r4
-
c0008024: eb00005c bl c000819c <__vet_atags>
-
......
-
c000819c <__vet_atags>:
-
c000819c: e3120003 tst r2, #3
-
c00081a0: 1a000008 bne c00081c8 <__vet_atags+0x2c>
-
c00081a4: e5925000 ldr r5, [r2]
-
c00081a8: e3550005 cmp r5, #5
-
c00081ac: 13550002 cmpne r5, #2
-
c00081b0: 1a000004 bne c00081c8 <__vet_atags+0x2c>
找到了vet_atags的代码
arch/arm/kernel/head-common.S
-
35 /* Determine validity of the r2 atags pointer. The heuristic requires
-
36 * that the pointer be aligned, in the first 16k of physical RAM and
-
37 * that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE
-
38 * is selected, then it will also accept a dtb pointer. Future revisions
-
39 * of this function may be more lenient with the physical address and
-
40 * may also be able to move the ATAGS block if necessary.
-
41 *
-
42 * Returns:
-
43 * r2 either valid atags pointer, valid dtb pointer, or zero
-
44 * r5, r6 corrupted
-
45 */
-
46 __vet_atags:
-
47 tst r2, #0x3 @ aligned?
-
48 bne 1f
-
49
-
50 ldr r5, [r2, #0]
-
51 #ifdef CONFIG_OF_FLATTREE
-
52 ldr r6, =OF_DT_MAGIC @ is it a DTB?
-
53 cmp r5, r6
-
54 beq 2f
-
55 #endif
-
56 cmp r5, #ATAG_CORE_SIZE @ is first tag ATAG_CORE?
-
57 cmpne r5, #ATAG_CORE_SIZE_EMPTY
-
58 bne 1f
-
59 ldr r5, [r2, #4]
-
60 ldr r6, =ATAG_CORE
-
61 cmp r5, r6
-
62 bne 1f
-
63
-
64 2: mov pc, lr @ atag/dtb pointer is ok
-
65
-
66 1: mov r2, #0
-
67 mov pc, lr
-
68 ENDPROC(__vet_atags)
发现注释里说r2可以是0,但代码里没有判断。
加上两句
cmp r2, #0
beq 1f
再运行,这地方就跑过去了 :)
-
(XEN) 3... 2... 1...
-
(XEN) *** Serial input -> DOM0 (type 'CTRL-a' three times to switch input to Xen)
-
(XEN) Freed 264kB init memory.
-
(XEN) DOM0: Uncompressing Linux... done, booting the kernel.
-
(XEN) DOM0: <6>Initializing cgroup subsys cpu
-
(XEN) DOM0: <5>Linux version 3.0.31-g3370a7c-dirty (uty@localhost.localdomain) (gcc version 4.6.x-google 20120106
-
(XEN) DOM0: SMP PREEMPT Fri Dec 12 02:30:48 CST 2014
-
(XEN) DOM0: CPU: ARMv7 Processor [410fc0f4] revision 4 (ARMv7), cr=10c5387d
-
(XEN) DOM0: CPU: VIPT nonaliasing data cache, VIPT aliasing instruction cache
-
(XEN) DOM0: Machine: ARNDALE
-
(XEN) DOM0: <4>Default boot params at physical 0x40000100 out of reach
-
(XEN) DOM0: <4>Ignoring unrecognised tag 0x00000000
-
(XEN) DOM0: Memory policy: ECC disabled, Data cache writealloc
跑到后面没多远,又停了,还得接着调。
还有要说的是
因为xen里默认dom0的kernel是用dtb的,所以machine id传的是0xffffffff。但3.0.31的内核android是没有用dtb的,所以machine id要填正确的。
xen/arch/arm/domain_build.c
-
1048 if ( is_pv32_domain(d) )
-
1049 {
-
1050 regs->cpsr = PSR_GUEST32_INIT;
-
1051
-
1052 /* FROM LINUX head.S
-
1053 *
-
1054 * Kernel startup entry point.
-
1055 * ---------------------------
-
1056 *
-
1057 * This is normally called from the decompressor code. The requirements
-
1058 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
-
1059 * r1 = machine nr, r2 = atags or dtb pointer.
-
1060 *...
-
1061 */
-
1062 regs->r0 = 0; /* SBZ */
-
1063 // uty: test
-
1064 //regs->r1 = 0xffffffff; /* We use DTB therefore no machine id */
-
1065 regs->r1 = 4272;
-
1066 //regs->r2 = kinfo.dtb_paddr;
-
1067 regs->r2 = 0;
-
1068 }
为了在head.S里输出调式信息,我在Makefile里加了AFLAGS_head.o += -DDEBUG,为了打开代码里的#ifdef DEBUG,不知道有没什么更正经的办法操作这个的?
arch/arm/boot/compressed/Makefile
-
18 AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
-
19 AFLAGS_head.o += -DDEBUG
-
20 HEAD = head.o
-
21 OBJS += misc.o decompress.o
-
22 FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
阅读(1344) | 评论(0) | 转发(0) |