Browse Source

Non-functioning x64 EFI loader (needs jump to protected)

K. Lange 2 years ago
parent
commit
ed020443d1
5 changed files with 41 additions and 14 deletions
  1. 13 6
      Makefile
  2. 6 2
      boot/cstuff.c
  3. 19 4
      boot/moremultiboot.h
  4. 2 1
      util/mkdisk.sh
  5. 1 1
      util/update-extents.py

+ 13 - 6
Makefile

@@ -190,18 +190,25 @@ image.iso: ${EFI_BOOT} cdrom/boot.sys fatbase/netinit ${MODULES} util/update-ext
 
 # Boot loader
 
-cdrom/fat.img: fatbase/ramdisk.img ${MODULES} fatbase/kernel fatbase/netinit fatbase/efi/boot/bootia32.efi util/mkdisk.sh
+cdrom/fat.img: fatbase/ramdisk.img ${MODULES} fatbase/kernel fatbase/netinit fatbase/efi/boot/bootia32.efi fatbase/efi/boot/bootx64.efi util/mkdisk.sh
 	util/mkdisk.sh $@ fatbase
 
-EFI_CFLAGS=-fno-stack-protector -fpic -DEFI_FUNCTION_WRAPPER -m32 -DEFI_PLATFORM -ffreestanding -fshort-wchar -I /usr/include/efi -I /usr/include/efi/ia32 -mno-red-zone
+EFI_CFLAGS=-fno-stack-protector -fpic -DEFI_PLATFORM -ffreestanding -fshort-wchar -I /usr/include/efi -mno-red-zone
 EFI_SECTIONS=-j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .reloc
 
 boot/efi.so: boot/cstuff.c boot/*.h
-	$(CC) ${EFI_CFLAGS} -c -o boot/efi.o $<
+	$(CC) ${EFI_CFLAGS} -I /usr/include/efi/ia32 -c -o boot/efi.o $<
 	$(LD) boot/efi.o /usr/lib32/crt0-efi-ia32.o -nostdlib -znocombreloc -T /usr/lib32/elf_ia32_efi.lds -shared -Bsymbolic -L /usr/lib32 -lefi -lgnuefi -o boot/efi.so
 
 fatbase/efi/boot/bootia32.efi: boot/efi.so
-	objcopy ${EFI_SECTIONS} --target=efi-app-ia32 boot/efi.so $@
+	objcopy ${EFI_SECTIONS} --target=efi-app-ia32 $< $@
+
+boot/efi64.so: boot/cstuff.c boot/*.h
+	gcc ${EFI_CFLAGS} -I /usr/include/efi/x86_64 -DEFI_FUNCTION_WRAPPER -c -o boot/efi64.o $<
+	$(LD) boot/efi64.o /usr/lib/crt0-efi-x86_64.o -nostdlib -znocombreloc -T /usr/lib/elf_x86_64_efi.lds -shared -Bsymbolic -L /usr/lib -lefi -lgnuefi -o boot/efi64.so
+
+fatbase/efi/boot/bootx64.efi: boot/efi64.so
+	objcopy ${EFI_SECTIONS} --target=efi-app-x86_64 $< $@
 
 cdrom/boot.sys: boot/boot.o boot/cstuff.o boot/link.ld | dirs
 	${KLD} -T boot/link.ld -o $@ boot/boot.o boot/cstuff.o
@@ -224,8 +231,8 @@ clean:
 	rm -f boot/*.o
 	rm -f boot/*.efi
 	rm -f boot/*.so
-	rm -f cdrom/fat.img cdrom/kernel cdrom/mod/* cdrom/efi/boot/bootia32.efi cdrom/ramdisk.img
-	rm -f fatbase/kernel fatbase/efi/boot/bootia32.efi
+	rm -f cdrom/fat.img cdrom/kernel cdrom/mod/* cdrom/ramdisk.img
+	rm -f fatbase/kernel fatbase/efi/boot/bootia32.efi fatbase/efi/boot/bootx64.efi
 	rm -f cdrom/netinit fatbase/netinit
 	rm -f ${KERNEL_OBJS} ${KERNEL_ASMOBJS} kernel/symbols.o kernel/symbols.S
 	rm -f base/lib/crt*.o

+ 6 - 2
boot/cstuff.c

@@ -20,9 +20,13 @@ EFI_HANDLE ImageHandleIn;
 
 /* Basic text strings */
 #ifdef EFI_PLATFORM
-#define VERSION_TEXT "ToaruOS-NIH Bootloader v1.3 (EFI, IA32)"
+#  if defined(__x86_64__)
+#    define VERSION_TEXT "ToaruOS-NIH Bootloader v1.3 (EFI, X64)"
+#  else
+#    define VERSION_TEXT "ToaruOS-NIH Bootloader v1.3 (EFI, IA32)"
+#  endif
 #else
-#define VERSION_TEXT "ToaruOS-NIH Bootloader v1.3 (BIOS)"
+#  define VERSION_TEXT "ToaruOS-NIH Bootloader v1.3 (BIOS)"
 #endif
 #define HELP_TEXT "Press <Enter> or select a menu option with \030/\031/\032/\033."
 #define COPYRIGHT_TEXT "ToaruOS is free software under the NCSA license."

+ 19 - 4
boot/moremultiboot.h

@@ -81,7 +81,7 @@ static void move_kernel(void) {
 			EFI_PHYSICAL_ADDRESS addr = phdr->p_vaddr;
 			uefi_call_wrapper(ST->BootServices->AllocatePages, 3, AllocateAddress, 0x80000000, phdr->p_memsz / 4096 + 1, &addr);
 #endif
-			memcpy((uint8_t*)phdr->p_vaddr, (uint8_t*)KERNEL_LOAD_START + phdr->p_offset, phdr->p_filesz);
+			memcpy((uint8_t*)(uintptr_t)phdr->p_vaddr, (uint8_t*)KERNEL_LOAD_START + phdr->p_offset, phdr->p_filesz);
 			long r = phdr->p_filesz;
 			while (r < phdr->p_memsz) {
 				*(char *)(phdr->p_vaddr + r) = 0;
@@ -210,13 +210,17 @@ static void move_kernel(void) {
 
 #ifdef EFI_PLATFORM
 	print_("\nExiting boot services and jumping to ");
-	print_hex_(entry);
+	print_hex_(_xmain);
 	print_(" with mboot_mag=");
 	print_hex_(_eax);
 	print_(" and mboot_ptr=");
 	print_hex_(_ebx);
 	print_("...\n");
 
+#if defined(__x86_64__)
+	print_("&_xmain = "); print_hex_(((uintptr_t)&_xmain) >> 32); print_hex_((uint32_t)(uintptr_t)&_xmain); print_("\n");
+#endif
+
 	if (1) {
 		EFI_STATUS e;
 		UINTN mapSize = 0, mapKey, descriptorSize;
@@ -231,11 +235,22 @@ static void move_kernel(void) {
 	}
 #endif
 
+#if defined(__x86_64__)
+	__asm__ __volatile__ (
+		".code32 \n"
+		"mov %1,%%eax \n"
+		"mov %2,%%ebx \n"
+		"jmp *%0 \n"
+		".code64 \n"
+		 : : "g"(_xmain), "g"(_eax), "g"(_ebx) : "eax", "ebx"
+		);
+#else
 	__asm__ __volatile__ (
 		"mov %1,%%eax \n"
 		"mov %2,%%ebx \n"
 		"jmp *%0" : : "g"(_xmain), "g"(_eax), "g"(_ebx) : "eax", "ebx"
 		);
+#endif
 }
 
 #ifndef EFI_PLATFORM
@@ -642,7 +657,7 @@ _try_module_again:
 					5, root, &file, name, EFI_FILE_MODE_READ, 0);
 			if (!EFI_ERROR(status)) {
 				status = uefi_call_wrapper(file->Read,
-						3, file, &bytes, (void *)(KERNEL_LOAD_START + offset));
+						3, file, &bytes, (void *)(KERNEL_LOAD_START + (uintptr_t)offset));
 				if (!EFI_ERROR(status)) {
 					print_("Loaded "); print_(*c); print_("\n");
 					modules_mboot[j].mod_start = KERNEL_LOAD_START + offset;
@@ -677,7 +692,7 @@ _try_module_again:
 				5, root, &file, name, EFI_FILE_MODE_READ, 0);
 		if (!EFI_ERROR(status)) {
 			status = uefi_call_wrapper(file->Read,
-					3, file, &bytes, (void *)(KERNEL_LOAD_START + offset));
+					3, file, &bytes, (void *)(KERNEL_LOAD_START + (uintptr_t)offset));
 			if (!EFI_ERROR(status)) {
 				print_("Loaded "); print_(c); print_("\n");
 				modules_mboot[multiboot_header.mods_count-1].mod_start = KERNEL_LOAD_START + offset;

+ 2 - 1
util/mkdisk.sh

@@ -28,5 +28,6 @@ do
     fi
 done
 
-rm cdrom/efi/boot/bootia32.efi # Otherwise virtualbox may erroneously try to load from this
+rm -f cdrom/efi/boot/bootia32.efi # Otherwise virtualbox may erroneously try to load from this
+rm -f cdrom/efi/boot/bootx64.efi # Same
 

+ 1 - 1
util/update-extents.py

@@ -294,7 +294,7 @@ def process(fatfile, path):
         #print path + fatfile.readable_name(), "is a file"
         cdfile = image.get_file(path + fatfile.readable_name())
         if not cdfile:
-            if fatfile.readable_name() != 'bootia32.efi':
+            if fatfile.readable_name() != 'bootia32.efi' and fatfile.readable_name() != 'bootx64.efi':
                 print "Warning:", fatfile.readable_name(), "not found in ISO"
         else:
             #print fatfile.get_offset() / 2048, fatfile.filesize