Chinaunix首页 | 论坛 | 博客
  • 博客访问: 21962
  • 博文数量: 10
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 140
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-05 00:47
文章分类

全部博文(10)

文章存档

2015年(1)

2014年(9)

我的朋友

分类: 虚拟化

2014-12-12 14:07:42

先说下昨天的zreladdr,定义在Makefile里。

  1. arch/arm/boot/Makefile

  2. 20 # Note: the following conditions must always be true:
  3. 21 # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
  4. 22 # PARAMS_PHYS must be within 4MB of ZRELADDR
  5. 23 # INITRD_PHYS must be in RAM
  6. 24 ZRELADDR := $(zreladdr-y)
  7. 25 PARAMS_PHYS := $(params_phys-y)
  8. 26 INITRD_PHYS := $(initrd_phys-y)


  9. arch/arm/mach-exynos/Makefile.boot

  10. 1 zreladdr-y := 0x40008000
  11. 2 params_phys-y := 0x40000100


昨天跑出early_printk

  1. (XEN) DOM0: Uncompressing Linux... done, booting the kernel.
  2. (XEN) uty: do_trap_data_abort_guest
  3. (XEN) uty: pc=0x800081a4
  4. (XEN) uty: info.gva=0x0
  5. (XEN) uty: info.gpa=0x0
  6. (XEN) uty: about to handle_mmio()
  7. (XEN) uty: handle_mmio gpa 0x0
又到0x800081a4出错,访问0地址。
开始以为是内核解压函数解到地方和最终调用的地方不一样,0x800081a4这里的数据是0。其实是没仔细想,如果真是这样,这地址的数据是0,会是这个错误吗? 现在也还是没想清楚。
不过为了验证这个假设,找到了内核解压函数。

arch/arm/boot/compressed/head.S
  1. 339 /*
  2. 340 * The C runtime environment should now be setup sufficiently.
  3. 341 * Set up some pointers, and start decompressing.
  4. 342 * r4 = kernel execution address
  5. 343 * r7 = architecture ID
  6. 344 * r8 = atags pointer
  7. 345 */
  8. 346 mov r0, r4
  9. 347 mov r1, sp @ malloc space above stack
  10. 348 add r2, sp, #0x10000 @ 64k max
  11. 349 mov r3, r7
  12. 350 bl decompress_kernel
  13. 351 bl cache_clean_flush
  14. 352 bl cache_off
  15. 353 mov r0, #0 @ must be zero
  16. 354 mov r1, r7 @ restore architecture number
  17. 355 mov r2, r8 @ restore atags pointer
  18. 356 ARM( mov pc, r4 ) @ call kernel
  19. 357 THUMB( bx r4 ) @ entry point is always ARM

arch/arm/boot/compressed/misc.c
  1. 173 void
  2. 174 decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
  3. 175 unsigned long free_mem_ptr_end_p,
  4. 176 int arch_id)
  5. 177 {
  6. 178 int ret;
  7. 179
  8. 180 output_data = (unsigned char *)output_start;
  9. 181 free_mem_ptr = free_mem_ptr_p;
  10. 182 free_mem_end_ptr = free_mem_ptr_end_p;
  11. 183 __machine_arch_type = arch_id;
  12. 184
  13. 185 arch_decomp_setup();
  14. 186
  15. 187 putstr("Uncompressing Linux...");
  16. 188 ret = do_decompress(input_data, input_data_end - input_data,
  17. 189 output_data, error);
  18. 190 if (ret)
  19. 191 error("decompressor returned an error");
  20. 192 else
  21. 193 putstr(" done, booting the kernel.\n");
  22. 194 }
r4里是解压后的kernel应该在的位置。加了些输出,看了r4,可以用kphex r4, 8

  1. (XEN) *** Serial input -> DOM0 (type 'CTRL-a' three times to switch input to Xen)
  2. (XEN) Freed 264kB init memory.
  3. (XEN) DOM0: 80008000uty test:
看来这个地址确实是kernel解压到了这里。后来我想,如果解压函数确实把内核解压到了这里,那这里的代码应该就是正确的。
这时候想到了是在0x800081a4这句上出错的。

  1. [uty@localhost kernel]$ arm-eabi-objdump -d vmlinux |less
  2. c0008000 :
  3. c0008000: e321f0d3 msr CPSR_c, #211 ; 0xd3
  4. c0008004: ee109f10 mrc 15, 0, r9, cr0, cr0, {0}
  5. c0008008: eb16855a bl c05a9578 <__lookup_processor_type>
  6. c000800c: e1b0a005 movs sl, r5
  7. c0008010: 0a168569 beq c05a95bc <__error_p>
  8. c0008014: e28f3030 add r3, pc, #48 ; 0x30
  9. c0008018: e8930110 ldm r3, {r4, r8}
  10. c000801c: e0434004 sub r4, r3, r4
  11. c0008020: e0888004 add r8, r8, r4
  12. c0008024: eb00005c bl c000819c <__vet_atags>
  13. ......
  14. c000819c <__vet_atags>:
  15. c000819c: e3120003 tst r2, #3
  16. c00081a0: 1a000008 bne c00081c8 <__vet_atags+0x2c>
  17. c00081a4: e5925000 ldr r5, [r2]
  18. c00081a8: e3550005 cmp r5, #5
  19. c00081ac: 13550002 cmpne r5, #2
  20. c00081b0: 1a000004 bne c00081c8 <__vet_atags+0x2c>
找到了vet_atags的代码

arch/arm/kernel/head-common.S
  1. 35 /* Determine validity of the r2 atags pointer. The heuristic requires
  2.  36 * that the pointer be aligned, in the first 16k of physical RAM and
  3.  37 * that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE
  4.  38 * is selected, then it will also accept a dtb pointer. Future revisions
  5.  39 * of this function may be more lenient with the physical address and
  6.  40 * may also be able to move the ATAGS block if necessary.
  7.  41 *
  8.  42 * Returns:
  9.  43 * r2 either valid atags pointer, valid dtb pointer, or zero
  10.  44 * r5, r6 corrupted
  11.  45 */
  12.  46 __vet_atags:
  13.  47 tst r2, #0x3 @ aligned?
  14.  48 bne 1f
  15.  49
  16.  50 ldr r5, [r2, #0]
  17.  51 #ifdef CONFIG_OF_FLATTREE
  18.  52 ldr r6, =OF_DT_MAGIC @ is it a DTB?
  19.  53 cmp r5, r6
  20.  54 beq 2f
  21.  55 #endif
  22.  56 cmp r5, #ATAG_CORE_SIZE @ is first tag ATAG_CORE?
  23.  57 cmpne r5, #ATAG_CORE_SIZE_EMPTY
  24.  58 bne 1f
  25.  59 ldr r5, [r2, #4]
  26.  60 ldr r6, =ATAG_CORE
  27.  61 cmp r5, r6
  28.  62 bne 1f
  29.  63
  30.  64 2: mov pc, lr @ atag/dtb pointer is ok
  31.  65
  32.  66 1: mov r2, #0
  33.  67 mov pc, lr
  34.  68 ENDPROC(__vet_atags)
发现注释里说r2可以是0,但代码里没有判断。
加上两句
cmp r2, #0
beq 1f
再运行,这地方就跑过去了 :)

  1. (XEN) 3... 2... 1...
  2. (XEN) *** Serial input -> DOM0 (type 'CTRL-a' three times to switch input to Xen)
  3. (XEN) Freed 264kB init memory.
  4. (XEN) DOM0: Uncompressing Linux... done, booting the kernel.
  5. (XEN) DOM0: <6>Initializing cgroup subsys cpu
  6. (XEN) DOM0: <5>Linux version 3.0.31-g3370a7c-dirty (uty@localhost.localdomain) (gcc version 4.6.x-google 20120106
  7. (XEN) DOM0: SMP PREEMPT Fri Dec 12 02:30:48 CST 2014
  8. (XEN) DOM0: CPU: ARMv7 Processor [410fc0f4] revision 4 (ARMv7), cr=10c5387d
  9. (XEN) DOM0: CPU: VIPT nonaliasing data cache, VIPT aliasing instruction cache
  10. (XEN) DOM0: Machine: ARNDALE
  11. (XEN) DOM0: <4>Default boot params at physical 0x40000100 out of reach
  12. (XEN) DOM0: <4>Ignoring unrecognised tag 0x00000000
  13. (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
  1. 1048 if ( is_pv32_domain(d) )
  2. 1049 {
  3. 1050     regs->cpsr = PSR_GUEST32_INIT;
  4. 1051
  5. 1052 /* FROM LINUX head.S
  6. 1053 *
  7. 1054 * Kernel startup entry point.
  8. 1055 * ---------------------------
  9. 1056 *
  10. 1057 * This is normally called from the decompressor code. The requirements
  11. 1058 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
  12. 1059 * r1 = machine nr, r2 = atags or dtb pointer.
  13. 1060 *...
  14. 1061 */
  15. 1062     regs->r0 = 0; /* SBZ */
  16. 1063     // uty: test
  17. 1064     //regs->r1 = 0xffffffff; /* We use DTB therefore no machine id */
  18. 1065     regs->r1 = 4272;
  19. 1066     //regs->r2 = kinfo.dtb_paddr;
  20. 1067     regs->r2 = 0;
  21. 1068 }

为了在head.S里输出调式信息,我在Makefile里加了AFLAGS_head.o += -DDEBUG,为了打开代码里的#ifdef DEBUG,不知道有没什么更正经的办法操作这个的?

arch/arm/boot/compressed/Makefile
  1. 18 AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
  2. 19 AFLAGS_head.o += -DDEBUG
  3. 20 HEAD = head.o
  4. 21 OBJS += misc.o decompress.o
  5. 22 FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c














阅读(1344) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~