Messages in this thread Patch in this message | | | Date | Sat, 27 Feb 2010 16:06:45 +1100 | From | Graeme Russ <> | Subject | Re: x86 embedded - Problem getting past 'move compressed kernel before decompression' |
| |
Graeme Russ wrote: > On Sun, Feb 21, 2010 at 4:53 PM, H. Peter Anvin <hpa@zytor.com> wrote: >> On 02/20/2010 09:45 PM, H. Peter Anvin wrote: >> > Thanks Peter - I gave that a try but no luck. I am in the process of > writing some routines which will dump the contents of the registers > upon entering startup_32 and the relocation jump address prior to > the jump. > > My assembler is a bit rusty, so it is taking a bit of time >
Sorry for the delay - been very busy lately.
I borrowed __show_regs() from process_32.c and implemented crash dump and break dump handlers in u-boot. So now I can int3 and dump all registers.
To give some context to what I am doing in u-boot:
#define DECLARE_INTERRUPT(x) \ ".globl irq_"#x"\n" \ ".hidden irq_"#x"\n" \ ".type irq_"#x", @function\n" \ "irq_"#x":\n" \ "pushl $"#x"\n" \ "jmp irq_common_entry\n"
asm(".globl irq_common_entry\n" \ ".hidden irq_common_entry\n" \ ".type irq_common_entry, @function\n" \ "irq_common_entry:\n" \ "cld\n" \ "pushl %gs\n" \ "pushl %fs\n" \ "pushl %es\n" \ "pushl %ds\n" \ "pushl %eax\n" \ "pushl %ebp\n" \ "pushl %edi\n" \ "pushl %esi\n" \ "pushl %edx\n" \ "pushl %ecx\n" \ "pushl %ebx\n" \ "mov %esp, %eax\n" \ "pushl %ebp\n" \ "movl %esp,%ebp\n" \ "pushl %eax\n" \ "call irq_llsr\n" \ "popl %eax\n" \ "leave\n"\ "popl %ebx\n" \ "popl %ecx\n" \ "popl %edx\n" \ "popl %esi\n" \ "popl %edi\n" \ "popl %ebp\n" \ "popl %eax\n" \ "popl %ds\n" \ "popl %es\n" \ "popl %fs\n" \ "popl %gs\n" \ "add $4, %esp\n" \ "iret\n" \ DECLARE_INTERRUPT(0) \ DECLARE_INTERRUPT(1) \ DECLARE_INTERRUPT(2) \ . . . DECLARE_INTERRUPT(255)
/* IRQ Low-Level Service Routine */ __isr__ irq_llsr(struct pt_regs *regs) { switch (regs->orig_eax) { case 0x00: printf("Divide Error (Division by zero)\n"); dump_regs(regs); while(1); break; case 0x01: printf("Debug Interrupt (Single step)\n"); dump_regs(regs); break; case 0x02: printf("NMI Interrupt\n"); dump_regs(regs); break; case 0x03: printf("Breakpoint\n"); dump_regs(regs); break; etc }
dump_regs() is pretty much the same as __show_regs() in process_32.c
I've pulled the latest 6.2.33 kernel source and applied the following patch to trace progress through the 32-bit Boot Protocol:
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index f543b70..3535470 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -32,6 +32,7 @@
__HEAD ENTRY(startup_32) + int3 cld /* * Test KEEP_SEGMENTS flag to see if the bootloader is asking @@ -93,12 +94,14 @@ ENTRY(startup_32) * Copy the compressed kernel to the end of our buffer * where decompression in place becomes safe. */ + int3 pushl %esi leal (_bss-4)(%ebp), %esi leal (_bss-4)(%ebx), %edi movl $(_bss - startup_32), %ecx shrl $2, %ecx std + int3 rep movsl cld popl %esi @@ -106,12 +109,15 @@ ENTRY(startup_32) /* * Jump to the relocated address. */ + int3 leal relocated(%ebx), %eax + int3 jmp *%eax ENDPROC(startup_32)
.text relocated: + int3
/* * Clear BSS (stack is currently empty) and in u-boot, to boot the kernel, I have:
struct boot_params boot_params __attribute__((aligned(16))); struct setup_header *hdr = (struct setup_header *)(0x90000 + 0x1f1); void boot_zimage(void *setup_base) { printf("&boot_params = 0x%8.8lx\n", (ulong)&boot_params); printf("sizeof (*hdr) = 0x%8.8lx\n", (ulong)(sizeof (*hdr))); memset(&boot_params, 0x00, sizeof boot_params); memcpy(&boot_params.hdr, hdr, sizeof (*hdr));
boot_params.alt_mem_k = 128 * 1024; boot_params.e820_entries = 1; boot_params.e820_map[0].addr = 0x00000000; boot_params.e820_map[0].size = 128 * 1024; boot_params.e820_map[0].type = 1; printf("Entering Linux\n");
asm volatile( "movl %2, %%ds\n" \ "movl %2, %%es\n" \ "movl %2, %%fs\n" \ "movl %2, %%gs\n" \ "movl %2, %%ss\n" \ "xorl %%ebp, %%ebp\n" \ "xorl %%ebx, %%ebx\n" \ "int3\n" \ "ljmpl $0x10,$0x100000" : : "S" (&boot_params), "D" (0), "r" (0x18)); }
The result is:
&boot_params = 0x03ffb350 sizeof (*hdr) = 0x00000067 Entering Linux Breakpoint EIP: 0010:[<03fe3e0b>] EFLAGS: 00000046 EAX: 00000018 EBX: 00000000 ECX: 000003f8 EDX: 000003f8 ESI: 03ffb350 EDI: 00000000 EBP: 00000000 ESP: 03ff42f3 DS: 0018 ES: 0018 FS: 0018 GS: 0018 SS: 01f1 CR0: 00000033 CR2: 00000000 CR3: 00000000 CR4: 00080099 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Breakpoint EIP: 0010:[<00100001>] EFLAGS: 00000046 EAX: 00000018 EBX: 00000000 ECX: 000003f8 EDX: 000003f8 ESI: 03ffb350 EDI: 00000000 EBP: 00000000 ESP: 03ff42f3 DS: 0018 ES: 0018 FS: 0018 GS: 0018 SS: 01f1 CR0: 00000033 CR2: 00000000 CR3: 00000000 CR4: 00080099 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Breakpoint EIP: 0010:[<00100042>] EFLAGS: 00000002 EAX: 00000018 EBX: 00377000 ECX: 000003f8 EDX: 000003f8 ESI: 03ffb350 EDI: 00000000 EBP: 00100000 ESP: 00000000 DS: 0018 ES: 0018 FS: 0018 GS: 0018 SS: 0000 CR0: 00000033 CR2: 00000000 CR3: 00000000 CR4: 00080099 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Breakpoint EIP: 0010:[<00100059>] EFLAGS: 00000416 EAX: 00000018 EBX: 00377000 ECX: 00070828 EDX: 000003f8 ESI: 002c209c EDI: 0053909c EBP: 00100000 ESP: 03ffb350 DS: 0018 ES: 0018 FS: 0018 GS: 0018 SS: 0000 CR0: 00000033 CR2: 00000000 CR3: 00000000 CR4: 00080099 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Breakpoint EIP: 0010:[<0010005e>] EFLAGS: 00000016 EAX: 00000018 EBX: 00377000 ECX: 00000000 EDX: 000003f8 ESI: 03ffb350 EDI: 00376ffc EBP: 00100000 ESP: 00000000 DS: 0018 ES: 0018 FS: 0018 GS: 0018 SS: 0000 CR0: 00000033 CR2: 00000000 CR3: 00000000 CR4: 00080099 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Breakpoint EIP: 0010:[<00100065>] EFLAGS: 00000016 EAX: 005379c4 EBX: 00377000 ECX: 00000000 EDX: 000003f8 ESI: 03ffb350 EDI: 00376ffc EBP: 00100000 ESP: 00000000 DS: 0018 ES: 0018 FS: 0018 GS: 0018 SS: 0000 CR0: 00000033 CR2: 00000000 CR3: 00000000 CR4: 00080099 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Invalid Opcode (UnDefined Opcode) EIP: 0010:[<dd013ea8>] EFLAGS: 00010016 EAX: 005379c4 EBX: 00377000 ECX: 00000000 EDX: 873d0328 ESI: 03ffb350 EDI: 00376ffc EBP: 00100000 ESP: 00000018 DS: 0018 ES: 0018 FS: 0018 GS: 0018 SS: 0000 CR0: 00000033 CR2: 00000000 CR3: 00000000 CR4: 00080099 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 I don't understand what is going on with SS and ESP, but everything else is looking good up until: jmp *%eax
At which point, eax appears to hold a reasonably value. But:
boot > md 5379c4 005379c4: c11c0e7f b0c2ea61 2d43c068 f02e6fa0 ....a...h.C-.o.. 005379d4: 3d0328ba 76651e87 c4c6e98e 26fddcad .(.=..ev.......& 005379e4: 1983b874 c9edece7 793c2ce4 a8de5f50 t........,<yP_.. 005379f4: a29afa5b e7b42f13 c4233d0a bc6e8424 [..../...=#.$.n. 00537a04: cb90001b dcea7bb4 969601e8 707fbe4a .....{......J..p 00537a14: dfead2ec b8e62d5b fd7d2b53 b8ad16ef ....[-..S+}..... 00537a24: e0252df2 28044367 9c80c800 beec457e .-%.gC.(....~E.. 00537a34: 22d27b84 4f32a8cc 9d1eb9b3 aac36b6a .{."..2O....jk.. 00537a44: f7f79e53 54af3ec6 f32eebe6 5a89fe1d S....>.T.......Z 00537a54: 3e3aadfa 63e0b27f 5086cadd b438532e ..:>...c...P.S8. 00537a64: 0a4daef6 f68fb9fc b525a3f1 c0cd58e7 ..M.......%..X.. 00537a74: 3f727ad6 061e1199 793d150a 5fd8a267 .zr?......=yg.._ 00537a84: fca2d658 4f1e392c dbdd62d3 4fed04dd X...,9.O.b.....O 00537a94: 07caba83 1274f371 e18ef1f5 e1c32aef ....q.t......*.. 00537aa4: 964ff812 f214be9d a59e8b2c 281d0dd6 ..O.....,......( 00537ab4: 0d5a95fc 818d59e7 11d33442 73b99e6b ..Z..Y..B4..k..s (Note: each of the above longs is in reverse byte order, so 0x005379c4 is actually 0x7f
I would have expected a 0xcc at 0x005379c4.
From u-boot, if I jump straight to 0x005379c4 I get pretty much the same crash. So it looks like a problem with the calculation of the copy source or target address, or the calculation of the relocated jump address.
Any ideas?
Regards
Graeme
| |