Hi all! I'm developing free x86_64 (amd64) operation system now. I decided to make the kernel multiboot-complient and use grub2 as a boot loader. Of course I have some problems: 1. AMD64 processor require to enable paging and to fill page tables before entering long mode (64-bit mode). In that case bootloader should leave processor in 32-bit protected mode. All switching to 64-bit mode should be done by the kernel. => we can use usual i386 boot loader 2. It's better to have kernel and modules as ELF64 executables for amd64. The patch below adds ELF64 support for multiboot (grub2): patch for file grub2/loader/i386/pc/multiboot.c: ----------------------------------------------- diff -urN old/multiboot.c new/multiboot.c --- old/multiboot.c Wed Jul 6 04:25:16 2005 +++ new/multiboot.c Fri Jul 8 02:38:12 2005 @@ -81,6 +81,45 @@ return GRUB_ERR_NONE; } +/* the following routine allows to load x86_64 ELF */ +static void +x86_elf64to32(char *buffer) +{ + register int i; + union + { + Elf32_Ehdr *addr32; + Elf64_Ehdr *addr64; + } ehdr; + union + { + Elf32_Phdr *addr32; + Elf64_Phdr *addr64; + } phdr; + + /* convert header */ + ehdr.addr64 = (Elf64_Ehdr *)buffer; + ehdr.addr32->e_entry = ehdr.addr64->e_entry; + ehdr.addr32->e_phoff = ehdr.addr64->e_phoff; + ehdr.addr32->e_shoff = ehdr.addr64->e_shoff; + memcpy(&ehdr.addr32->e_flags, &ehdr.addr64->e_flags, 16); + + /* convert program header table */ + for (i = 0; i < ehdr.addr32->e_phnum; i++) + { + register Elf32_Word flags; + phdr.addr64 = (Elf64_Phdr *)(buffer + ehdr.addr32->e_phoff + i * ehdr.addr32- >e_phentsize); + flags = phdr.addr64->p_flags; + phdr.addr32->p_offset = phdr.addr64->p_offset; + phdr.addr32->p_vaddr = phdr.addr64->p_vaddr; + phdr.addr32->p_paddr = phdr.addr64->p_paddr; + phdr.addr32->p_filesz = phdr.addr64->p_filesz; + phdr.addr32->p_memsz = phdr.addr64->p_memsz; + phdr.addr32->p_align = phdr.addr64->p_align; + phdr.addr32->p_flags = flags; + } +} + void grub_rescue_cmd_multiboot (int argc, char *argv[]) { @@ -140,8 +179,20 @@ ehdr = (Elf32_Ehdr *) buffer; - if (grub_dl_check_header (ehdr, sizeof(*ehdr))) + /* convert ELF64 for x86_64 to ELF32 for i386 */ + if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) + { + ehdr->e_ident[EI_CLASS] = ELFCLASS32; + if (ehdr->e_machine == EM_X86_64) + ehdr->e_machine = EM_386; + if (grub_dl_check_header(ehdr, sizeof(*ehdr))) + goto bad_header; + x86_elf64to32(buffer); + } + /* usual ELF32 for i386 */ + else if (grub_dl_check_header (ehdr, sizeof(*ehdr))) { + bad_header: grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found"); goto fail; } -------------- Best regards, Ruslan Nikolaev
-- ___________________________________________________________ Sign-up for Ads Free at Mail.com http://promo.mail.com/adsfreejump.htm _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel