arm なカーネルの DeviceTree を確認すべく (4)
gdb できそげなのが分かったので無理やり。
$ sudo qemu-system-arm -S -gdb tcp::1234 -M vexpress-a9 -kernel /opt/kernel/zImage \ -append "root=/dev/nfs rw nfsroot=10.0.2.2:/opt/export/filesystem.dir ip=dhcp"
で、別端末にて
$ ./arm-none-linux-gnueabi-gdb vmlinuz
で何とかなっている模様。
list 確認してたら以下なソレが出てきたので
58 /* 59 * Kernel startup entry point. 60 * --------------------------- (gdb) l 61 * 62 * This is normally called from the decompressor code. The requirements 63 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, 64 * r1 = machine nr, r2 = atags or dtb pointer. 65 * 66 * This code is mostly position independent, so if you link the kernel at 67 * 0xc0008000, you call this at __pa(0xc0008000). 68 * 69 * See linux/arch/arm/tools/mach-types for the complete list of machine 70 * numbers for r1. (gdb) l 71 * 72 * We're trying to keep crap to a minimum; DO NOT add any machine specific 73 * crap here - that's what the boot loader (or in extreme, well justified 74 * circumstances, zImage) is for. 75 */ 76 .arm 77 78 __HEAD 79 ENTRY(stext)
とりあえず b 79 して、continue か。
あ、先にこっちらしい。
(gdb) target remote localhost:1234 Remote debugging using localhost:1234 0x60000000 in ?? () (gdb)
む、不用意に c して行ってらっしゃい状態になったなorz
リトライ
むむ、ちょい諸々確認します。ええと、_setup_machine_fdt() in arch/arm/kernel/devicetree.c_ を呼び出すのが、_setup_arch() in arch/arm/kernel/setup.c_ とのことなので、以下?
(gdb) b setup_arch Breakpoint 4 at 0x8036acd8: file arch/arm/kernel/setup.c, line 737. (gdb)
を、張れた。すばら。continue してみる。当り前ですが止まる。
(gdb) c Continuing. Breakpoint 4, setup_arch (cmdline_p=0x80391fdc) at arch/arm/kernel/setup.c:737 737 setup_processor(); (gdb)
ええと、問題の手続き呼び出しは次の行です。
(gdb) l 732 733 void __init setup_arch(char **cmdline_p) 734 { 735 struct machine_desc *mdesc; 736 737 setup_processor(); 738 mdesc = setup_machine_fdt(__atags_pointer); 739 if (!mdesc) 740 mdesc = setup_machine_tags(__atags_pointer, machine_arch_type); 741 machine_desc = mdesc; (gdb)
ので、n して s か。
(gdb) n 738 mdesc = setup_machine_fdt(__atags_pointer); (gdb) s 737 setup_processor(); (gdb) n 738 mdesc = setup_machine_fdt(__atags_pointer); (gdb) si 0x8036af26 738 mdesc = setup_machine_fdt(__atags_pointer); (gdb) s setup_machine_fdt (dt_phys=1610612992) at arch/arm/kernel/devtree.c:79 79 if (!dt_phys) (gdb)
自分でも何してるか微妙ですが setup_machine_fdt の中には入れたな。
とりあえず時間も無いので (いま 0550)、return 直前で止めて云々してみます。
(gdb) l 124 of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); 125 /* Initialize {size,address}-cells info */ 126 of_scan_flat_dt(early_init_dt_scan_root, NULL); 127 /* Setup memory, calling early_init_dt_add_memory_arch */ 128 of_scan_flat_dt(early_init_dt_scan_memory, NULL); 129 130 /* Change machine number to match the mdesc we're using */ 131 __machine_arch_type = mdesc_best->nr; 132 133 return mdesc_best; (gdb) b 133 Breakpoint 5 at 0x8036b7fc: file arch/arm/kernel/devtree.c, line 133. (gdb) c Continuing.
あら、戻ってこないorz
上見てみるにこんな行があるな。
if (!mdesc_best) { const char *prop; long size; early_print("\nError: unrecognized/unsupported " "device tree compatible list:\n[ "); prop = of_get_flat_dt_prop(dt_root, "compatible", &size); while (size > 0) { early_print("'%s' ", prop); size -= strlen(prop) + 1; prop += strlen(prop) + 1; } early_print("]\n\n"); dump_machine_table(); /* does not return */ }
ここ通過してるのかどうか。
ちょっとだけリトライ
ここでも駄目。
98 if (!mdesc_best) { 99 const char *prop; 100 long size; 101 102 early_print("\nError: unrecognized/unsupported " 103 "device tree compatible list:\n[ "); (gdb) b 98 Breakpoint 2 at 0x8036b770: file arch/arm/kernel/devtree.c, line 98. (gdb) c Continuing.
continue しちゃ駄目なのかな。それともここ以前の分岐で戻ってるのか。つうか、変数の値を検査してるんですが、色々と挙動が微妙だな。このあたり含め、現実トウヒなナニで諸々確認の方向ということにて。