Page 1 of 1

UEFI Not booting kernel.

Posted: Sun Dec 02, 2012 12:25 pm
by zhiayang
I have been going at this for a long time... Let me share my agony.
requimrar wrote: -- Insert agonising complaints and whining --
18. KERNEL LOADER DOES NOT BOOT...!


TL;DR: UEFI does not boot my kernel.
Here it is:

Code: Select all

#include <efi.h>
#include <efilib.h>

EFI_STATUS _start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
	SystemTable->ConOut->OutputString(SystemTable->ConOut, (CHAR16*)L"Hello World\n\r");

	asm volatile("cli; hlt");

	return EFI_SUCCESS;
}
I don't get any compile or linking errors on this, so I assume it's all defined properly.

Build process:

Code: Select all


EFICCFLAGS  = -w -m64 -O0 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -std=gnu11 -fstrength-reduce -fno-leading-underscore -fno-stack-protector -fomit-frame-pointer -finline-functions -ffreestanding -nostdlib -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -Isrc/kernel/include -Isrc/ares/efi/efi/include -c


        @$(CC) $(EFICCFLAGS) -o obj/efi/ares.o src/ares/efi/ares.c


	@$(AS) --64 src/ares/efi/efi/x86_64/efi_stub.S -o obj/efi/efi_stub.o


	@$(CC) $(EFICCFLAGS) -o obj/efi/boxdraw.o src/ares/efi/efi/boxdraw.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/console.o src/ares/efi/efi/console.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/crc.o src/ares/efi/efi/crc.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/data.o src/ares/efi/efi/data.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/debug.o src/ares/efi/efi/debug.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/dpath.o src/ares/efi/efi/dpath.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/error.o src/ares/efi/efi/error.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/event.o src/ares/efi/efi/event.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/guid.o src/ares/efi/efi/guid.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/hand.o src/ares/efi/efi/hand.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/hw.o src/ares/efi/efi/hw.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/init.o src/ares/efi/efi/init.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/lock.o src/ares/efi/efi/lock.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/misc.o src/ares/efi/efi/misc.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/print.o src/ares/efi/efi/print.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/smbios.o src/ares/efi/efi/smbios.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/sread.o src/ares/efi/efi/sread.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/str.o src/ares/efi/efi/str.c


	@$(CC) $(EFICCFLAGS) -o obj/efi/efirtlib.o src/ares/efi/efi/runtime/efirtlib.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/rtdata.o src/ares/efi/efi/runtime/rtdata.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/rtlock.o src/ares/efi/efi/runtime/rtlock.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/rtstr.o src/ares/efi/efi/runtime/rtstr.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/vm.o src/ares/efi/efi/runtime/vm.c


	@$(CC) $(EFICCFLAGS) -o obj/efi/callwrap.o src/ares/efi/efi/x86_64/callwrap.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/initplat.o src/ares/efi/efi/x86_64/initplat.c
	@$(CC) $(EFICCFLAGS) -o obj/efi/math.o src/ares/efi/efi/x86_64/math.c



	@$(LD) -o output/Ares.efi $(wildcard obj/efi/*.o)


	@$(EFI_OBJCOPY) -O pe-x86-64 output/ares.efi output/bootx64.efi

	@$(QEMU) -L output/qemu -bios OVMF.fd -m 786 -vga cirrus -hda output/efi.img


What is this?
Wrong flags? Wrong address...?


EDIT: I should probably say I have an image, with a FAT32 32MB partition, and a ~1GB data partition as HFS+ (Didn't format that)
the EFI firmware detects the disk, but it doesn't boot from it automatically (or fails to).

When I go to 'boot from file' and select my bootx64.efi, the screen flashes black, then I get sent back to the menu screen.

Am I doing anything wrong...?

Help, thanks!



EDIT 2: For the purposes of help, here are the relevant files:

1. bootx64.efi, HERE
Thanks for your time.

Re: UEFI Not booting kernel.

Posted: Mon Dec 03, 2012 11:31 am
by blm768
When using GNU-EFI, there's some sort of call wrapper you need to use to simulate the UEFI calling convention. I can't remember what it is, but I'll edit this post when I have a chance to look it up.

Edit: Looks like I've been beaten to it.

Re: UEFI Not booting kernel.

Posted: Mon Dec 03, 2012 11:38 am
by Griwes
It is (how surprisingly) called `uefi_call_wrapper` - http://wiki.osdev.org/UEFI#Example_in_C.

By the way, getting (relatively) sanier OS for development, instead of one created only with computer newbies in mind, would be a good idea :)

Re: UEFI Not booting kernel.

Posted: Tue Dec 04, 2012 12:18 am
by zhiayang
Griwes wrote:It is (how surprisingly) called `uefi_call_wrapper` - http://wiki.osdev.org/UEFI#Example_in_C.
Mhmm. I did try that, but I was still not able to make it work. Even a simple

Code: Select all

asm volatile("cli; hlt");
return EFI_SUCCESS;
Doesn't work. I have a strong suspicion that it's something with how my file is built, but I'm sure it's all according to spec...
Griwes wrote:By the way, getting (relatively) sanier OS for development, instead of one created only with computer newbies in mind, would be a good idea :)
No. I like it the way it is. Linux doesn't have the apps I want, and it's too slow and inconvenient to do work in a VM. No flame wars, please.

Re: UEFI Not booting kernel.

Posted: Tue Dec 04, 2012 3:29 am
by feryno
could you post your binary of the kernel file?

Re: UEFI Not booting kernel.

Posted: Tue Dec 04, 2012 8:39 am
by zhiayang
feryno wrote:could you post your binary of the kernel file?
Will do. Should be linked in OP.

Re: UEFI Not booting kernel.

Posted: Thu Dec 06, 2012 1:09 am
by feryno
you guessed it correctly, there is something wrong in the header of the file
I found these 2 problems in your bootx64.efi file

[0]
offset: 0DCh
your value: 03h
should be: 0Bh = EFIBOOT (0Ah = EFI, 0Ch = EFIRUNTIME)

[1]
offset: 96h
your value: word 0227h
problem found: IMAGE_FILE_DLL=2000h flag is missing
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
see IMAGE_FILE_HEADER.Characteristics

editing these 2 problems in the header didn't help yet which means another flags/fields in the header have to be changed
I'll try to find it later
maybe this article can help a bit:
http://x86asm.net/articles/uefi-program ... index.html
we were discussing problems in header here but the forum is not related to the programming language of your program:
http://board.flatassembler.net/topic.php?p=144747

Re: UEFI Not booting kernel.

Posted: Thu Dec 06, 2012 2:05 am
by zhiayang
feryno wrote: [0]
offset: 0DCh
your value: 03h
should be: 0Bh = EFIBOOT (0Ah = EFI, 0Ch = EFIRUNTIME)
um... I don't know where those values are from... But at offset 0xDC, the DWORD is 0000 0000....
feryno wrote: [1]
offset: 96h
your value: word 0227h
problem found: IMAGE_FILE_DLL=2000h flag is missing
What... What is this microsoft coff bullshit...?!?!
Also: The WORD at 0x96 is 0000...


I'll try other things in the meantime, and also read on the material you suggested (I really... don't want to get involved with microsoft **** right now... Including the un-buildable EDKII, because, ironically, a lack of a 'build' command)

Thanks for your time, feryno.

Re: UEFI Not booting kernel.

Posted: Fri Dec 07, 2012 7:37 pm
by zhiayang
I've been trying many things recently, however none have come to fruition.

1. I've compiled an *old* version of binutils (2.19, I think), that still had the efi-app-x86_64 target. Few problems:
  • - x86_64-efi-objcopy can take an ELF file and output an EFI file, but no other utilities (including objdump) can read them anymore.
    - Same applies with linking directly to a efi-app-x86_64 OUTPUT_FORMAT with LD.

    - And of course, still no results with getting EFI to execute my file.



2. I kinda 'gave up' and tried resorting to GRUB 2.
So, after wasting quite some time mucking about (including about 5 minutes of 'WAI NO MB HEADER', when I was using the multiboot command instead of the multiboot2 one), I finally managed to get GRUB2 to compile (in a bloody VM, no less)

Of course, nothing goes right... GRUB itself loads fine, however...
  • - Upon loading my kernel (without using 'boot' yet), grub 'WARN: No console will be available to OS'... Perhaps as a forewarning as to the following predicament.

    - When I do use 'boot', I get some kind of video corruption; what appears to be miniature versions of the grub screen I was just at, appear to be tiled on the screen.
    - QEMU freezes. I get a bunch of garbage on SerialOut.
    - It appears my application doesn't even get loaded... I have routines to output to SerialOut, but I can't find the string I output...


So, a bunch of questions:
  • 1. What in the world does it take to get an EFI app running...! None of the articles or things I've read have succeeded...
    2. How is it possible that binutils cannot read a file it can output...?!

    3. What is with that screen corruption, and how do I solve it/use the screen output..?!
    4. Is my kernel even getting loaded...?
    I'll try some things first, but I would like some advice...

    EDIT: Nothing worked, so I'm assuming GRUB is *not* even loading my file. wth...?!

    • - Setting CR3 to garbage
      - Divide by 0 (I would assume EFI has basic ISR handlers...?)
      - etc.

    5. The latest multiboot2.h file specifies a

    Code: Select all

    struct multiboot_tag_efi64
    {
            uint32_t type;
            uint32_t size;
            uint64_t pointer;
    }
    
    Would 'pointer' point to the EFI_SYSTEM_TABLE* that is usually passed as an argument to a normal EFI application...?
So many problems...

I would appreciate some help/advice on this, thanks!