Recent

Author Topic: Strange Question that why I cannot pass the parameter to the loaded elf files  (Read 549 times)

TYDQ

  • Full Member
  • ***
  • Posts: 102
I was successfully loaded kernel elf file to the memory with these code:
Code: Pascal  [Select][+][-]
  1. library uefiloader;
  2.  
  3. {$MODE FPC}
  4.  
  5. uses uefi,tydqfs,binarybase,bootconfig;
  6.  
  7. var proccontent:array[1..67108864] of byte;
  8.     procsize:dword;
  9.  
  10. function efi_main(ImageHandle:efi_handle;systemtable:Pefi_system_table):efi_status;cdecl;[public,alias:'_DLLMainCRTStartup'];
  11. var fsi:tydqfs_system_info;
  12.     edl:efi_disk_list;
  13.     sfsp:Pefi_simple_file_system_protocol;
  14.     fp:Pefi_file_protocol;
  15.     efsl:efi_file_system_list;
  16.     i,count:natuint;
  17.     status:efi_status;
  18.     finfo:efi_file_info;
  19.     finfosize:natuint;
  20.     procsize:natuint;
  21.     partstr:PWideChar;
  22.     gpl:efi_graphics_list;
  23.     isgraphics:boolean;
  24.     framebufferbase:qword;
  25.     framebufferwidth:dword;
  26.     framebufferheight:dword;
  27.     screenconfig:screen_config;
  28.     {For elf structure}
  29.     header:elf64_header;
  30.     program_headers:^elf64_program_header;
  31.     LowAddress,HighAddress:qword;
  32.     PageCount:qword;
  33.     KernelRelocateBase,RelocateOffset:qword;
  34.     ZeroStart:^qword;
  35.     SourceStart,DestStart:^byte;
  36.     KernelEntry:Pointer;
  37.     bool:array[1..4] of boolean;
  38.     {For loading elf files}
  39.     initparam:Psys_parameter_item;
  40.     param:sys_parameter;
  41.     func:sys_parameter_function;
  42.     funcaddr:sys_function;
  43.     procaddr:sys_procedure;
  44.     funcandparam:sys_parameter_function_and_parameter;
  45.     res:Pointer;
  46. begin
  47.  compheap_initialize; sysheap_initialize;
  48.  efi_console_initialize(systemtable,efi_bck_black,efi_lightgrey,500);
  49.  edl:=efi_disk_tydq_get_fs_list(systemtable);
  50.  fsi:=tydq_fs_systeminfo_read(edl);
  51.  freemem(edl.disk_block_content); freemem(edl.disk_content); edl.disk_count:=0;
  52.  efsl:=efi_list_all_file_system(systemtable,0);
  53.  i:=1; count:=efsl.file_system_count;
  54.  gpl:=efi_graphics_initialize(systemtable);
  55.  efi_graphics_get_maxwidth_maxheight_and_maxdepth(gpl,1);
  56.  while(i<=count) do
  57.   begin
  58.    sfsp:=(efsl.file_system_content+i-1)^;
  59.    sfsp^.OpenVolume(sfsp,fp);
  60.    fp^.Open(fp,fp,'\EFI\SYSTEM\kernelmain.elf',efi_file_mode_read,efi_file_system);
  61.    fp^.SetPosition(fp,0);
  62.    finfosize:=sizeof(efi_file_info);
  63.    fp^.GetInfo(fp,@efi_file_info_id,finfosize,finfo);
  64.    procsize:=finfo.filesize;
  65.    status:=fp^.efiRead(fp,procsize,proccontent);
  66.    if(status=efi_success) then break;
  67.   end;
  68.  if(i>count) then
  69.   begin
  70.    efi_console_output_string(systemtable,'Boot failed,the kernel does not exist.'#10);
  71.    while(True) do;
  72.   end;
  73.  screenconfig.screen_is_graphics:=fsi.header.tydqgraphics;
  74.  screenconfig.screen_address:=(gpl.graphics_item^)^.Mode^.FrameBufferBase;
  75.  screenconfig.screen_width:=(gpl.graphics_item^)^.Mode^.Info^.HorizontalResolution;
  76.  screenconfig.screen_height:=(gpl.graphics_item^)^.Mode^.Info^.VerticalResolution;
  77.  freemem(gpl.graphics_item); gpl.graphics_count:=0;
  78.  freemem(efsl.file_system_content); efsl.file_system_count:=0;
  79.  bool[1]:=Pelf64_header(@proccontent)^.elf64_identify[1]=Byte(#$7F);
  80.  bool[2]:=Pelf64_header(@proccontent)^.elf64_identify[2]=Byte('E');
  81.  bool[3]:=Pelf64_header(@proccontent)^.elf64_identify[3]=Byte('L');
  82.  bool[4]:=Pelf64_header(@proccontent)^.elf64_identify[4]=Byte('F');
  83.  if not(bool[1] and bool[2] and bool[3] and bool[4]) then
  84.   begin
  85.    efi_console_output_string(systemtable,'Boot failed,the kernel is not the elf format file.'#10);
  86.    while(True) do;
  87.   end;
  88.  bool[1]:=Pelf64_header(@proccontent)^.elf64_identify[5]=Byte(#$2);
  89.  if(bool[1]=false) then
  90.   begin
  91.    efi_console_output_string(systemtable,'Boot failed,the kernel is not the elf 64-bit format file.'#10);
  92.    while(True) do;
  93.   end;
  94.  {Load the elf kernel}
  95.  header:=Pelf64_header(@proccontent)^;
  96.  program_headers:=allocmem(sizeof(elf64_program_header)*header.elf64_program_header_number);
  97.  LowAddress:=$FFFFFFFFFFFFFFFF; HighAddress:=0;
  98.  for i:=1 to header.elf64_program_header_number do
  99.   begin
  100.    (program_headers+i-1)^:=Pelf64_program_header(@proccontent+header.elf64_program_header_offset+sizeof(elf64_program_header)*(i-1))^;
  101.    if((program_headers+i-1)^.program_type=elf_program_table_load) then
  102.     begin
  103.      if(LowAddress>(program_headers+i-1)^.program_physical_address) then
  104.       begin
  105.        LowAddress:=(program_headers+i-1)^.program_physical_address;
  106.       end;
  107.      if(HighAddress<(program_headers+i-1)^.program_physical_address+(program_headers+i-1)^.program_memory_size) then
  108.       begin
  109.        HighAddress:=(program_headers+i-1)^.program_physical_address+(program_headers+i-1)^.program_memory_size;
  110.       end;
  111.     end;
  112.   end;
  113.  PageCount:=(HighAddress-LowAddress+4095) div 4096;
  114.  status:=SystemTable^.BootServices^.AllocatePages(AllocateAnyPages,efiLoaderCode,PageCount,KernelRelocateBase);
  115.  RelocateOffset:=kernelRelocateBase-LowAddress;
  116.  Zerostart:=Pqword(KernelRelocateBase);
  117.  for i:=1 to PageCount shl 9 do
  118.   begin
  119.    (Zerostart+i-1)^:=$0000000000000000;
  120.   end;
  121.  for i:=1 to header.elf64_program_header_number do
  122.   begin
  123.    if((program_headers+i-1)^.program_type=elf_program_table_load) then
  124.     begin
  125.      SourceStart:=Pointer(@proccontent+(program_headers+i-1)^.program_offset);
  126.      DestStart:=Pointer((program_headers+i-1)^.program_virtual_address+RelocateOffset);
  127.      Move(DestStart^,SourceStart^,(program_headers+i-1)^.program_file_size);
  128.     end;
  129.   end;
  130.  KernelEntry:=Pointer(header.elf64_entry+RelocateOffset);
  131.  {Load ended}
  132.  initparam:=allocmem(sizeof(sys_parameter_item));
  133.  initparam^.item_content:=@screenconfig;
  134.  initparam^.item_size:=sizeof(screen_config);
  135.  param:=sys_parameter_construct(initparam,1);
  136.  funcaddr:=sys_function(KernelEntry);
  137.  efi_console_output_String(systemtable,'S1'#10);
  138.  func.func:=funcaddr;
  139.  efi_console_output_String(systemtable,'S2'#10);
  140.  funcandparam:=sys_parameter_and_function_construct(param,func,sizeof(qword));
  141.  efi_console_output_String(systemtable,'S3'#10);
  142.  res:=sys_parameter_function_execute(funcandparam);
  143.  efi_console_output_String(systemtable,'S4'#10);
  144.  partstr:=UintToPWChar(Pqword(res)^);
  145.  efi_console_output_string(systemtable,partstr);
  146.  Wstrfree(partstr);
  147.  efi_console_output_String(systemtable,'S5'#10);
  148.  freemem(res);
  149.  efi_console_output_String(systemtable,'S6'#10);
  150.  sys_parameter_and_function_free(funcandparam);
  151.  efi_console_output_String(systemtable,'S7'#10);
  152.  freemem(initparam);
  153.  efi_console_output_String(systemtable,'S8'#10);
  154.  while True do;
  155.  efi_main:=efi_success;
  156. end;
  157.  
  158. end.
And these are the content of kernelmain.pas(My kernel for test):
Code: Pascal  [Select][+][-]
  1. program kernelmain;
  2.  
  3. uses bootconfig,graphics;
  4.  
  5. function kernel_main(param:sys_parameter):Pointer;[public,alias:'_start'];
  6. var screenconfig:screen_config;
  7.     ptr:Pgraphics_item;
  8.     res:Pqword;
  9. begin
  10.  screenconfig:=Pscreen_config(param.param_content)^;
  11.  graphics_heap_initialize;
  12.  ptr:=graphics_heap_getmem(1,1,screenconfig.screen_width,screenconfig.screen_height);
  13.  graphics_draw_block(ptr,1,1,screenconfig.screen_width,screenconfig.screen_height,$FF,$FF,$FF,$FF);
  14.  graphics_heap_output_to_screen(screenconfig.screen_address,screenconfig.screen_width,screenconfig.screen_height);
  15.  res:=allocmem(sizeof(qword));
  16.  res^:=screenconfig.screen_width;
  17.  kernel_main:=res;
  18. end;
  19.  
  20. begin
  21. end.
And the rest of the related code is in github https://github.com/TYDQSoft/UEFIPascalOS.
Does anyone know why I cannot pass the parameter(parameter in uefiloader.pas was tested vaild,but the kernel parameter tested that all of them is zero) to the loaded elf file in UEFI bare metal?

TYDQ

  • Full Member
  • ***
  • Posts: 102
Does anyone have the idea about what the error occurs?
I have debugged my kernel,all of the parameter does not transmit properly but I don't where the parameter transmitting error occurs.
« Last Edit: August 04, 2024, 03:56:02 pm by TYDQ »

TYDQ

  • Full Member
  • ***
  • Posts: 102
Does anyone have the plan about where the error occurs?

 

TinyPortal © 2005-2018