Forums before death by AOL, social media and spammers... "We can't have nice things"
|    alt.os.development    |    Operating system development chatter    |    4,255 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 3,977 of 4,255    |
|    wolfgang kern to James Harris    |
|    Q1-4: in UEFI boot basics    |
|    25 Nov 23 07:13:53    |
   
   From: nowhere@never.at   
      
   On 24/11/2023 18:59, James Harris wrote:   
      
   > efi_main is:   
      
   > ;Called with x64 ms abi   
   > ; RCX = image   
   > ; RDX = systab   
      
   where to ??? address of this call ms abi is   
   [rcx + efi_stop.OutputString] ???   
      
      
   > global efi_main   
   > efi_main:   
   >   
   > push rbp   
   > mov rbp, rsp   
   > sub rsp, 32   
   > mov r10, rdi ;image   
   > mov r11, rsi ;systab   
   >   
   > lea rdx, [rel msg_hello]   
   > mov rcx, [r11 + efi_systab.conout]   
   > mov rax, [rcx + efi_stop.OutputString]   
      
   > call rax   
   >   
   > add rsp, 32   
   > pop rbp   
   > ret   
   >   
   > section .data   
   >   
   > msg_hello: dw __?utf16?__("Hello 64 UEFI..."), 13, 10, 0   
   ...   
   > So pushing RBP will realign the stack. But that needs to be revisited.   
      
   yes, I'd try stack aligning from very start w/o using RBP at all,   
      
   may the call return any useful parameter on the stack or in REGs ?   
   or can we just ignore all of it.   
      
   copied from below:   
    > struc efi_stop ;UEFI simple text output protocol   
    > .Reset: resq 1   
    > .OutputString: resq 1   
    > .TestString: resq 1   
    > .QueryMode: resq 1   
    > .SetMode: resq 1   
    > .SetAttribute: resq 1   
    > .ClearScreen: resq 1   
    > .SetCursorPosition: resq 1   
    > .EnableCursor: resq 1   
    > .Mode: resq 1   
    > endstruc   
      
   how would this struct look in my notes: ?   
   I assume resq 1 mean 64 bit pointers   
      
   000 qq reset   
   008 qq OutputString   
   010 qq ...   
   ...   
   048 qq mode   
      
   and how can we know the value for the call ?   
   is there a thunk table somewhere or windoze styled call by "name".   
      
    > In that, the OutputString field holds the address of the UEFI function   
      
   THAT'S the question: how to find these function addresses ?   
      
    > which can be called to write a string of 16-bit chars to the screen.   
    > It is passed   
    >   
    > ECX = the STO table for the console (i.e. conout)   
    > EDX = the string to print   
      
   > One thing UEFI gives the booted code is a pointer to the System Table.   
   > The table is documented in section 4. It starts with the following   
   > fields. (I included only as far as I needed.)   
      
   how. where and when will UEFI give me that?   
      
      
   > struc efi_systab ;UEFI system table   
   > .hdr: resb efi_hdr_size   
   > .fvend: resq 1 ;FirmwareVendor   
   > .frev: resd 1 ;FirmwareRevision   
   > resd 1 ;padding   
   > .coninh: resq 1 ;ConsoleInHandle   
   > .conin: resq 1 ;ConIn   
   > .conouth: resq 1 ;ConsoleOutHandle   
   > .conout: resq 1 ;ConOut   
   > endstruc   
      
      
   > The header is   
      
   > struc efi_hdr ;Generic header   
   > .Signature: resq 1   
   > .Revision: resd 1   
   > .HeaderSize: resd 1   
   > .CRC32: resd 1   
   > resd 1 ;reserved   
   > endstruc   
      
   can you please show me the above again in my notation   
   don't mind I already got your type cast style :)   
      
   > A note for anyone not familiar with C: where the spec in section 4.3.1 says   
   >   
   > CHAR16    
   *FirmwareVendor;   
   > UINT32    
   FirmwareRevision;   
   >   
   > whereas FirmwareRevision in the second line is uint32, as you might   
   > expect, the asterisk on the first line indicates that FirmwareVendor is   
   > a /pointer/ to the stated type, char16, and so in this case the field is   
   > 64-bit.   
      
   now I'm totally confused yet, CHAR16 means 64 bit ?   
   it seems it's just another 64 bit pointer.   
      
   > Going back to the code, the System Table's conout field is a pointer to   
   > a 'simple text output' (STO) table for the console, i.e. the screen at   
   > boot time. An STO table includes the following fields.   
   >   
   > struc efi_stop ;UEFI simple text output protocol   
   > .Reset: resq 1   
   > .OutputString: resq 1   
   > .TestString: resq 1   
   > .QueryMode: resq 1   
   > .SetMode: resq 1   
   > .SetAttribute: resq 1   
   > .ClearScreen: resq 1   
   > .SetCursorPosition: resq 1   
   > .EnableCursor: resq 1   
   > .Mode: resq 1   
   > endstruc   
   >   
   > In that, the OutputString field holds the address of the UEFI function   
   > which can be called to write a string of 16-bit chars to the screen. It   
   > is passed   
   >   
   > ECX = the STO table for the console (i.e. conout)   
   > EDX = the string to print   
   >   
   > Lo and behold, text appears! At least it does if one has everything   
   > right. I can say more about that if anyone wants but for now I'll stop   
   > here and not make this post any longer.   
   >   
   > Feel free to add comments, questions and corrections.   
      
   thanks a lot, I now learned how to interpret your RESb/d/q :)   
   __   
   wolfgang   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca