Recent

Author Topic: Does anyone know why this code cannot show the hello world in uefi?  (Read 1571 times)

TYDQ

  • New Member
  • *
  • Posts: 48
I am writing an Demo which just show Hello World on the console screen.I have read https://kagurazakakotori.github.io/ubmp-cn/part1/basics/program.html to writing my Pascal Code for UEFI with UEFI Specifiation but I failed to execute my pascal code using QEMU and OVMF.fd,These are my full code and build.sh:
System.pas:
Code: Pascal  [Select][+][-]
  1. unit system;
  2. {$MODE FPC}
  3. interface
  4.  
  5. type
  6.   hresult = LongInt;
  7.   DWord = LongWord;
  8.   Cardinal = LongWord;
  9.   Integer = SmallInt;
  10.   UInt64 = QWord;
  11.   Pbyte=^byte;
  12.   Pchar=^char;
  13.   PWideChar=^WideChar;
  14.   PPWideChar=^PWideChar;
  15.   variableargument_list=^byte;
  16.   Pword=^word;
  17.   Pdword=^dword;
  18.   Pqword=^qword;
  19.   PPointer=^Pointer;
  20.   Pboolean=^boolean;
  21.   {$IFDEF CPU32}
  22.   NatUint=dword;
  23.   PNatUint=^dword;
  24.   {$ELSE}
  25.   NatUint=qword;
  26.   PNatUint=^qword;
  27.   {$ENDIF}
  28.   TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkSet,
  29.     tkMethod, tkSString, tkLString, tkAString, tkWString, tkVariant, tkArray,
  30.     tkRecord, tkInterface, tkClass, tkObject, tkWChar, tkBool, tkInt64, tkQWord,
  31.     tkDynArray, tkInterfaceRaw, tkProcVar, tkUString, tkUChar, tkHelper, tkFile,
  32.     tkClassRef, tkPointer);
  33.   jmp_buf = packed record
  34.     rbx, rbp, r12, r13, r14, r15, rsp, rip: QWord;
  35.     {$IFDEF win64}
  36.     rsi, rdi: QWord;
  37.     xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15: record
  38.       m1, m2: QWord;
  39.     end;
  40.     mxcsr: LongWord;
  41.     fpucw: word;
  42.     padding: word;
  43.     {$ENDIF win64}
  44.   end;
  45.   Pjmp_buf = ^jmp_buf;
  46.   PExceptAddr = ^TExceptAddr;
  47.   TExceptAddr = record
  48.     buf: Pjmp_buf;
  49.     next: PExceptAddr;
  50.     {$IFDEF CPU16}
  51.     frametype: SmallInt;
  52.     {$ELSE CPU16}
  53.     frametype: LongInt;
  54.     {$ENDIF CPU16}
  55.   end;
  56.   PGuid = ^TGuid;
  57.   TGuid = packed record
  58.     case Integer of
  59.     1:
  60.      (Data1: DWord;
  61.       Data2: word;
  62.       Data3: word;
  63.       Data4: array [0 .. 7] of byte;
  64.     );
  65.     2:
  66.      (D1: DWord;
  67.       D2: word;
  68.       D3: word;
  69.       D4: array [0 .. 7] of byte;
  70.     );
  71.     3:
  72.     ( { uuid fields according to RFC4122 }
  73.       time_low: DWord; // The low field of the timestamp
  74.       time_mid: word; // The middle field of the timestamp
  75.       time_hi_and_version: word;
  76.       // The high field of the timestamp multiplexed with the version number
  77.       clock_seq_hi_and_reserved: byte;
  78.       // The high field of the clock sequence multiplexed with the variant
  79.       clock_seq_low: byte; // The low field of the clock sequence
  80.       node: array [0 .. 5] of byte; // The spatially unique node identifier
  81.     );
  82.   end;
  83. implementation
  84.  
  85. end.
uefimain.pas:
Code: Pascal  [Select][+][-]
  1. unit uefimain;
  2.  
  3. interface
  4. uses uefi;
  5. procedure efi_main(ImageHandle:Pointer;SystemTable:Pefi_system_table);cdecl;
  6. implementation
  7. procedure efi_main(ImageHandle:Pointer;SystemTable:Pefi_system_table);cdecl;[public,alias:'efi_main'];
  8. begin
  9.  SystemTable^.ConOut^.ClearScreen(SystemTable^.ConOut);
  10.  SystemTable^.ConOut^.OutputString(SystemTable^.ConOut,PWideChar('Hello UEFI!'+#10));
  11.  while(True) do;
  12. end;
  13.  
  14. end.
build.sh:
Code: Bash  [Select][+][-]
  1. fpc -APECoff -n -O4 -Si -Sc -Sg -Xd -CX -XXs -Px86_64 -Rintel -Twin64 uefimain.pas
  2.         ld --gc-sections -nostdlib -fno-builtin -shared --oformat pei-x86-64 uefimain.o uefi.o system.o -e efi_main -o MAIN.EFI
  3.         objcopy -I pei-x86-64 -O efi-app-x86-64 MAIN.EFI bootx64.efi
  4.         dd if=/dev/zero of=fat.img bs=512 count=93750
  5.         /usr/sbin/mkfs.vfat -F 32 fat.img
  6.         mmd -i fat.img ::/EFI
  7.         mmd -i fat.img ::/EFI/BOOT
  8.         mcopy -i fat.img bootx64.efi ::/EFI/BOOT
  9.         mkdir iso
  10.         cp fat.img iso
  11.         xorriso -as mkisofs -R -f -e fat.img -no-emul-boot -o cdimage.iso iso
  12.         qemu-system-x86_64 -bios OVMF.fd -m 2048 -cdrom cdimage.iso
  13.         rm -rf iso
  14.         rm -rf *.ppu
  15.         rm -rf *.img
As I enter bash build.sh to execute the program,I have met the error shows:
BdsDxe:loading Boot0001 "UEFI QEMU DVD-ROM QM00003" from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0)
BdsDxe:failed to load Boot0001 "UEFI QEMU DVD-ROM QM00003" from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0) :Unsupported

>>Start PXE over IPv4.
Does anyone discover what occurs the error and tell me what?Thank you for solving my problem.
« Last Edit: April 16, 2024, 09:08:27 am by TYDQ »

TYDQ

  • New Member
  • *
  • Posts: 48
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #1 on: April 16, 2024, 08:50:45 am »
uefi.pas as a extra:
Code: Pascal  [Select][+][-]
  1. unit uefi;
  2.  
  3. interface
  4. type efi_guid=record
  5.               data1:dword;
  6.               data2:word;
  7.               data3:word;
  8.               data4:array[0..7] of byte;
  9.               end;
  10.      Pefi_guid=^efi_guid;
  11.      PPefi_guid=^Pefi_guid;
  12.      PPPefi_guid=^PPefi_guid;
  13.      efi_table_header=record
  14.                       signature:qword;
  15.                       revision:dword;
  16.                       headersize:dword;
  17.                       crc32:dword;
  18.                       reserved:dword;
  19.                       end;
  20.      efi_handle=pointer;
  21.      Pefi_handle=^pointer;
  22.      PPefi_handle=^Pefi_handle;
  23.      efi_event=pointer;
  24.      Pefi_event=^pointer;
  25.      PPefi_event=^Pefi_event;
  26.      efi_physical_address=qword;
  27.      efi_virtual_address=qword;
  28.      efi_input_key=record
  29.                    scancode:word;
  30.                    UnicodeChar:WideChar;
  31.                    end;
  32.      efi_status=NatUint;
  33.      Pefi_simple_text_input_protocol=^efi_simple_text_input_protocol;
  34.      efi_input_reset=function (This:Pefi_simple_text_input_protocol;ExtendedVerification:boolean):EFI_STATUS;
  35.      efi_input_read_key=function (This:Pefi_simple_text_input_protocol;var key:efi_input_key):EFI_STATUS;
  36.      efi_simple_text_input_protocol=record
  37.                                     Reset:efi_input_reset;
  38.                                     ReadKeyStroke:efi_input_read_key;
  39.                                     WaitForKey:efi_event;
  40.                                     end;
  41.      Pefi_simple_text_output_protocol=^efi_simple_text_output_protocol;
  42.      simple_text_output_mode=record
  43.                              MaxMode:integer;
  44.                              SAttribute:integer;
  45.                              CursorColumn:integer;
  46.                              CursorRow:integer;
  47.                              CursorVisible:boolean;
  48.                              end;
  49.      efi_text_reset=function (This:Pefi_simple_text_output_protocol;ExtendedVerification:boolean):efi_status;
  50.      efi_text_output_string=function (This:Pefi_simple_text_output_protocol;efistring:PWideChar):efi_status;
  51.      efi_text_test_string=function (This:Pefi_simple_text_output_protocol;efistring:PWideChar):efi_status;
  52.      efi_text_query_mode=function (This:Pefi_simple_text_output_protocol;Modenumber:NatUint;var Columns,Rows:NatUint):efi_status;
  53.      efi_text_set_mode=function (This:Pefi_simple_text_output_protocol;Modenumber:NatUint):efi_status;
  54.      efi_text_set_attribute=function (This:Pefi_simple_text_output_protocol;eattribute:NatUint):efi_status;
  55.      efi_text_clear_screen=function (This:Pefi_simple_text_output_protocol):efi_status;
  56.      efi_text_set_cursor_position=function (This:Pefi_simple_text_output_protocol;column,row:Natuint):efi_status;
  57.      efi_text_enable_cursor=function (This:Pefi_simple_text_output_protocol;visible:boolean):efi_status;
  58.      efi_simple_text_output_protocol=record
  59.                                      Reset:efi_text_reset;
  60.                                      Outputstring:efi_text_output_string;
  61.                                      Teststring:efi_text_test_string;
  62.                                      QueryMode:efi_text_query_mode;
  63.                                      SetMode:efi_text_set_mode;
  64.                                      SetAttribute:efi_text_set_attribute;
  65.                                      clearscreen:efi_text_clear_screen;
  66.                                      setcursorposition:efi_text_set_cursor_position;
  67.                                      enablecursor:efi_text_enable_cursor;
  68.                                      mode:^simple_text_output_mode;
  69.                                      end;
  70.      efi_time=record
  71.               year:word;
  72.               month:byte;
  73.               day:byte;
  74.               hour:byte;
  75.               minute:byte;
  76.               second:byte;
  77.               pad1:byte;
  78.               nanosecond:longword;
  79.               timezone:smallint;
  80.               daylight:byte;
  81.               pad2:byte;
  82.               end;
  83.      Pefi_time=^efi_time;
  84.      efi_time_capabilities=record
  85.                            resolution:dword;
  86.                            accuracy:dword;
  87.                            SetsToZero:boolean;
  88.                            end;
  89.      Pefi_time_capabilities=^efi_time_capabilities;
  90.      efi_memory_descriptor=record
  91.                            efitype:longword;
  92.                            physicalstart:efi_physical_address;
  93.                            virtualstart:efi_virtual_address;
  94.                            NumberofPages:qword;
  95.                            efiAttribute:qword;
  96.                            end;
  97.      Pefi_memory_descriptor=^efi_memory_descriptor;
  98.      efi_get_time=function (var Time:Pefi_time;var Capabilities:Pefi_time_capabilities):efi_status;cdecl;
  99.      efi_set_time=function (Time:Pefi_time):efi_status;cdecl;
  100.      efi_get_wakeup_time=function (var Enabled,Pending:boolean;var Time:Pefi_time):efi_status;cdecl;
  101.      efi_set_wakeup_time=function (enabled:boolean;Time:Pefi_time):efi_status;cdecl;
  102.      efi_set_virtual_address_map=function (MemoryMapSize,DescriptorSize:NatUint;DescriptorVersion:dword;VirtualMap:Pefi_memory_descriptor):efi_status;cdecl;
  103.      efi_convert_pointer=function (DebugPosition:NatUint;Address:PPointer):efi_status;cdecl;
  104.      efi_get_variable=function (VariableName:PWideChar;VendorGuid:efi_guid;var attributes:dword;var datasize:NatUint;var data:Pointer):efi_Status;cdecl;
  105.      efi_get_next_variable_name=function (var VariableNameSize:PNatUint;var VariableName:PWidechar;var VendorGuid:Pefi_guid):efi_status;cdecl;
  106.      efi_set_variable=function (VariableName:PWideChar;VendorGuid:Pefi_guid;Attributes:dword;DataSize:Natuint;Data:Pointer):efi_status;cdecl;
  107.      efi_get_next_monotonic_count=function (Highcount:Pdword):efi_Status;cdecl;
  108.      efi_reset_type=(EfiResetCold,EfiResetWarm,EfiResetShutDown,EfiResetPlatformSpecific);
  109.      Pefi_reset_type=^efi_reset_type;
  110.      efi_reset_system=function (ResetType:efi_reset_type;ResetStatus:efi_status;DataSize:Natuint;ResetData:Pointer):efi_status;cdecl;
  111.      efi_capsule_block_descriptor=record
  112.                                   efilength:qword;
  113.                                   case Boolean of
  114.                                   True:(DataBlock:efi_physical_address);
  115.                                   False:(ContinuationPointer:efi_physical_address);
  116.                                   end;
  117.      efi_capsule_header=record
  118.                         CapsuleGuid:efi_guid;
  119.                         headersize:dword;
  120.                         flags:dword;
  121.                         CapsuleImageSize:dword;
  122.                         end;
  123.      Pefi_capsule_header=^efi_capsule_header;
  124.      PPefi_capsule_header=^Pefi_capsule_header;
  125.      efi_update_capsule=function (CapsuleHeaderArray:PPefi_capsule_header;CapsuleCount:NatUint;ScatterGatherList:efi_physical_address):efi_status;cdecl;
  126.      efi_query_capsule_capabilities=function (CapsuleHeaderArray:PPefi_capsule_header;CapsuleCount:NatUint;var MaximumCapsuleSize:qword;var ResetType:Pefi_reset_type):efi_status;cdecl;
  127.      efi_query_variable_info=function (attributes:dword;MaximumVariableStorageSize,RemainingVariableStorageSize,MaximumVariableSize:Pqword):efi_status;cdecl;                
  128.      efi_runtime_services=record
  129.                           hdr:efi_table_header;
  130.                           Gettime:efi_get_time;
  131.                           Settime:efi_set_time;
  132.                           GetWakeupTime:efi_get_wakeup_time;
  133.                           SetWakeupTime:efi_set_wakeup_time;
  134.                           SetVirtualAddressMap:efi_set_virtual_address_map;
  135.                           ConvertPointer:efi_convert_pointer;
  136.                           getvariable:efi_get_variable;
  137.                           getnextvariablename:efi_get_next_variable_name;
  138.                           setvariable:efi_set_variable;
  139.                           GetNextMonotonicCount:efi_get_next_monotonic_count;
  140.                           ResetSystem:efi_reset_system;
  141.                           UpdateCapsule:efi_update_capsule;
  142.                           QueryCapsuleCapabilities:efi_query_capsule_capabilities;
  143.                           QueryVariableInfo:efi_query_variable_info;
  144.                           end;
  145.      efi_tpl=NatUint;
  146.      efi_raise_tpl=function (NewTpl:efi_tpl):efi_status;cdecl;
  147.      efi_restore_tpl=function (OldTpl:efi_tpl):efi_status;cdecl;
  148.      efi_allocate_type=(AllocateAnyPages,AllocateMaxAddress,AllocateAddress,MaxAllocateType);
  149.         efi_memory_type=(EfiReservedMemoryType,EfiLoaderCode,EfiLoaderData,EfiBootServicesCode,EfiBootServicesData,EfiRuntimeServicesCode,EfiRuntimeServicesData,EfiConventionalMemory,EfiUnusableMemory,EfiACPIReclaimMemory,EfiACPIMemoryNVS,EfiMemoryMappedIO,EfiMemoryMappedIOPortSpace,EfiPalCode,EfiPersistentMemory,EfiUnacceptedMemoryType,EfiMaxMemoryType);
  150.      efi_allocate_pages=function (efitype:efi_allocate_type;MemoryType:efi_memory_type;Pages:NatUint;Memory:Pqword):efi_status;cdecl;
  151.      efi_free_pages=function (Memory:qword;Pages:NatUint):efi_status;cdecl;
  152.      efi_get_memory_map=function (var MemoryMapSize:PNatuint;var Memory_map:Pefi_memory_descriptor;var MapKey,DescriptorSize:PNatUint;var DescriptorVersion:Pdword):efi_status;cdecl;
  153.      efi_allocate_pool=function (PoolType:efi_memory_type;Size:NatUint;var Buffer:PPointer):efi_status;cdecl;
  154.      efi_free_pool=function (Buffer:Pointer):efi_status;cdecl;
  155.      efi_event_notify=function (Event:efi_event;Context:Pointer):efi_status;cdecl;
  156.      efi_create_event=function (efitype:dword;NotifyTpl:efi_tpl;NotifyFunction:efi_event_notify;NotifyContext:Pointer;var Event:Pefi_event):efi_status;cdecl;
  157.      efi_create_event_ex=function (efitype:dword;NotifyTpl:efi_tpl;NotifyFunction:efi_event_notify;const NotifyContext:Pointer;const EventGroup:Pefi_guid;var Event:Pefi_event):efi_status;cdecl;
  158.      efi_timer_delay=(TimerCancel,TimerPeriodic,TimerRelative);
  159.      efi_set_timer=function (event:efi_event;efitype:efi_timer_delay;TriggerTime:qword):efi_status;cdecl;
  160.      efi_wait_for_event=function (NumberOfEvents:NatUint;Event:efi_event;Index:PNatUint):efi_status;cdecl;
  161.      efi_signal_event=function (event:efi_event):efi_status;cdecl;
  162.      efi_close_event=function (event:efi_event):efi_status;cdecl;
  163.      efi_check_event=function (event:efi_event):efi_status;cdecl;
  164.      efi_interface_type=(efi_native_interface);
  165.      efi_install_protocol_interface=function (var Handle:Pefi_handle;Protocol:Pefi_guid;InterfaceType:efi_interface_type;efiinterface:Pointer):efi_status;cdecl;
  166.      efi_reinstall_protocol_interface=function (Handle:efi_handle;Protocol:Pefi_guid;Oldinterface,Newinterface:Pointer):efi_status;cdecl;
  167.      efi_uninstall_protocol_interface=function (Handle:efi_handle;Protocol:Pefi_guid;efiinterface:Pointer):efi_status;cdecl;
  168.      efi_handle_protocol=function (Handle:efi_handle;Protocol:Pefi_guid;efiinterface:PPointer):efi_status;cdecl;
  169.      efi_register_protocol_notify=function (Protocol:Pefi_guid;Event:efi_event;var Registration:PPointer):efi_status;cdecl;
  170.      efi_locate_search_type=(AllHandles,ByRegisterNotify,ByProtocol);
  171.      efi_locate_handle=function (SearchType:efi_locate_search_type;Protocol:Pefi_guid;SearchKey:Pointer;var BufferSize:Pointer;var Buffer:Pefi_handle):efi_status;cdecl;
  172.      efi_device_path_protocol=record
  173.                               efitype:byte;
  174.                               subtype:byte;
  175.                               efilength:array[0..1] of byte;
  176.                               end;
  177.      Pefi_device_path_protocol=^efi_device_path_protocol;
  178.      PPefi_device_path_protocol=^Pefi_device_path_protocol;
  179.      efi_locate_device_path=function (Protocol:Pefi_guid;var DevicePath:PPefi_device_path_protocol;Device:Pefi_handle):efi_status;cdecl;
  180.      efi_install_configuration_table=function (Guid:Pefi_guid;Table:Pointer):efi_status;cdecl;
  181.      efi_image_load=function (BootPolicy:boolean;ParentImageHandle:efi_handle;DevicePath:Pefi_device_path_protocol;SourceBuffer:Pointer;SourceSize:NatUint;var ImageHandle:Pefi_handle):efi_status;cdecl;
  182.      efi_image_start=function (ImageHandle:efi_handle;var ExitDataSize:PNatUint;var ExitData:PPWideChar):efi_status;cdecl;
  183.      efi_exit=function (ImageHandle:efi_handle;ExitStatus:efi_status;ExitDataSize:NatUInt;ExitData:PWideChar):efi_status;cdecl;
  184.      efi_image_unload=function (ImageHandle:efi_handle):efi_status;cdecl;
  185.      efi_exit_boot_services=function (ImageHandle:efi_handle;MapKey:NatUint):efi_status;cdecl;
  186.      efi_stall=function (Microseconds:NatUint):efi_status;cdecl;
  187.      efi_set_watchdog_timer=function (Timeout:NatUint;Watchdogcode:qword;DataSize:NatUint;WatchDogData:PWideChar):efi_status;cdecl;
  188.      efi_connect_controller=function (ControllerHandle:efi_handle;DriveImageHandle:Pefi_handle;RemainingDevicePath:Pefi_device_path_protocol;Recursive:boolean):efi_status;cdecl;
  189.      efi_disconnect_controller=function (ControllerHandle,DriverImageHandle,ChildHandle:efi_handle):efi_status;cdecl;
  190.      efi_open_protocol=function (Handle:efi_handle;Protocol:Pefi_guid;var efiinterface:PPointer;AgentHandle:efi_handle;ControllerHandle:efi_handle;Attributes:dword):efi_status;cdecl;
  191.      efi_close_protocol=function (Handle:efi_handle;Protocol:Pefi_guid;AgentHandle:efi_handle;ControllerHandle:efi_handle):efi_status;cdecl;
  192.      efi_open_protocol_information_entry=record
  193.                                          AgentHandle,ControllerHandle:efi_handle;
  194.                                          Attributes,OpenCount:dword;
  195.                                          end;
  196.      Pefi_open_protocol_information_entry=^efi_open_protocol_information_entry;
  197.      PPefi_open_protocol_information_entry=^Pefi_open_protocol_information_entry;
  198.      efi_open_protocol_information=function (Handle:efi_handle;Protocol:Pefi_guid;var EntryBuffer:PPefi_open_protocol_information_entry;EntryCount:PNatUint):efi_status;cdecl;
  199.      efi_Protocols_Per_Handle=function (Handle:efi_handle;var ProtocolBuffer:PPPefi_guid;var ProtocolBufferCount:PNatUint):efi_status;cdecl;
  200.      efi_locate_handle_buffer=function (searchtype:efi_locate_search_type;Protocol:Pefi_guid;SearchKey:Pointer;var noHandles:PNatUint;var Buffer:PPefi_handle):efi_status;cdecl;
  201.      efi_install_multiple_protocol_interfaces=function (var Handle:efi_handle;argument:variableargument_list):efi_status;cdecl;
  202.      efi_uninstall_multiple_protocol_interfaces=function (var Handle:efi_handle;argument:variableargument_list):efi_status;cdecl;
  203.      efi_calculate_crc32=function (Data:Pointer;DataSize:NatUint;var Crc32:Pdword):efi_status;cdecl;
  204.      efi_copy_mem=procedure (Destination,Source:Pointer;efilength:NatUint);cdecl;
  205.      efi_set_mem=procedure (Buffer:Pointer;size:NatUint;efivalue:byte);cdecl;
  206.      efi_boot_services=record
  207.                        hdr:efi_table_header;
  208.                        RaiseTPL:efi_raise_tpl;
  209.                        RestoreTPL:efi_restore_tpl;
  210.                        AllocatePages:efi_allocate_pages;
  211.                        FreePages:efi_free_pages;
  212.                        GetMemoryMap:efi_get_memory_map;
  213.                        AllocatePool:efi_allocate_pool;
  214.                        FreePool:efi_free_pool;
  215.                        CreateEvent:efi_create_event;
  216.                        SetTimer:efi_set_timer;
  217.                        WaitForEvent:efi_wait_for_event;
  218.                        SignalEvent:efi_signal_event;
  219.                        CloseEvent:efi_close_event;
  220.                        CheckEvent:efi_check_event;
  221.                        InstallProtocolInterface:efi_install_protocol_interface;
  222.                        ReinstallProtocolInterface:efi_reinstall_protocol_interface;
  223.                        UninstallProtocolInterface:efi_uninstall_protocol_interface;
  224.                        HandleProtocol:efi_handle_protocol;
  225.                        RegisterProtocolNotify:efi_register_protocol_notify;
  226.                        locatehandle:efi_locate_handle;
  227.                        locatedevicepath:efi_locate_device_path;
  228.                        InstallConfigurationTable:efi_install_configuration_table;
  229.                        loadimage:efi_image_load;
  230.                        startimage:efi_image_start;
  231.                        efiexit:efi_exit;
  232.                        unloadimage:efi_image_unload;
  233.                        exitbootservices:efi_exit_boot_services;
  234.                        GetNextMonotonicCount:efi_get_next_monotonic_count;
  235.                        stall:efi_stall;
  236.                        SetWatchDogTimer:efi_set_watchdog_timer;
  237.                        ConnectController:efi_connect_controller;
  238.                        DisconnectController:efi_disconnect_controller;
  239.                        OpenProtocol:efi_open_protocol;
  240.                        CloseProtocol:efi_close_protocol;
  241.                        OpenProtocolInformation:efi_open_protocol_information;
  242.                        Protocolsperhandle:efi_protocols_per_handle;
  243.                        LocateHandleBuffer:efi_locate_handle_buffer;
  244.                        InstallMultipleProtocolInterfaces:efi_install_multiple_protocol_interfaces;
  245.                        UninstallMultipleProtocolInterfaces:efi_uninstall_multiple_protocol_interfaces;
  246.                        CalculateCrc32:efi_calculate_crc32;
  247.                        CopyMem:efi_copy_mem;
  248.                        SetMem:efi_set_mem;
  249.                        CreateEventEx:efi_create_event_ex;
  250.                        end;
  251.      efi_configuration_table=record
  252.                              VendorGuid:efi_guid;
  253.                              VendorTable:pointer;
  254.                              end;
  255.      efi_system_table=record
  256.                       hdr:efi_table_header;
  257.                       FirmWareVendor:^WideChar;
  258.                       FirmWareRevision:dword;
  259.                       ConIn:^efi_simple_text_input_protocol;
  260.                       ConsoleInHandle:efi_handle;
  261.                       ConOut:^efi_simple_text_output_protocol;
  262.                       StandardErrorHandle:efi_handle;
  263.                       StdErr:^efi_simple_text_output_protocol;
  264.                       RuntimeServices:^efi_runtime_services;
  265.                       bootservices:^efi_boot_services;
  266.                       numberofTableEntries:NatUint;
  267.                       configuration_table:^efi_configuration_table;
  268.                       end;
  269.      Pefi_system_table=^efi_system_table;
  270. implementation
  271.  
  272. end.
« Last Edit: April 16, 2024, 12:16:28 pm by TYDQ »

Laksen

  • Hero Member
  • *****
  • Posts: 758
    • J-Software
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #2 on: April 16, 2024, 12:24:37 pm »
There seems to be some problems in how the PE Executable is linked in the manner you do it. When using the internal linker in FPC it works fine (requires a bit of hacking)

Other than that you have a bug in your efi type definitions. You are missing ConsoleOutHandle

I have attached a version that works fine for me with a trunk compiler. It compiles uefimain as a DLL instead of an executable just to illustrate that it can exit, but the compiler hardcodes the PASCALMAIN entry as no_return for EXEs (it messes up the stack if it does exit and just crashes after fpc_do_exit)

TYDQ

  • New Member
  • *
  • Posts: 48
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #3 on: April 16, 2024, 12:55:39 pm »
There seems to be some problems in how the PE Executable is linked in the manner you do it. When using the internal linker in FPC it works fine (requires a bit of hacking)

Other than that you have a bug in your efi type definitions. You are missing ConsoleOutHandle

I have attached a version that works fine for me with a trunk compiler. It compiles uefimain as a DLL instead of an executable just to illustrate that it can exit, but the compiler hardcodes the PASCALMAIN entry as no_return for EXEs (it messes up the stack if it does exit and just crashes after fpc_do_exit)
So Can you write a correct linker example file to link all pascal files together?I will refer to it and write my own.
And how to use the internal linker of fpc,which format of EFI file it is?
I have add ConsoleOutHandle to my uefi.pas

Laksen

  • Hero Member
  • *****
  • Posts: 758
    • J-Software
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #4 on: April 16, 2024, 01:00:18 pm »
So Can you write a correct linker example file to link all pascal files together?I will refer to it and write my own.
And how to use the internal linker of fpc,which format of EFI file it is?
I have add ConsoleOutHandle to my uefi.pas

No, I don't have time to do that with binutils. The documentation seems non-existing

I attached a zip in the previous post with all the files and a modified build.sh that builds everything with only FPC.

TYDQ

  • New Member
  • *
  • Posts: 48
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #5 on: April 16, 2024, 01:27:04 pm »
So Can you write a correct linker example file to link all pascal files together?I will refer to it and write my own.
And how to use the internal linker of fpc,which format of EFI file it is?
I have add ConsoleOutHandle to my uefi.pas

No, I don't have time to do that with binutils. The documentation seems non-existing

I attached a zip in the previous post with all the files and a modified build.sh that builds everything with only FPC.
Ok,I will try this.If I encounter any error,I will report to you.

TYDQ

  • New Member
  • *
  • Posts: 48
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #6 on: April 16, 2024, 02:28:30 pm »
So Can you write a correct linker example file to link all pascal files together?I will refer to it and write my own.
And how to use the internal linker of fpc,which format of EFI file it is?
I have add ConsoleOutHandle to my uefi.pas

No, I don't have time to do that with binutils. The documentation seems non-existing

I attached a zip in the previous post with all the files and a modified build.sh that builds everything with only FPC.
But I still confused why my code cannot work.Can you patiently answer this question?
And why your code can create correct dll files while I can't?
« Last Edit: April 16, 2024, 02:55:00 pm by TYDQ »

Laksen

  • Hero Member
  • *****
  • Posts: 758
    • J-Software
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #7 on: April 16, 2024, 03:34:38 pm »
My assumption is that it is caused by ld using some default linker script which does not link correctly. Also the default ld might not have proper PECOFF support?

The following linker command works with your code
Code: [Select]
x86_64-w64-mingw32-ld --gc-sections --oformat pei-x86-64 uefimain.o uefi.o system.o -e efi_main -o MAIN.EFI link.lds

Together with this link.lds file. It was generated with fpc for the files I sent previously by supplying -sh on the command line to emit a script to use an external linker. Note, this fails too when using the standard linux binutils ld
Code: [Select]
OUTPUT_FORMAT(pei-x86-64)
ENTRY(efi_main)
SECTIONS
{
  . = SIZEOF_HEADERS;
  . = ALIGN(__section_alignment__);
  .text  __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :
  {
    __text_start__ = . ;
    *(.init)
    *(.text .stub .text.* .gnu.linkonce.t.*)
    *(SORT(.text$*))
    *(.glue_7t)
    *(.glue_7)
    . = ALIGN(8);
     ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
    LONG (-1);
    LONG (-1);
    *(.ctors); *(.ctor); *(SORT(.ctors.*));  LONG (0);
    LONG (0);
     ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
    LONG (-1);
    LONG (-1);
    *(.dtors); *(.dtor); *(SORT(.dtors.*));  LONG (0);
    LONG (0);
     *(.fini)
    PROVIDE (etext = .);
    *(.gcc_except_table)
  }
  .data BLOCK(__section_alignment__) :
  {
    __data_start__ = . ;
    *(.data .data.* .gnu.linkonce.d.* .fpc*)
    *(.data2)
    *(SORT(.data$*))
    *(.jcr)
    PROVIDE (_tls_index = .);
    LONG (0);
    __data_end__ = . ;
    *(.data_cygwin_nocopy)
  }
  .rdata BLOCK(__section_alignment__) :
  {
    *(.rdata)
    *(.rdata.*)
    *(.rodata .rodata.* .gnu.linkonce.r.*)
    *(SORT(.rdata$*))
    *(.eh_frame)
    ___RUNTIME_PSEUDO_RELOC_LIST__ = .;
    __RUNTIME_PSEUDO_RELOC_LIST__ = .;
    *(.rdata_runtime_pseudo_reloc)
    ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
    __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
  }
  .pdata BLOCK(__section_alignment__) : { *(.pdata) }
  .bss BLOCK(__section_alignment__) :
  {
    __bss_start__ = . ;
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(SORT(.bss$*))
    *(COMMON)
    __bss_end__ = . ;
  }
  .edata BLOCK(__section_alignment__) : { *(.edata) }
  .idata BLOCK(__section_alignment__) :
  {
    SORT(*)(.idata$2)
    SORT(*)(.idata$3)
    /* These zeroes mark the end of the import list.  */
    LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
    SORT(*)(.idata$4)
    SORT(*)(.idata$5)
    SORT(*)(.idata$6)
    SORT(*)(.idata$7)
  }
  .CRT BLOCK(__section_alignment__) :
  {
    ___crt_xc_start__ = . ;
    *(SORT(.CRT$XC*))  /* C initialization */
    ___crt_xc_end__ = . ;
    ___crt_xi_start__ = . ;
    *(SORT(.CRT$XI*))  /* C++ initialization */
    ___crt_xi_end__ = . ;
    ___crt_xl_start__ = . ;
    *(SORT(.CRT$XL*))  /* TLS callbacks */
    /* ___crt_xl_end__ is defined in the TLS Directory support code */
    PROVIDE (___crt_xl_end__ = .);
    ___crt_xp_start__ = . ;
    *(SORT(.CRT$XP*))  /* Pre-termination */
    ___crt_xp_end__ = . ;
    ___crt_xt_start__ = . ;
    *(SORT(.CRT$XT*))  /* Termination */
    ___crt_xt_end__ = . ;
  }
  .tls BLOCK(__section_alignment__) :
  {
    ___tls_start__ = . ;
    *(.tls .tls.*)
    *(.tls$)
    *(SORT(.tls$*))
    ___tls_end__ = . ;
  }
  .rsrc BLOCK(__section_alignment__) :
  {
    *(.rsrc)
    *(SORT(.rsrc$*))
  }
  .reloc BLOCK(__section_alignment__) : { *(.reloc) }
  .stab BLOCK(__section_alignment__) (NOLOAD) : { *(.stab) }
  .stabstr BLOCK(__section_alignment__) (NOLOAD) : { *(.stabstr) }
  .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }
  .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }
  .debug_info BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_info) *(.gnu.linkonce.wi.*) }
  .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
  .debug_line BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_line) }
  .debug_frame BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_frame) }
  .debug_str BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_str) }
  .debug_loc BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_loc) }
  .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
  .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_weaknames) }
  .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_funcnames) }
  .debug_typenames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_typenames) }
  .debug_varnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_varnames) }
  .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }
}

TYDQ

  • New Member
  • *
  • Posts: 48
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #8 on: April 16, 2024, 04:05:34 pm »
My assumption is that it is caused by ld using some default linker script which does not link correctly. Also the default ld might not have proper PECOFF support?

The following linker command works with your code
Code: [Select]
x86_64-w64-mingw32-ld --gc-sections --oformat pei-x86-64 uefimain.o uefi.o system.o -e efi_main -o MAIN.EFI link.lds

Together with this link.lds file. It was generated with fpc for the files I sent previously by supplying -sh on the command line to emit a script to use an external linker. Note, this fails too when using the standard linux binutils ld
Code: [Select]
OUTPUT_FORMAT(pei-x86-64)
ENTRY(efi_main)
SECTIONS
{
  . = SIZEOF_HEADERS;
  . = ALIGN(__section_alignment__);
  .text  __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :
  {
    __text_start__ = . ;
    *(.init)
    *(.text .stub .text.* .gnu.linkonce.t.*)
    *(SORT(.text$*))
    *(.glue_7t)
    *(.glue_7)
    . = ALIGN(8);
     ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
    LONG (-1);
    LONG (-1);
    *(.ctors); *(.ctor); *(SORT(.ctors.*));  LONG (0);
    LONG (0);
     ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
    LONG (-1);
    LONG (-1);
    *(.dtors); *(.dtor); *(SORT(.dtors.*));  LONG (0);
    LONG (0);
     *(.fini)
    PROVIDE (etext = .);
    *(.gcc_except_table)
  }
  .data BLOCK(__section_alignment__) :
  {
    __data_start__ = . ;
    *(.data .data.* .gnu.linkonce.d.* .fpc*)
    *(.data2)
    *(SORT(.data$*))
    *(.jcr)
    PROVIDE (_tls_index = .);
    LONG (0);
    __data_end__ = . ;
    *(.data_cygwin_nocopy)
  }
  .rdata BLOCK(__section_alignment__) :
  {
    *(.rdata)
    *(.rdata.*)
    *(.rodata .rodata.* .gnu.linkonce.r.*)
    *(SORT(.rdata$*))
    *(.eh_frame)
    ___RUNTIME_PSEUDO_RELOC_LIST__ = .;
    __RUNTIME_PSEUDO_RELOC_LIST__ = .;
    *(.rdata_runtime_pseudo_reloc)
    ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
    __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
  }
  .pdata BLOCK(__section_alignment__) : { *(.pdata) }
  .bss BLOCK(__section_alignment__) :
  {
    __bss_start__ = . ;
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(SORT(.bss$*))
    *(COMMON)
    __bss_end__ = . ;
  }
  .edata BLOCK(__section_alignment__) : { *(.edata) }
  .idata BLOCK(__section_alignment__) :
  {
    SORT(*)(.idata$2)
    SORT(*)(.idata$3)
    /* These zeroes mark the end of the import list.  */
    LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
    SORT(*)(.idata$4)
    SORT(*)(.idata$5)
    SORT(*)(.idata$6)
    SORT(*)(.idata$7)
  }
  .CRT BLOCK(__section_alignment__) :
  {
    ___crt_xc_start__ = . ;
    *(SORT(.CRT$XC*))  /* C initialization */
    ___crt_xc_end__ = . ;
    ___crt_xi_start__ = . ;
    *(SORT(.CRT$XI*))  /* C++ initialization */
    ___crt_xi_end__ = . ;
    ___crt_xl_start__ = . ;
    *(SORT(.CRT$XL*))  /* TLS callbacks */
    /* ___crt_xl_end__ is defined in the TLS Directory support code */
    PROVIDE (___crt_xl_end__ = .);
    ___crt_xp_start__ = . ;
    *(SORT(.CRT$XP*))  /* Pre-termination */
    ___crt_xp_end__ = . ;
    ___crt_xt_start__ = . ;
    *(SORT(.CRT$XT*))  /* Termination */
    ___crt_xt_end__ = . ;
  }
  .tls BLOCK(__section_alignment__) :
  {
    ___tls_start__ = . ;
    *(.tls .tls.*)
    *(.tls$)
    *(SORT(.tls$*))
    ___tls_end__ = . ;
  }
  .rsrc BLOCK(__section_alignment__) :
  {
    *(.rsrc)
    *(SORT(.rsrc$*))
  }
  .reloc BLOCK(__section_alignment__) : { *(.reloc) }
  .stab BLOCK(__section_alignment__) (NOLOAD) : { *(.stab) }
  .stabstr BLOCK(__section_alignment__) (NOLOAD) : { *(.stabstr) }
  .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }
  .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }
  .debug_info BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_info) *(.gnu.linkonce.wi.*) }
  .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
  .debug_line BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_line) }
  .debug_frame BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_frame) }
  .debug_str BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_str) }
  .debug_loc BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_loc) }
  .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
  .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_weaknames) }
  .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_funcnames) }
  .debug_typenames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_typenames) }
  .debug_varnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_varnames) }
  .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }
}
I got an error:x86_64-w64-mingw32-ld:linker.lds:6: undefined symbol `__section_alignment__' referenced in expression
when I added a -r option to this command,so how to solve it?
« Last Edit: April 16, 2024, 04:32:28 pm by TYDQ »

Laksen

  • Hero Member
  • *****
  • Posts: 758
    • J-Software
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #9 on: April 16, 2024, 04:11:56 pm »
I guess you can find it or something close to in some red hat package somewhere. Not familiar with red hat. Maybe try to check this https://pkgs.org/download/mingw64-binutils

TYDQ

  • New Member
  • *
  • Posts: 48
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #10 on: April 16, 2024, 04:34:09 pm »
I guess you can find it or something close to in some red hat package somewhere. Not familiar with red hat. Maybe try to check this https://pkgs.org/download/mingw64-binutils
I solve the cross-ld problem with zypper,but when execute your command I got the error above your answer.

Laksen

  • Hero Member
  • *****
  • Posts: 758
    • J-Software
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #11 on: April 16, 2024, 04:45:14 pm »
Why did you add the -r?

TYDQ

  • New Member
  • *
  • Posts: 48
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #12 on: April 16, 2024, 04:55:21 pm »
Why did you add the -r?
If I don't add the -r,I will got an error that 0-bit reloc in dll.And It is no guarantee that every object file generated by fpc is relocatable although added -WB

Laksen

  • Hero Member
  • *****
  • Posts: 758
    • J-Software
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #13 on: April 16, 2024, 05:04:13 pm »
I get the error with 0-bit reloc when trying to compile with -shared
When just using "x86_64-w64-mingw32-ld  --gc-sections --oformat pei-x86-64 uefimain.o uefi.o system.o -e efi_main -o MAIN.EFI link.lds" it works fine

Why does it need to be relocatable? As far as I can tell the Win64 code generates position independent code by default, but I'm not an expert on Windows stuff

TYDQ

  • New Member
  • *
  • Posts: 48
Re: Does anyone know why this code cannot show the hello world in uefi?
« Reply #14 on: April 16, 2024, 05:28:59 pm »
I get the error with 0-bit reloc when trying to compile with -shared
When just using "x86_64-w64-mingw32-ld  --gc-sections --oformat pei-x86-64 uefimain.o uefi.o system.o -e efi_main -o MAIN.EFI link.lds" it works fine

Why does it need to be relocatable? As far as I can tell the Win64 code generates position independent code by default, but I'm not an expert on Windows stuff
When I execute the shell code that x86_64-w64-mingw32-ld --gc-sections --oformat pei-x86-64 uefimain.o uefi.o system.o -e efi_main -o main.efi -Tlinker.lds,I got the error that:
x86_64-w64-mingw32-ld: error: 0-bit reloc in dll
uefimain.o:uefimain.pas:(.pdata.n_uefimain_$$_efi_main$pointer$pefi_system_table+0x0): relocation truncated to fit: IMAGE_REL_AMD64_ADDR32NB against `.text.n_uefimain_$$_efi_main$pointer$pefi_system_table'
uefimain.o:uefimain.pas:(.pdata.n_uefimain_$$_efi_main$pointer$pefi_system_table+0x4): relocation truncated to fit: IMAGE_REL_AMD64_ADDR32NB against `.text.n_uefimain_$$_efi_main$pointer$pefi_system_table'
uefimain.o:uefimain.pas:(.pdata.n_uefimain_$$_efi_main$pointer$pefi_system_table+0x8): relocation truncated to fit: IMAGE_REL_AMD64_ADDR32NB against `.xdata.n_uefimain_$$_efi_main$pointer$pefi_system_table'
So how to do to solve these error above,buddy?

 

TinyPortal © 2005-2018