Вот основная функция начальной загрузки
/* bootmain - the entry of bootloader */
void
bootmain(void) {
// read the 1st page off disk
readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0);
// is this a valid ELF?
if (ELFHDR->e_magic != ELF_MAGIC) {
goto bad;
}
struct proghdr *ph, *eph;
// load each program segment (ignores ph flags)
ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff);
eph = ph + ELFHDR->e_phnum;
for (; ph < eph; ph ++) {
readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset);
}
// call the entry point from the ELF header
// note: does not return
((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF))();
bad:
outw(0x8A00, 0x8A00);
outw(0x8A00, 0x8E00);
/* do nothing */
while (1);
}
Мне интересно, что означают последние директивы: 'outw (0x8A00, 0x8A00); outw (0x8A00, 0x8E00);'Как вы знаете, функция ядра никогда не вернется。 функция outw определена следующим образом, которая просто выполняет ввод-вывод с указанным портом.
static inline void
outw(uint16_t port, uint16_t data) {
asm volatile ("outw %0, %1" :: "a" (data), "d" (port));
}
Более того, мне интересно, почему каждый виртуальный адрес читается изELF должен быть логическим А с 0xFFFFFF, например. ph-> p_va & 0xFFFFFF. Что делать, если нет логики и операции?