Question about EFI_TABLE_HEADER
-
- Posts: 16
- Joined: Thu Apr 02, 2020 5:24 pm
Question about EFI_TABLE_HEADER
Hello, i'm programming actually UEFI Bootloader. He work fine. I have followed this link to understand how the EFI protocol work: https://johv.dk/blog/bare-metal-assembly-tutorial.html
But i don't understand something about EFI_TABLE_HEADER size (into EFI_SYSTEM_TABLE structure.
This link say EFI_TABLE_HEADER (hdr) is 12 bytes and this is specified into p.p0 of UEFI specification.
But when i have looked this into UEFI specification, this isn't this size: you have 1 x UINT64 and 4 x UINT32 = 8 + ( 4*4) = 24 bytes ... I think i don't understand something
But i don't understand something about EFI_TABLE_HEADER size (into EFI_SYSTEM_TABLE structure.
This link say EFI_TABLE_HEADER (hdr) is 12 bytes and this is specified into p.p0 of UEFI specification.
But when i have looked this into UEFI specification, this isn't this size: you have 1 x UINT64 and 4 x UINT32 = 8 + ( 4*4) = 24 bytes ... I think i don't understand something
Re: Question about EFI_TABLE_HEADER
I make it 24 bytes for the header then 5 * 8 bytes for the remaining fields before *ConOut (allowing for each field being 8 byte aligned). So the offset 64 is correct, but the calculation is hokum.
Almost all tutorials contain errors - if you see a discrepancy between the documentation and a tutorial, always believe the former.
Almost all tutorials contain errors - if you see a discrepancy between the documentation and a tutorial, always believe the former.
-
- Posts: 16
- Joined: Thu Apr 02, 2020 5:24 pm
Re: Question about EFI_TABLE_HEADER
I have thinking it's an error, but his code works ...
Re: Question about EFI_TABLE_HEADER
Did you read what I said?
The calculation is rubbish, but it just happens to come up with the right answer. It's important to understand what you are doing rather than blindly following a tutorial.
The calculation is rubbish, but it just happens to come up with the right answer. It's important to understand what you are doing rather than blindly following a tutorial.
-
- Posts: 16
- Joined: Thu Apr 02, 2020 5:24 pm
Re: Question about EFI_TABLE_HEADER
Oh yes sorry, i'm french and sometimes if i read so fast, i miss some informations
I'm agree with you
If you can help me, i search to call function to change console text color, but i haven't any success...
Look:
I know my argument are bad, but i don't understand what argument i need to pass
I'm agree with you
If you can help me, i search to call function to change console text color, but i haven't any success...
Look:
Code: Select all
format pe64 efi
entry Main
section '.text' code readable executable
Main:
mov rcx,[rdx+64]
mov rax,[rcx+40]
mov rdx,0010000b+0x0
sub rsp,32
call rax
add rsp,32
mov rcx,[rdx+64]
mov rax,[rcx+8]
mov rdx,SystemMessage
sub rsp,32
call rax
add rsp,32
mov rcx,[rdx+64]
mov rax,[rcx+40]
mov rdx,1111000b+0x0
sub rsp,32
call rax
add rsp,32
mov rcx,[rdx+64]
mov rax,[rcx+8]
mov rdx,Message
sub rsp,32
call rax
add rsp,32
jmp $
section '.data' data readable writable
SystemMessage du '* EFI Boot: '
Message du 'Test OK',0xD,0xA,0x0
Re: Question about EFI_TABLE_HEADER
the header size is 24 bytes and not 12, every field needs NOT to be 8-byte aligned, only 8-byte ones do. the tutorial has some error statements, that don't help at least to say.
First, you need to learn alignment rules. they are tricky but 100% deterministic, there is no uncertainty, cannot be.
Second. for the sake of God, write for UEFI in C. it was made for this exactly way. you will waste a lot of time fooling around assembly there. later on, when having loaded your kernel, you can happily do as much assembly as you want.
First, you need to learn alignment rules. they are tricky but 100% deterministic, there is no uncertainty, cannot be.
Second. for the sake of God, write for UEFI in C. it was made for this exactly way. you will waste a lot of time fooling around assembly there. later on, when having loaded your kernel, you can happily do as much assembly as you want.
Re: Question about EFI_TABLE_HEADER
Not really all that hard.zaval wrote:First, you need to learn alignment rules. they are tricky but 100% deterministic, there is no uncertainty, cannot be.
- Elementary types: Alignment == Size
- Arrays: Alignment == Alignment of base type
- Structs/Unions: Alignment == Largest alignment of the members
- 64-bit integers usually have alignment 8 on 64-bit architectures, but alignment 4 on 32-bit architectures. There, they behave like a struct of two 32-bit integers.
- Long double is weird. On x86, the usable size of long double is 10 bytes, which really doesn't fit most schemes, so in 32-bit mode it is typically given a size of 12 bytes,with an alignment of 4, but in 64-bit mode it has a size of 16 bytes and an alignment of 16 bytes.
Carpe diem!
-
- Posts: 16
- Joined: Thu Apr 02, 2020 5:24 pm
Re: Question about EFI_TABLE_HEADER
Okay, thanks you. But the problem isn't with fonction calling to show text, this part work. It's just for changing color. It's difficult to found good tutorial yes. Many times, i need to understand alone to programming intoassembly, many people say some bad explanations.zaval wrote:the header size is 24 bytes and not 12, every field needs NOT to be 8-byte aligned, only 8-byte ones do. the tutorial has some error statements, that don't help at least to say.
Yes it's true. I understand the purpose of alignement, but i have problem how alignement works. And where do you have found into UEFI documentation data need to be aligned ? I don't remember i have read that.zaval wrote:First, you need to learn alignment rules. they are tricky but 100% deterministic, there is no uncertainty, cannot be
I know UEFI is writed for C, but in one word: NO. I have time and i would like to code with assembly sorry (i detest to program with high level language)zaval wrote:Second. for the sake of God, write for UEFI in C. it was made for this exactly way. you will waste a lot of time fooling around assembly there. later on, when having loaded your kernel, you can happily do as much assembly as you want.
I programming only for Intel 64 bits processor at the moment.nullplan wrote:Not really all that hard.zaval wrote:First, you need to learn alignment rules. they are tricky but 100% deterministic, there is no uncertainty, cannot be.With only two caveats, really:
- Elementary types: Alignment == Size
- Arrays: Alignment == Alignment of base type
- Structs/Unions: Alignment == Largest alignment of the members
Oh, and nonstandard types (e.g. vector types) are weird and usually, you don't need to care.
- 64-bit integers usually have alignment 8 on 64-bit architectures, but alignment 4 on 32-bit architectures. There, they behave like a struct of two 32-bit integers.
- Long double is weird. On x86, the usable size of long double is 10 bytes, which really doesn't fit most schemes, so in 32-bit mode it is typically given a size of 12 bytes,with an alignment of 4, but in 64-bit mode it has a size of 16 bytes and an alignment of 16 bytes.
Re: Question about EFI_TABLE_HEADER
Obviously it's entirely your choice, but if you insist on not taking advantage of the benefits of high-level languages then you should be prepared to do most of the work for yourself. Most example code is in C and it is the language that the majority of programmers in this field use. So, really, it's not entirely fair to ask for help to solve difficulties that are of your own making.Fulgurance wrote:I know UEFI is writed for C, but in one word: NO. I have time and i would like to code with assembly sorry (i detest to program with high level language)
Re: Question about EFI_TABLE_HEADER
just a clear proof it's tricky. because you are wrong here. ironically, just a few days ago, I stumbled upon this question, on the example of one UEFI structure and was wondering - really, would a 64 bit field in a structure require 8-byte alignment on a 32 bit architecture? after all, the native word is 32 bit and that field would be accessed as 2 32 bit words. the structure in question:With only two caveats, really:
64-bit integers usually have alignment 8 on 64-bit architectures, but alignment 4 on 32-bit architectures. There, they behave like a struct of two 32-bit integers.
Code: Select all
typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE{
UINT32 MaxMode;
UINT32 Mode;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
UINTN SizeOfInfo;
EFI_PHYSICAL_ADDRESS FrameBufferBase;
UINTN FrameBufferSize;
}EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE, *PEFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
In the UEFI data structures, there is a lot of places, where dudes, devising them, introduced misaligned layout, see the example above. this especially important for you, - one, that wants to program in assembly, since you need to calculate offsets to the fields manually. unlike C programmers. Got it? if the structure were layed out without the need for the compiler to add padding, it would be easier - you would look at it and straight calculate offsets adding sizes of the previous elements. now, you need to thouroughly analyze and see where the compiler has put padding and take that into account. let me show you one the most f&cked up structures in the UEFI regarding this, yet it's a very used one by OS loaders:Yes it's true. I understand the purpose of alignement, but i have problem how alignement works. And where do you have found into UEFI documentation data need to be aligned ? I don't remember i have read that.
Code: Select all
struct _EFI_LOADED_IMAGE_PROTOCOL{
UINT32 Revision;
EFI_HANDLE ParentHandle;
EFI_SYSTEM_TABLE *SystemTable;
/* Source location of the image */
EFI_HANDLE DeviceHandle;
EFI_DEVICE_PATH_PROTOCOL *FilePath;
VOID *Reserved;
/* Image’s load options */
UINT32 LoadOptionsSize;
VOID *LoadOptions;
/* Location where image was loaded */
VOID *ImageBase;
UINT64 ImageSize;
EFI_MEMORY_TYPE ImageCodeType;
EFI_MEMORY_TYPE ImageDataType;
EFI_IMAGE_UNLOAD Unload;
};
Code: Select all
struct _EFI_LOADED_IMAGE_PROTOCOL{
UINT32 Revision;
#if TARGET_BITNESS == 0x40
UINT32 _Pad_64_0;
#endif
EFI_HANDLE ParentHandle;
EFI_SYSTEM_TABLE *SystemTable;
/* Source location of the image */
EFI_HANDLE DeviceHandle;
EFI_DEVICE_PATH_PROTOCOL *FilePath;
VOID *Reserved;
/* Image’s load options */
UINT32 LoadOptionsSize;
#if TARGET_BITNESS == 0x40
UINT32 _Pad_64_1;
#endif
VOID *LoadOptions;
/* Location where image was loaded */
VOID *ImageBase;
#if TARGET_BITNESS == 0x20
UINT32 _Pad_32_0;
#endif
UINT64 ImageSize;
EFI_MEMORY_TYPE ImageCodeType;
EFI_MEMORY_TYPE ImageDataType;
EFI_IMAGE_UNLOAD Unload;
#if TARGET_BITNESS == 0x20
UINT32 _Pad_32_1;
#endif
};
PS. Funny, they were greedy to make Revision and LoadOptionSize UINTN, that would instantly eliminate both misalignment on 64 bits, but made ImageSize always 64 bit, what introduced 2 misalignments on 32 bits. did they think that one day a UEFI executable won't fit 4GB? well, maybe if made as the modern "web technology", then it's not that infeasible. after all, Chrome now eats up 100MB of RAM for every web page, even containing just a moderate amount of text and a few of tiny icons.
Re: Question about EFI_TABLE_HEADER
OK, obviously I should have included a statement to the effect of: 64-bit integers on 32-bit architectures can get tricky, so look it up in the relevant ABI. The only 32-bit architecture I normally work with is PPC32, and there my statement is correct.zaval wrote:just a clear proof it's tricky. because you are wrong here. ironically, just a few days ago, I stumbled upon this question, on the example of one UEFI structure and was wondering - really, would a 64 bit field in a structure require 8-byte alignment on a 32 bit architecture? after all, the native word is 32 bit and that field would be accessed as 2 32 bit words.
Also of note: Double precision floating point numbers generally have alignment 8 even on 32-bit architectures. And some PPC implementations will trap when accessing misaligned floating point numbers, even if they ordinarily would not when accessing integers.
Yeah, assembly is difficult. Specifically, interfacing assembly and C requires knowledge of the ABI so you don't make mistakes. At the end of the day, the compiler does a hard job, and unlike people it does not get tired and makes mistakes due to fatigue.zaval wrote:this all is not a concern for a C coder, since compilers take care of this burden, but our OP wants be all assembly. hehe.
I went through a phase where I was writing Win32 GUI applications in assembly. But that was totally pointless, since that was mostly about calling DLL functions, so the programs were always just push-push-push-push-call. And with Win32's tendency to long parameter lists, messing up and pushing the wrong number of things, or pushing things in the wrong order, was a constant threat. I gave up on it after spending some hours debugging a crash, finally asking for help, and having it revealed that I called a function wrong. Which a compiler would have told me in less than one second.
Carpe diem!
Re: Question about EFI_TABLE_HEADER
In this case I'd recommend the following sources:Fulgurance wrote:I know UEFI is writed for C, but in one word: NO. I have time and i would like to code with assembly sorry (i detest to program with high level language)
- Uefi.inc - an UEFI ABI wrapper. Provides a "uefi_call_wrapper" macro for fasm (works just like in GNUEFI), it's a bit easier to use and makes your code more readable
- x86asm.net on UEFI - great source with lots of explanation
Cheers,
bzt