boot-amd64.asm (16789B)
1 .intel_syntax 2 3 .globl EntryPoint 4 5 .equ EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, 10 6 7 .equ IMAGE_MACHINE_x64, 0x8664 8 9 .equ IMAGE_FILE_EXECUTABLE_IMAGE, 0x0002 10 .equ IMAGE_FILE_LARGE_ADDRESS_AWARE, 0x0020 11 .equ IMAGE_FILE_DEBUG_STRIPPED, 0x0200 12 13 .equ PE32PLUS_MAGIC, 0x020b 14 15 .equ IMAGE_SCN_CNT_CODE, 0x00000020 16 .equ IMAGE_SCN_CNT_DATA, 0x00000040 17 .equ IMAGE_SCN_MEM_SHARED, 0x10000000 18 .equ IMAGE_SCN_MEM_EXECUTE, 0x20000000 19 .equ IMAGE_SCN_MEM_READ, 0x40000000 20 .equ IMAGE_SCN_MEM_WRITE, 0x80000000 21 22 .code64 23 24 .section .header, "a", %progbits 25 BEGIN: 26 27 HEADER: 28 29 MSDOS_HDR: 30 MSDOS_HDR.e_magic: .byte 'M', 'Z', 0x00, 0x00 31 .fill 14, 4, 0x00000000 32 MSDOS_HDR.e_lfanew: .int (PE_HDR - MSDOS_HDR) 33 MSDOS_HDR_END: 34 35 MSDOS_STUB: 36 .fill 16, 4, 0x00000000 37 MSDOS_STUB_END: 38 39 PE_HDR: 40 PE_HDR.PEMagic: .byte 'P', 'E', 0x00, 0x00 41 PE_HDR.Machine: .short IMAGE_MACHINE_x64 42 PE_HDR.NumberOfSections: .short 2 43 PE_HDR.TimeDateStamp: .int 1717539955 44 PE_HDR.PointerToSymbolTable: .int 0 45 PE_HDR.NumberOfSymbols: .int 0 46 PE_HDR.SizeOfOptionalHeader: .short (PEOPT_HDR_END - PEOPT_HDR) 47 PE_HDR.Characteristics: .short (IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_LARGE_ADDRESS_AWARE | IMAGE_FILE_EXECUTABLE_IMAGE) 48 PE_HDR_END: 49 50 PEOPT_HDR: 51 PEOPT_HDR.PEOptMagic: .short PE32PLUS_MAGIC 52 PEOPT_HDR.MajorLinkerVersion: .byte 0 53 PEOPT_HDR.MinorLinkerVersion: .byte 0 54 PEOPT_HDR.SizeOfCode: .int (CODE_END - CODE) 55 PEOPT_HDR.SizeOfData: .int (DATA_END - DATA) 56 PEOPT_HDR.SizeOfBss: .int 0 57 PEOPT_HDR.AddressOfEntryPoint: .int (EntryPoint - BEGIN) 58 PEOPT_HDR.BaseOfCode: .int (CODE - BEGIN) 59 60 PEOPT_HDR.BaseOfData: /* missing due to 64-bit ImageBase in 64-bit PEs*/ 61 PEOPT_HDR.ImageBase: .quad 0x40000 62 PEOPT_HDR.SectionAlignment: .int 0x1000 63 PEOPT_HDR.FileAlignment: .int 0x1000 64 PEOPT_HDR.MajorOSVersion: .short 0 65 PEOPT_HDR.MinorOSVersion: .short 0 66 PEOPT_HDR.MajorImageVersion: .short 0 67 PEOPT_HDR.MinorImageVersion: .short 0 68 PEOPT_HDR.MajorSubsystemVersion:.short 0 69 PEOPT_HDR.MinorSubsystemVersion:.short 0 70 PEOPT_HDR.Win32VersionValue: .int 0 71 PEOPT_HDR.SizeOfImage: .int (END - BEGIN) 72 PEOPT_HDR.SizeOfHeaders: .int (HEADER_END - HEADER) 73 PEOPT_HDR.Checksum: .int 0 74 PEOPT_HDR.Subsystem: .short EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 75 PEOPT_HDR.DllCharacteristics: .short 0 76 PEOPT_HDR.SizeOfStackReserve: .quad 0x200000 77 PEOPT_HDR.SizeOfStackCommit: .quad 0x1000 78 PEOPT_HDR.SizeOfHeapReserve: .quad 0x200000 79 PEOPT_HDR.SizeOfHeapCommit: .quad 0x1000 80 PEOPT_HDR.LoaderFlags: .int 0 81 PEOPT_HDR.NumberOfRvaAndSizes: .int 0 82 83 PEOPT_HDR_END: 84 85 SECTIONS_HDR: 86 87 SECTION_CODE: 88 SECTION_CODE.Name: .byte '.', 't', 'e', 'x', 't', 0x00, 0x00, 0x00 89 SECTION_CODE.VirtualSize: .int (CODE_END - CODE) 90 SECTION_CODE.VirtualAddress: .int (CODE - BEGIN) 91 SECTION_CODE.SizeOfRawData: .int (CODE_END - CODE) 92 SECTION_CODE.PointerToRawData: .int (CODE - BEGIN) 93 SECTION_CODE.PointerToRelocs: .int 0 94 SECTION_CODE.PointerToLineNums: .int 0 95 SECTION_CODE.NumberOfRelocs: .short 0 96 SECTION_CODE.NumberOfLineNums: .short 0 97 SECTION_CODE.Characteristics: .int (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ) 98 99 SECTION_DATA: 100 SECTION_DATA.Name: .byte '.', 'd', 'a', 't', 'a', 0x00, 0x00, 0x00 101 SECTION_DATA.VirtualSize: .int (DATA_END - DATA) 102 SECTION_DATA.VirtualAddress: .int (DATA - BEGIN) 103 SECTION_DATA.SizeOfRawData: .int (DATA_END - DATA) 104 SECTION_DATA.PointerToRawData: .int (DATA - BEGIN) 105 SECTION_DATA.PointerToRelocs: .int 0 106 SECTION_DATA.PointerToLineNums: .int 0 107 SECTION_DATA.NumberOfRelocs: .short 0 108 SECTION_DATA.NumberOfLineNums: .short 0 109 SECTION_DATA.Characteristics: .int (IMAGE_SCN_CNT_DATA | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE) 110 111 SECTIONS_HDR_END: 112 113 HEADER_END: 114 115 .align 16 116 .section .text, "ax", %progbits 117 118 CODE: 119 120 .equ EFI_SUCCESS, 0 121 122 .equ EFI_ERROR, 0x8000000000000000 123 .equ EFI_LOAD_ERROR, 1 124 .equ EFI_INVALID_PARAMETER, 2 125 .equ EFI_UNSUPPORTED, 3 126 .equ EFI_BUFFER_TOO_SMALL, 4 127 .equ EFI_NOT_FOUND, 14 128 129 .equ EFI_WARNING, 0x0000000000000000 130 131 /* typedef void *EFI_HANDLE; 132 * typedef EFI_HANDLE EFI_IMAGE_HANDLE; 133 * 134 * typedef struct { 135 * u64 Signature; 136 * u32 Revision; 137 * u32 HeaderSize; 138 * u32 CRC32; 139 * u32 Reserved; 140 * } EFI_TABLE_HEADER; 141 */ 142 .equ EFI_TABLE_HEADER_SZ, 24 143 144 /* typedef struct { 145 * EFI_GUID VendorGuid; 146 * void *VendorTable; 147 * } EFI_CONFIGURATION_TABLE; 148 * 149 * typedef struct { 150 * EFI_TABLE_HEADER Hdr; 151 * c16 *FirmwareVendor; 152 * u32 FirmwareRevision; 153 * EFI_HANDLE ConsoleInHandle; 154 * EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; 155 * EFI_HANDLE ConsoleOutHandle; 156 * EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; 157 * EFI_HANDLE StandardErrorHandle; 158 * EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr; 159 * EFI_RUNTIME_SERVICES *RuntimeServices; 160 * EFI_BOOT_SERVICES *BootServices; 161 * umm NumberOfTableEntries; 162 * EFI_CONFIGURATION_TABLE *ConfigurationTable; 163 * } EFI_SYSTEM_TABLE; 164 */ 165 .equ EFI_SYSTEM_TABLE_CON_IN, (EFI_TABLE_HEADER_SZ + 24) 166 .equ EFI_SYSTEM_TABLE_CON_OUT, (EFI_TABLE_HEADER_SZ + 40) 167 .equ EFI_SYSTEM_TABLE_STD_ERR, (EFI_TABLE_HEADER_SZ + 56) 168 .equ EFI_SYSTEM_TABLE_RUNTIME_SERVICES, (EFI_TABLE_HEADER_SZ + 64) 169 .equ EFI_SYSTEM_TABLE_BOOT_SERVICES, (EFI_TABLE_HEADER_SZ + 72) 170 .equ EFI_SYSTEM_TABLE_NUBER_OF_TABLE_ENTS, (EFI_TABLE_HEADER_SZ + 80) 171 .equ EFI_SYSTEM_TABLE_CONFIGURATION_TABLE, (EFI_TABLE_HEADER_SZ + 88) 172 173 /* typedef struct { 174 * EFI_INPUT_RESET Reset; 175 * EFI_INPUT_READ_KEY ReadKeyStroke; 176 * EFI_EVENT WaitForKey; 177 * } EFI_SIMPLE_TEXT_INPUT_PROTOCOL; 178 * 179 * typedef struct { 180 * s32 MaxMode; 181 * 182 * s32 Mode; 183 * s32 Attribute; 184 * s32 CursorColumn; 185 * s32 CursorRow; 186 * b8 CursorVisible; 187 * } SIMPLE_TEXT_OUTPUT_MODE; 188 * 189 * typedef struct { 190 * EFI_TEXT_RESET Reset; 191 * EFI_TEXT_STRING OutputString; 192 * EFI_TEXT_TEST_STRING TestString; 193 * EFI_TEXT_QUERY_MODE QueryMode; 194 * EFI_TEXT_SET_MODE SetMode; 195 * EFI_TEXT_SET_ATTRIBUTE SetAttribute; 196 * EFI_TEXT_CLEAR_SCREEN ClearScreen; 197 * EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition; 198 * EFI_TEXT_ENABLE_CURSOR EnableCursor; 199 * SIMPLE_TEXT_OUTPUT_MODE *Mode; 200 * } EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; 201 */ 202 .equ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_RESET, 0 203 .equ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUT_STRING, 8 204 .equ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_SET_ATTRIBUTE, 40 205 .equ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_CLEAR_SCREEN, 48 206 207 .equ EFI_FG_WHITE, 0x0F 208 209 .equ EFI_BG_BLACK, 0x00 210 .equ EFI_BG_RED, 0x40 211 212 /* typedef struct { 213 * EFI_TABLE_HEADER Hdr; 214 * 215 * EFI_GET_TIME GetTime; 216 * EFI_SET_TIME SetTime; 217 * EFI_GET_WAKEUP_TIME GetWakeupTime; 218 * EFI_SET_WAKEUP_TIME SetWakeupTime; 219 * 220 * EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; 221 * EFI_CONVERT_POINTER ConvertPointer; 222 * 223 * EFI_GET_VARIABLE GetVariable; 224 * EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName; 225 * EFI_SET_VARIABLE SetVariable; 226 * 227 * EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHightMonotonicCount; 228 * EFI_RESET_SYSTEM ResetSystem; 229 * 230 * // UEFI 2.0+ specified fields 231 * } EFI_RUNTIME_SERVICES; 232 */ 233 .equ EFI_RUNTIME_SERVICES_RESET_SYSTEM, (EFI_TABLE_HEADER_SZ + 80) 234 235 .equ EFI_RESET_COLD, 0 236 .equ EFI_RESET_WARM, 1 237 .equ EFI_RESET_SHUTDOWN, 2 238 .equ EFI_RESET_PLATFORM_SPECIFIC, 3 239 240 /* typedef struct { 241 * EFI_TABLE_HEADER Hdr; 242 * 243 * EFI_RAISE_TPL RaiseTPL; 244 * EFI_RESTORE_TPL RestoreTPL; 245 * 246 * EFI_ALLOCATE_PAGES AllocatePages; 247 * EFI_FREE_PAGES FreePages; 248 * EFI_GET_MEMORY_MAP GetMemoryMap; 249 * EFI_ALLOCATE_POOL AllocatePool; 250 * EFI_FREE_POOL FreePool; 251 * 252 * EFI_CREATE_EVENT CreateEvent; 253 * EFI_SET_TIMER SetTimer; 254 * EFI_WAIT_FOR_EVENT WaitForEvent; 255 * EFI_SIGNAL_EVENT SignalEvent; 256 * EFI_CLOSE_EVENT CloseEvent; 257 * EFI_CHECK_EVENT CheckEvent; 258 * 259 * EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface; 260 * EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; 261 * EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; 262 * EFI_HANDLE_PROTOCOL HandleProtocol; 263 * void *Reserved; 264 * EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify; 265 * EFI_LOCATE_HANDLE LocateHandle; 266 * EFI_LOCATE_DEVICE_PATH LocateDevicePath; 267 * EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable; 268 * 269 * EFI_IMAGE_LOAD LoadImage; 270 * EFI_IMAGE_START StartImage; 271 * EFI_EXIT Exit; 272 * EFI_IMAGE_UNLOAD UnloadImage; 273 * EFI_EXIT_BOOT_SERVICES ExitBootServices; 274 * 275 * EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; 276 * EFI_STALL Stall; 277 * EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; 278 * 279 * // EFI 1.1+ specified fields 280 * EFI_CONNECT_CONTROLLER ConnectController; 281 * EFI_DISCONNECT_CONTROLLER DisconnectController; 282 * 283 * EFI_OPEN_PROTOCOL OpenProtocol; 284 * EFI_CLOSE_PROTOCOL CloseProtocol; 285 * EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation; 286 * 287 * EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle; 288 * EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer; 289 * EFI_LOCATE_PROTOCOL LocateProtocol; 290 * EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces; 291 * EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces; 292 * 293 * EFI_CALCULATE_CRC32 CalculateCRC32; 294 * 295 * EFI_COPY_MEM CopyMem; 296 * EFI_SET_MEM SetMem; 297 * 298 * // UEFI 2.0+ specified fields 299 * } EFI_BOOT_SERVICES; 300 */ 301 .equ EFI_BOOT_SERVICES_GET_MEMORY_MAP, (EFI_TABLE_HEADER_SZ + 40) 302 .equ EFI_BOOT_SERVICES_EXIT, (EFI_TABLE_HEADER_SZ + 192) 303 .equ EFI_BOOT_SERVICES_EXIT_BOOT_SERVICES, (EFI_TABLE_HEADER_SZ + 208) 304 .equ EFI_BOOT_SERVICES_STALL, (EFI_TABLE_HEADER_SZ + 224) 305 .equ EFI_BOOT_SERVICES_LOCATE_PROTOCOL, (EFI_TABLE_HEADER_SZ + 296) 306 307 .equ MICROS, 1000000 308 309 /* we get called with the following state: 310 * rcx: EFI_HANDLE 311 * rdx: EFI_SYSTEM_TABLE * 312 * rsp: 8 byte offset, <retaddr> 313 * 314 * NOTE: UEFI requires a 16-byte aligned stack, and due to the return address 315 * being passed on the stack, we have an 8-byte offset. UEFI also expects 316 * a 32-byte shadow space to allow pushing all 4 potential arg registers. 317 */ 318 EntryPoint: 319 320 /* NOTE: fix up the stack due to the following rules: 321 * sub rsp, (a + b*8) 322 * - a : realign stack pointer to 16-bytes, accounting for the passed retaddr 323 * - b : we need to reserve shadow space for preserved registers 324 */ 325 sub rsp, (8 + 8*8) 326 327 mov rax, [rdx + EFI_SYSTEM_TABLE_CON_OUT] 328 mov rax, [rax + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_RESET] 329 mov rcx, [rdx + EFI_SYSTEM_TABLE_CON_OUT] 330 xor rdx, rdx 331 call rax 332 333 mov rax, [rdx + EFI_SYSTEM_TABLE_CON_OUT] 334 mov rax, [rax + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUT_STRING] 335 mov rcx, [rdx + EFI_SYSTEM_TABLE_CON_OUT] 336 lea rdx, [MSG_LOAD_KERNEL] 337 call rax 338 339 wait: 340 jmp wait 341 342 add rsp, (8 + 8*8) 343 ret 344 345 mov EFI_IMAGE_HANDLE, rcx 346 mov EFI_SYSTEM_TABLE, rdx 347 348 mov rax, [rdx + EFI_SYSTEM_TABLE_CON_OUT] 349 mov EFI_STDOUT, rax 350 351 mov rax, [rdx + EFI_SYSTEM_TABLE_RUNTIME_SERVICES] 352 mov EFI_RUNTIME_SERVICES, rax 353 354 mov rax, [rdx + EFI_SYSTEM_TABLE_BOOT_SERVICES] 355 mov EFI_BOOT_SERVICES, rax 356 357 mov rax, [rdx + EFI_SYSTEM_TABLE_CONFIGURATION_TABLE] 358 mov EFI_CONFIGURATION_TABLE, rax 359 360 jmp load_kernel 361 362 get_memory_map: 363 /* typedef struct { 364 * u32 Type; 365 * EFI_PHYSICAL_ADDRESS PhysicalStart; 366 * EFI_VIRTUAL_ADDRESS VirtualStart; 367 * u64 NumberOfPages; 368 * u64 Attribute; 369 * } EFI_MEMORY_DESCRIPTOR; 370 * 371 * typedef EFI_STATUS (EFIAPI *EFI_GET_MEMORY_MAP) ( 372 * IN OUT umm *MemoryMapSize, 373 * OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, 374 * OUT umm *MapKey, 375 * OUT umm *DescriptorSize, 376 * OUT u32 *DescriptorVersion 377 * ); 378 */ 379 lea rcx, MEMORY_MAP_SIZE 380 lea rdx, MEMORY_MAP 381 lea r8, MEMORY_MAP_KEY 382 lea r9, MEMORY_DESCRIPTOR_SIZE 383 lea rax, MEMORY_DESCRIPTOR_VERSION 384 mov [rsp+32], rax 385 mov rax, EFI_BOOT_SERVICES 386 call [rax + EFI_BOOT_SERVICES_GET_MEMORY_MAP] 387 cmp al, EFI_BUFFER_TOO_SMALL /* correct buffer size returned in [MEMORY_MAP_SIZE] */ 388 je get_memory_map 389 390 cmp rax, EFI_SUCCESS 391 jne failure 392 393 /* typedef EFI_STATUS (EFIAPI *EFI_EXIT_BOOT_SERVICES) ( 394 * IN EFI_HANDLE ImageHandle, 395 * IN umm MapKey 396 * ); 397 */ 398 mov rcx, EFI_IMAGE_HANDLE 399 mov rdx, MEMORY_MAP_KEY 400 mov rax, EFI_BOOT_SERVICES 401 call [rax + EFI_BOOT_SERVICES_EXIT_BOOT_SERVICES] 402 cmp rax, EFI_SUCCESS /* was our memory map key invalid? */ 403 jne get_memory_map 404 405 load_kernel: 406 407 /* typedef EFI_STATUS (EFIAPI *EFI_TEXT_RESET) ( 408 * IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 409 * IN b8 ExtendedVerification 410 * ); 411 */ 412 mov rcx, EFI_STDOUT 413 mov rdx, 1 414 call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_RESET] 415 cmp rax, EFI_SUCCESS 416 jne failure 417 418 /* typedef EFI_STATUS (EFIAPI *EFI_TEXT_SET_ATTRIBUTE) ( 419 * IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 420 * IN umm Attribute 421 * ); 422 */ 423 mov rcx, EFI_STDOUT 424 mov rdx, EFI_FG_WHITE | EFI_BG_BLACK 425 call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_SET_ATTRIBUTE] 426 cmp rax, EFI_SUCCESS 427 jne failure 428 429 /* typedef EFI_STATUS (EFIAPI *EFI_TEXT_OUTPUT_CLEAR_SCREEN) ( 430 * IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This 431 * ); 432 */ 433 mov rcx, EFI_STDOUT 434 call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_CLEAR_SCREEN] 435 cmp rax, EFI_SUCCESS 436 jne failure 437 438 /* typedef EFI_STATUS (EFIAPI *EFI_TEXT_OUTPUT_STRING) ( 439 * IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 440 * IN c16 *String 441 * ); 442 */ 443 mov rcx, EFI_STDOUT 444 lea rdx, MSG_LOAD_KERNEL 445 call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUT_STRING] 446 cmp rax, EFI_SUCCESS 447 jne failure 448 449 /* typedef EFI_STATUS (EFIAPI *EFI_STALL) ( 450 * IN umm Microseconds 451 * ); 452 */ 453 mov rcx, 10 * MICROS 454 mov rax, [EFI_BOOT_SERVICES] 455 call [rax + EFI_BOOT_SERVICES_STALL] 456 457 /* TODO: enable efi framebuffer for drawing */ 458 459 /* typedef EFI_STATUS (EFIAPI *EFI_RESET_SYSTEM) ( 460 * IN EFI_RESET_TYPE ResetType, 461 * IN EFI_STATUS ExitStatus, 462 * IN umm DataSize, 463 * IN c16 *ResetData OPTIONAL 464 * ); 465 */ 466 mov rcx, EFI_RESET_SHUTDOWN 467 mov rdx, EFI_SUCCESS 468 mov r8, 0 469 mov r9, 0 470 mov rax, [EFI_RUNTIME_SERVICES] 471 call [rax + EFI_RUNTIME_SERVICES_RESET_SYSTEM] 472 473 /* EFI_RESET_SYSTEM does not return */ 474 475 mov rax, EFI_SUCCESS 476 jmp exit 477 478 failure: 479 mov rcx, [EFI_STDOUT] 480 lea rdx, [MSG_FAILURE] 481 call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUT_STRING] 482 483 /* typedef EFI_STATUS (EFIAPI *EFI_EXIT) ( 484 * IN EFI_HANDLE ImageHandle, 485 * IN EFI_STATUS ExitStatus, 486 * IN umm ExitDataSize, 487 * IN c16 *ExitData OPTIONAL 488 * ); 489 */ 490 mov rcx, [EFI_IMAGE_HANDLE] 491 mov rdx, EFI_ERROR | EFI_LOAD_ERROR 492 mov r8, 0 493 mov r9, 0 494 mov rax, [EFI_BOOT_SERVICES] 495 call [rax + EFI_BOOT_SERVICES_EXIT] 496 497 /* EFI_EXIT does not return */ 498 499 mov rax, EFI_ERROR | EFI_LOAD_ERROR 500 jmp exit 501 502 exit: 503 add rsp, (8 + 8*8) /* undo UEFI stack constraints */ 504 retn 505 506 CODE_END: 507 508 .align 4096 509 .section .data, "aw", %progbits 510 511 DATA: 512 513 MSG_LOAD_KERNEL: .short 'U', 'E', 'F', 'I', 13, 10, 0 514 515 .align 16 516 EFI_IMAGE_HANDLE: .quad 0 517 EFI_SYSTEM_TABLE: .quad 0 518 519 EFI_STDOUT: .quad 0 520 521 EFI_RUNTIME_SERVICES: .quad 0 522 EFI_BOOT_SERVICES: .quad 0 523 EFI_CONFIGURATION_TABLE: .quad 0 524 525 MEMORY_MAP_SIZE: .quad (32 * 1024) /* initially requested memory map buffer size */ 526 MEMORY_MAP: .quad 0x200000 /* address at which to place the memory map */ 527 MEMORY_MAP_KEY: .quad 0 528 MEMORY_DESCRIPTOR_SIZE: .quad 0 529 MEMORY_DESCRIPTOR_VERSION: .quad 0 530 531 /* all strings are in unicode */ 532 .align 16 533 MSG_FAILURE: .short 'F', 'A', 'I', 'L', 13, 10, 0 534 535 /* 536 .align 16 537 MSG_LOAD_KERNEL: .short 'U', 'E', 'F', 'I', 13, 10, 0 538 */ 539 540 DATA_END: 541 542 .align 4096 543 PAYLOAD: 544 545 PAYLOAD_END: 546 547 END: