getting to the kernel, 68k way
Someday I should write about the start of the 68k port, there is plenty to talk about… Today^Wnight^Wmornin erh, hmm well, now, I’ll try to do a live report on the issue I left you with last time: getting the kernel to load correctly.
I was at the point where it reads the 2 program segments into memory and start with digging symbols and relocation entries. I actually spent some time adding an hex dumper to elf.cpp to see if the loaded segments were correctly read, by diffing the debug output and the hexdump of the original binary. Well it seems I messed up the kernel linker script once again.
Here is the current kernel_m68k as per readelf -l:
Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x80000034 0x80000034 0x00080 0x00080 R 0x4 LOAD 0x000000 0x80000000 0x80000000 0xc62f2 0xc62f2 R E 0x2000 LOAD 0x0c7000 0x800c7000 0x800c7000 0x0628c 0x1267b RW 0x2000 DYNAMIC 0x0cd28c 0x800cd28c 0x800cd28c 0x000a0 0x000a0 RW 0x4
And the bootloader debug output:
elf_load_image(fd = 2, image = 0x000a0fe8) segment 1: start = 0x80000000, size = 815104, delta = 80000000 segment 2: start = 0x800c7000, size = 77824, delta = 7ff39000 load segment 1 (811762 bytes)... load segment 2 (25228 bytes)...
Then the dynamic section is searched for entries… at 0x800cd28c which is right after the end of the part read from file (the mem size is larger because it also comprises the BSS section that is initialized to 0). Let’s compare to an x86 kernel:
LOAD 0x000000 0x80000000 0x80000000 0xd4d69 0xd4d69 R E 0x1000 LOAD 0x0d5000 0x800d5000 0x800d5000 0x06480 0x1f6ad RW 0x1000 DYNAMIC 0x0db400 0x800db400 0x800db400 0x00080 0x00080 RW 0x4
The second (data) program segment overlaps the dynamic segment here (0xd5000+0x06480 = 0xdb480 = 0xdb400+0x80). Now I know why the .dynamic section had both :dynamic and :data segment qualifiers in linker script examples I read, it’s supposed to be both declared as a separate program header and part of the data segment! Let’s fix kernel.ld again:
LOAD 0x000000 0x80000000 0x80000000 0xc62f2 0xc62f2 R E 0x2000 LOAD 0x0c7000 0x800c7000 0x800c7000 0x0632c 0x1267b RW 0x2000 DYNAMIC 0x0cd28c 0x800cd28c 0x800cd28c 0x000a0 0x000a0 RW 0x4
Let’s ask bash just in case:
$ printf '%x %x\n' $((0xc7000+0x0632c)) $((0xcd28c+0x000a0)) cd32c cd32c
Great, it should work now, let’s try!
load kernel... elf_load_image(fd = 2, image = 0x000a0fe8) segment 1: start = 0x80000000, size = 815104, delta = 80000000 segment 2: start = 0x800c7000, size = 77824, delta = 7ff39000 load segment 1 (811762 bytes)... load segment 2 (25388 bytes)... loaded 4910 debug symbols elf_parse_dynamic_section: dyn 0x800cd28c elf_parse_dynamic_section: d[0].d_tag 1 elf_parse_dynamic_section: d[0].d_tag 1 elf_parse_dynamic_section: d[1].d_tag 4 elf_parse_dynamic_section: d[2].d_tag 5 elf_parse_dynamic_section: d[3].d_tag 6 elf_parse_dynamic_section: d[4].d_tag 10 elf_parse_dynamic_section: d[5].d_tag 11 elf_parse_dynamic_section: d[6].d_tag 21 elf_parse_dynamic_section: d[7].d_tag 3 elf_parse_dynamic_section: d[8].d_tag 2 elf_parse_dynamic_section: d[9].d_tag 20 elf_parse_dynamic_section: d[10].d_tag 23 elf_parse_dynamic_section: d[11].d_tag 7 elf_parse_dynamic_section: d[12].d_tag 8 elf_parse_dynamic_section: d[13].d_tag 9 total 72 plt-relocs (here some undisplayable chars... someone played nasty with debug output) total 15 rela relocs elf_load_image(directory = 0x01008be0, "ahci") elf_load_image(fd = 3, image = 0x8013a000) segment 0: start = 0x00000000, size = 36864, delta = 0 segment 1: start = 0x0000a000, size = 4096, delta = ffff6000 load segment 0 (32812 bytes)... load segment 1 (2344 bytes)... loaded 179 debug symbols elf_load_image(directory = 0x01008be0, "bfs") elf_load_image(fd = 3, image = 0x8013ba03) segment 0: start = 0x00000000, size = 167936, delta = 0 segment 1: start = 0x0002a000, size = 4096, delta = fffd6000 load segment 0 (164720 bytes)... load segment 1 (2972 bytes)... loaded 720 debug symbols elf_load_image(directory = 0x01008be0, "block_io") elf_load_image(fd = 3, image = 0x8013baa9) segment 0: start = 0x00000000, size = 12288, delta = 0 segment 1: start = 0x00004000, size = 4096, delta = ffffc000 load segment 0 (9088 bytes)... load segment 1 (560 bytes)... loaded 105 debug symbols elf_load_image(directory = 0x01008be0, "config_manager") elf_load_image(fd = 3, image = 0x8013c6aa) segment 0: start = 0x00000000, size = 4096, delta = 0 segment 1: start = 0x00002000, size = 4096, delta = ffffe000 load segment 0 (3112 bytes)... load segment 1 (400 bytes)... loaded 72 debug symbols elf_load_image(directory = 0x01008be0, "ehci") elf_load_image(fd = 3, image = 0x8013cf82) segment 0: start = 0x00000000, size = 65536, delta = 0 segment 1: start = 0x00011000, size = 8192, delta = fffef000 load segment 0 (65052 bytes)... load segment 1 (856 bytes)... loaded 342 debug symbols elf_load_image(directory = 0x01008be0, "generic_ide_pci") elf_load_image(fd = 3, image = 0x8019b67b) segment 0: start = 0x00000000, size = 4096, delta = 0 segment 1: start = 0x00002000, size = 4096, delta = ffffe000 load segment 0 (3040 bytes)... load segment 1 (464 bytes)... loaded 77 debug symbols elf_load_image(directory = 0x01008be0, "ide") elf_load_image(fd = 3, image = 0x8019bf2a) segment 0: start = 0x00000000, size = 32768, delta = 0 segment 1: start = 0x00009000, size = 4096, delta = ffff7000 load segment 0 (29320 bytes)... load segment 1 (976 bytes)... loaded 200 debug symbols elf_load_image(directory = 0x01008be0, "ide_adapter") elf_load_image(fd = 3, image = 0x801aa64c) segment 0: start = 0x00000000, size = 8192, delta = 0 segment 1: start = 0x00003000, size = 8192, delta = ffffd000 load segment 0 (7820 bytes)... load segment 1 (580 bytes)... loaded 94 debug symbols elf_load_image(directory = 0x01008be0, "intel") elf_load_image(fd = 3, image = 0x801ab1e5) segment 0: start = 0x00000000, size = 45056, delta = 0 segment 1: start = 0x0000c000, size = 4096, delta = ffff4000 load segment 0 (41680 bytes)... load segment 1 (1364 bytes)... loaded 259 debug symbols elf_load_image(directory = 0x01008be0, "it8211") elf_load_image(fd = 3, image = 0x801c0d85) segment 0: start = 0x00000000, size = 4096, delta = 0 segment 1: start = 0x00002000, size = 4096, delta = ffffe000 load segment 0 (2876 bytes)... load segment 1 (456 bytes)... loaded 76 debug symbols elf_load_image(directory = 0x01008be0, "legacy_sata") elf_load_image(fd = 3, image = 0x801c165f) segment 0: start = 0x00000000, size = 8192, delta = 0 segment 1: start = 0x00003000, size = 4096, delta = ffffd000 load segment 0 (4612 bytes)... load segment 1 (512 bytes)... loaded 81 debug symbols elf_load_image(directory = 0x01008be0, "locked_pool") elf_load_image(fd = 3, image = 0x801c1f57) segment 0: start = 0x00000000, size = 8192, delta = 0 segment 1: start = 0x00003000, size = 4096, delta = ffffd000 load segment 0 (4464 bytes)... load segment 1 (396 bytes)... loaded 82 debug symbols elf_load_image(directory = 0x01008be0, "ohci") elf_load_image(fd = 3, image = 0x801c2843) segment 0: start = 0x00000000, size = 69632, delta = 0 segment 1: start = 0x00012000, size = 4096, delta = fffee000 load segment 0 (66160 bytes)... load segment 1 (908 bytes)... loaded 345 debug symbols elf_load_image(directory = 0x01008be0, "pci") elf_load_image(fd = 3, image = 0x801e4802) segment 0: start = 0x00000000, size = 516096, delta = 0 segment 1: start = 0x0007f000, size = 237568, delta = fff81000 load segment 0 (516012 bytes)... load segment 1 (232436 bytes)... loaded 182 debug symbols elf_load_image(directory = 0x01008be0, "scsi") elf_load_image(fd = 3, image = 0x8029fc3c) segment 0: start = 0x00000000, size = 28672, delta = 0 segment 1: start = 0x00008000, size = 4096, delta = ffff8000 load segment 0 (26140 bytes)... load segment 1 (1216 bytes)... loaded 206 debug symbols elf_load_image(directory = 0x01008be0, "scsi_cd") elf_load_image(fd = 3, image = 0x802a155f) segment 0: start = 0x00000000, size = 8192, delta = 0 segment 1: start = 0x00003000, size = 4096, delta = ffffd000 load segment 0 (6448 bytes)... load segment 1 (436 bytes)... loaded 81 debug symbols elf_load_image(directory = 0x01008be0, "scsi_disk") elf_load_image(fd = 3, image = 0x802af54c) segment 0: start = 0x00000000, size = 8192, delta = 0 segment 1: start = 0x00003000, size = 4096, delta = ffffd000 load segment 0 (4244 bytes)... load segment 1 (440 bytes)... loaded 76 debug symbols elf_load_image(directory = 0x01008be0, "scsi_periph") elf_load_image(fd = 3, image = 0x802aff39) segment 0: start = 0x00000000, size = 16384, delta = 0 segment 1: start = 0x00005000, size = 8192, delta = ffffb000 load segment 0 (16320 bytes)... load segment 1 (648 bytes)... loaded 115 debug symbols elf_load_image(directory = 0x01008be0, "silicon_image_3112") elf_load_image(fd = 3, image = 0x802b0c75) segment 0: start = 0x00000000, size = 12288, delta = 0 segment 1: start = 0x00004000, size = 4096, delta = ffffc000 load segment 0 (8648 bytes)... load segment 1 (760 bytes)... loaded 95 debug symbols elf_load_image(directory = 0x01008be0, "uhci") elf_load_image(fd = 3, image = 0x802b173b) segment 0: start = 0x00000000, size = 69632, delta = 0 segment 1: start = 0x00012000, size = 4096, delta = fffee000 load segment 0 (68428 bytes)... load segment 1 (832 bytes)... loaded 357 debug symbols elf_load_image(directory = 0x01008be0, "usb") elf_load_image(fd = 3, image = 0x802b2e32) segment 0: start = 0x00000000, size = 57344, delta = 0 segment 1: start = 0x0000f000, size = 4096, delta = ffff1000 load segment 0 (53680 bytes)... load segment 1 (596 bytes)... loaded 319 debug symbols elf_load_image(directory = 0x01008be0, "usb_disk") elf_load_image(fd = 3, image = 0x802ec2ef) segment 0: start = 0x00000000, size = 12288, delta = 0 segment 1: start = 0x00004000, size = 4096, delta = ffffc000 load segment 0 (11448 bytes)... load segment 1 (584 bytes)... loaded 112 debug symbols elf_load_image(directory = 0x0100a018, "file_systems/bfs") kernel entry at 80034ffe
The last line is spit right before calling the kernel, and it just gets stuck there. But at least we loaded the kernel and all the modules \o/
Update
It seems I forgot to use -fno-pic for building arch_elf.cpp, which was the cause of the undisplayable characters in debug output, now the dprintfs get the correct pointers :)