/* Все адреса (например, в jmp) правильные, код дизассембирован правильно (код и данные не перепутаны) */ /* Data */ 00 08 10 01 00 00 00 00 /* Linux kernel parameters */ /* 32 */ 59 pop %ecx /* Begin of "in" function */ 5a pop %edx 52 push %edx 51 push %ecx ec in (%dx),%al c3 ret /* End of "in" function */ /* Data */ 55 aa /* Linux kernel magic "0xaa55" */ /* 16 */ 0: eb 2e jmp 0x30 /* --+ Entry point */ /* Data */ 2: 48 64 72 53 /* | Linux kernel magic "HdrS" */ 6: 00 20 /* | Linux kernel parameters */ /* 32 */ 8: 59 pop %ecx /* | Begin of "out" function */ 9: 5a pop %edx /* | */ a: 58 pop %eax /* | */ b: 50 push %eax /* | */ c: 52 push %edx /* | */ d: 51 push %ecx /* | */ e: ee out %al,(%dx) /* | */ f: c3 ret /* | End of "out" function */ /* Data */ 10: 00 00 /* | */ 12: 00 80 6b 02 09 00 /* | GDT */ 18: 00 00 00 00 /* | Сюда загрузчик кладёт адрес на initial ramdisk/ramfs */ 1c: 00 00 00 00 00 00 00 00 /* | */ 24: 00 00 0c 00 /* | Адрес таблицы шрифта */ 28: 00 00 00 00 /* | */ 2c: ff ff ff 00 /* | Linux kernel parameters */ /* 16 */ 30: b8 01 4f mov $0x4f01,%ax /* <-+ ? */ 33: b9 05 41 mov $0x4105,%cx /* ? */ 36: 50 push %ax /* ? */ 37: 51 push %cx /* ? */ 38: bf 00 10 mov $0x1000,%di /* ? */ 3b: 8e c7 mov %di,%es /* ? */ 3d: cd 10 int $0x10 /* Прерывание для графики */ 3f: 5b pop %bx /* ? */ 40: 58 pop %ax /* ? */ 41: 40 inc %ax /* ? */ 42: cd 10 int $0x10 /* ? */ 44: b8 30 11 mov $0x1130,%ax /* ? */ 47: b7 06 mov $0x6,%bh /* ? */ 49: cd 10 int $0x10 /* ? */ 4b: 2e 89 2e 24 00 mov %bp,%cs:0x24 /* ? */ 50: fa cli /* 1 "The x86 is bootstrapped into 32bit mode in 6 instructions" - Gavin Barraclough */ 51: 2e 0f 01 1e 6b 00 lidtw %cs:0x6b /* 2 Loading IDT (see below) */ 57: 2e 0f 01 16 12 00 lgdtw %cs:0x12 /* 3 Loading GDT (see above) */ 5d: b8 01 00 mov $0x1,%ax /* 4 */ 60: 0f 01 f0 lmsw %ax /* 5 */ 63: 66 ea c3 02 09 00 08 ljmpl $0x8,$0x902c3 /* --+ 6 */ /* Data */ 6a: 00 /* */ 6b: 00 00 00 00 00 00 00 00 /* | IDT */ 73: ff ff 00 00 00 9a cf 00 /* | IDT */ 7b: ff ff 00 00 00 92 cf 00 /* | IDT */ 83: 20 20 31 32 33 /* | Begin of keyboard layout */ 88: 34 35 36 37 38 39 30 2d /* | */ 90: 3d 20 20 71 77 65 72 74 /* | */ 98: 79 75 69 6f 70 5b 5d 0a /* | */ a0: 20 61 73 64 66 67 68 6a /* | */ a8: 6b 6c 3b 20 20 20 20 7a /* | */ b0: 78 63 76 62 6e 6d 2c 2e /* | */ b8: 20 20 20 20 20 20 20 20 /* | */ c0: 20 20 20 /* | End of keyboard layout */ /* 32 */ c3: 66 b8 10 00 mov $0x10,%ax /* <-+ ? */ c7: 8e d8 mov %eax,%ds /* ? */ c9: 8e d0 mov %eax,%ss /* ? */ cb: bc f0 01 09 00 mov $0x901f0,%esp /* ? */ objdump -D -z -b binary -m i386 Raw hex: 0008100100000000595a5251ecc355aa eb2e486472530020595a58505251eec3 000000806b0209000000000000000000 0000000000000c0000000000ffffff00 b8014fb905415051bf00108ec7cd105b 5840cd10b83011b706cd102e892e2400 fa2e0f011e6b002e0f01161200b80100 0f01f066eac302090008000000000000 000000ffff0000009acf00ffff000000 92cf002020313233343536373839302d 3d202071776572747975696f705b5d0a 206173646667686a6b6c3b202020207a 786376626e6d2c2e2020202020202020 20202066b810008ed88ed0bcf0010900 Карта памяти ------------ * У всех интервалов левая граница дана включительно, а правая - нет * "OK" означает, что интервал можно использовать по своему усмотрению * Тест производился так: в память писалась информация. Если ничего не упало - то всё OK. Не проверялась возможность чтения из памяти. Все проверки проходили только в user space. Таким образом, с точки зрения ядра это могут быть другие адреса. Единственный "хороший" интервал памяти, о котором я уверен, что он читабелен/писабелен и одинаково виден из ядра и user space - это 0x100000 - 0x8000000 * Хорошо бы ещё раз провести "контрольную проверку" окейности областей, помеченных OK * Возможно, ещё какая-то из окейных областей является куском видеопамяти * 0 - 1 1028 OK * 1 1028 - 1 102c OK, адрес видеопамяти, он переписывается в начале работы * 1 102c - 9 0000 OK * 9 0000 - 9 1200 Kernel * 9 0000 - 0 01f0 Kernel variables * 9 01f0 - 9 02d0 huge_string, часть ядра, написанная на ассемблере (содержит не только код, но и данные). Код выполняется только один раз при старте, так что его можно перезаписывать. Но нельзя трогать данные, которые могут понадобиться * 9 01f0 - 9 01f8 OK * 9 01f8 - 9 01fe "in" function * 9 01fe - 9 0200 OK * 9 0200 _hard_kernel_image, в gavin.hint написано: "0x90200 is the address at which a Linux bootloader loads an x86 kernel image", хотя на самом деле начало образа ядра находится раньше * 9 0200 - 9 0208 OK * 9 0208 Здесь начинается функция "out". Я не знаю, где она заканчивается (скорее всего, не позже, чем через 8 байт), но это не важно, так как она не используется после начала работы soft_main, и поэтому её можно переписывать * 9 0208 - 9 0218 OK * 9 0218 - 9 021c OK, сюда загрузчик кладёт адрес на initial ramdisk/ramfs. Ramdisk распаковывается в начале работы, так что адрес не нужен * 9 021c - 9 0224 OK * 9 0224 - 9 0228 OK, адрес таблицы шрифта, он переписывается в начале работы * 9 0228 - 9 0283 OK * 9 0283 - 9 02c3 Keyboard layout * 9 02c3 - 9 02d0 OK * 9 02d0 - 9 1200 Код ядра на си * 9 1200 - 10 0000 Где-то здесь могут находиться таблица шрифта и куски видеопамяти, в остальном OK * 10 0000 - 800 0000 OK * 800 0000 - ffff ffff Дальше мне лень проверять, но там много подводных камней. Также граница ffff ffff указана включительно