[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
ELF64 patch
From: |
Ruslan Nikolaev |
Subject: |
ELF64 patch |
Date: |
Wed, 13 Jul 2005 18:19:56 -0500 |
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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- ELF64 patch,
Ruslan Nikolaev <=