Mac on fire
Winter is approaching. Why don't boot your Mac into a a demo showing fire and heating your place?
Status
Status du project | |
---|---|
Date de début | August 2014 |
Status | work in progress |
Initiateur | Magnus |
Description
This project aims at creating a disk image (to use on a USB stick) from which recent Macs can boot. The image will be based on GPT/HFS+ with an EBC boot loader showing a fire demo on the screen.
To Do
- Switching between text and graphcis mode
Material
Participants
<doodle |[maconfire] Interested in joining this project>
participation active | participation passive | suivre de loins |
---|
</doodle>
Log
23/09/2014
Shell script to convert annotated hex file with repetitions into binary:
cat test.hex | perl -pe 's/#.*//;s/([[:xdigit:]]{2})\*(\d+)/"$1 " x $2/e;s/\s+//sg' | xxd -r -p > test.efi
Some input example might look like:
- test.hex
### MZ HEADER ### 4D 5A # magic: "MZ" 00*58 # dummy 40 00 00 00 # address of PE header ### PE HEADER ### 50 45 00 00 # magic: "PE\0\0" BC 0E # machine: efi byte code
10/10/2014
This is booting!!
- hello.hex
# Compile line: # cat hello.hex | perl -pe 's/#.*//;s/([[:xdigit:]]{2})\*(\d+)/"$1 " x $2/e;s/\s+//sg' | xxd -r -p > hello.efi # ###################### ### HEADER (PE32+) ### ###################### ### MZ HEADER ### 4D 5A # magic: "MZ" 00*22 40 00 # TODO: address of DOS stub? somehow needed for "file" command to work 00*34 # dummy 80 00 00 00 # address of PE header 00*64 # dummy DOS stub ### PE HEADER ### 50 45 00 00 # magic: "PE\0\0" BC 0E # machine: efi byte code 01 00 # number of sections (we have only one!) 00 00 00 00 # file creation (TODO...) 00 00 00 00 # symbol table 00 00 00 00 # number of symbols 70 00 # size of optional header 2E 20 # characteristics: executable (TODO...) ### PE OPTIONAL HEADER ### 0B 02 # magic: PE32+ 00 00 # linker version 00 02 00 00 # code size (512 bytes) 00 00 00 00 # data size (initialised, not used, all constant data in code segment) 00 00 00 00 # data size (uninitialised, not used) 00 02 00 00 # entry point 00 02 00 00 # code base address 00 00 00 00 00 00 00 00 # image base address 00 02 00 00 # section alignment (512 byte) 00 02 00 00 # file alignment (512 byte) 00 00 00 00 # OS version (unused) 00 00 00 00 # image version (unused) 0A 00 00 00 # subsystem version: EFI application 00 00 00 00 # Win32 version (unused) 00 04 00 00 # image size (512 byte header, 512 byte code) 00 02 00 00 # header size (512 bytes) 00 00 00 00 # checksum (TODO!) 0A 00 # subsystem (TODO) 40 00 # DLL characteristics: relocatable 00 10 00 00 00 00 00 00 # stack size (reserve): 4k 00 10 00 00 00 00 00 00 # stack size (commit): 4k 00 00 01 00 00 00 00 00 # heap size (reserve): 64k 00 00 00 00 00 00 00 00 # heap size (commit): 0k 00 00 00 00 # loader flags (TODO) 00 00 00 00 # data-directory entries (not needed) ### SECTION TABLE ### 2E 74 65 78 74 00 00 00 # ".text" 00 02 00 00 # virtual size 00 02 00 00 # virtual address 00 02 00 00 # raw size 00 02 00 00 # raw address 00*12 # unused 20 00 00 60 # characteristics: code, readable, executable 00*208 # padding to 512 (TODO: shorter header?) #################### ### CODE (.text) ### #################### ## INIT ## # register usage: # - R1: Code offset (for position independent code) # - R2: &SystemTable # - R3: &BootServices 2A 11 # STORESP R1,IP // R1=0x202 (shouldn't it be 0x200?) (+ real address after loading) 72 82 01 21 # MOVnw R2,@R0(+1,+16) // EFI_SYSTEM_TABLE*SystemTable (16 byte is the stack offset, 1 natural is skipping the first arguemnt (EFI_HANDLE)) 72 A3 89 21 # MOVnw R3,@R2(+9,+24) // EFI_BOOT_SERVICES*BootServices ## SWITCH TO TEXT MODE ## 72 B4 25 36 # MOVnw R4,@R3(+37,+24) // EFI_LOCATE_PROTOCOL*LocateProtocol 35 06 # PUSHn R6 // reserve space for return value on stack 33 06 # MOVnd R6,R0 35 06 # PUSHn R6 // VOID**Interface 16 55 # XOR32 R5,R5 // R5=0 35 05 # PUSHn R5 // VOID*Registration 77 15 FE 00 # MOVIww R5,0xFE // offset to GUID 4C 15 # ADD R5,R1 35 05 # PUSHn R5 // EFI_GUID*Protocol 03 24 # CALLex R4 // LocateProtocol(*Protocol,*Registration,**Interface) #55 55 # NOP //OR R5,R5 36 07 # POPn R7 // restore stack 36 07 # POPn R7 // restore stack 36 07 # POPn R7 // restore stack 36 04 # POPn R4 // VOID*Interface (EFI_CONSOLE_CONTROL_PROTOCOL*) 77 15 00 00 # MOVIww R5,0 // EfiConsoleControlScreenGraphics 35 05 # PUSHn R5 // EFI_CONSOLE_CONTROL_SCREEN_MODE Mode 35 04 # PUSHn R4 // EFI_CONSOLE_CONTROL_PROTOCOL*This 72 C4 01 20 # MOVnw R4,@R4(+1,+0) // SetModeImp 03 24 # CALLex R4 // SetModeImp(*This,Mode); call native code #55 55 # NOP //OR R5,R5 36 07 # POPn R7 // restore stack 36 07 # POPn R7 // restore stack ## PRINT MESSAGE ## 72 A4 85 21 # MOVnw R4,@R2(+5,+24) // EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*ConOut; TODO: why +5,+24 and not +4,+28 ?? - perhaps structure padding... 77 15 0E 01 # MOVIww R5,0x010E // offset to string 4C 15 # ADD R5,R1 35 05 # PUSHn R5 // CHAR16*String 35 04 # PUSHn R4 // EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*This 72 C4 01 20 # MOVnw R4,@R4(+1,+0) // EFI_TEXT_STRING*OutputString 03 24 # CALLex R4 // OutputString(*This,*String); call native code 36 07 # POP R7 // restore stack 36 07 # POP R7 // restore stack #04 00 # 021C: RET 02 FF # JMP -1 // for(;;); 00*170 # Padding to 0x0300 ### DATA (but also in .text) ### # 0300: 82 77 2F F4 2E 01 12 4C 99 56 49 F9 43 04 F7 21 # EFI_CONSOLE_CONTROL_PROTOCOL_GUID: F42F7782-012E-4C12-9956-49F94304F721 # 0310: 4D 00 4D 00 0D 00 0A 00 00 00 # 'MM\r\n\0'
14/10/2014
This one actually shows graphics: but with 2 frames/second… FAIL. Seems that I need to switch to native code to get some decent animation going. Also unclear how to avoid tearing.
- colours.hex
# Compile line: # cat colours.hex | perl -pe 's/#.*//;s/([[:xdigit:]]{2})\*(\d+)/"$1 " x $2/e;s/\s+//sg' | xxd -r -p > colours.efi # ###################### ### HEADER (PE32+) ### ###################### ### MZ HEADER ### 4D 5A # magic: "MZ" 00*22 40 00 # TODO: address of DOS stub? somehow needed for "file" command to work 00*34 # dummy 80 00 00 00 # address of PE header 00*64 # dummy DOS stub ### PE HEADER ### 50 45 00 00 # magic: "PE\0\0" BC 0E # machine: efi byte code 01 00 # number of sections (we have only one!) 00 00 00 00 # file creation (TODO...) 00 00 00 00 # symbol table 00 00 00 00 # number of symbols 70 00 # size of optional header 2E 20 # characteristics: executable (TODO...) ### PE OPTIONAL HEADER ### 0B 02 # magic: PE32+ 00 00 # linker version 00 02 00 00 # code size (512 bytes) 00 00 00 00 # data size (initialised, not used, all constant data in code segment) 00 00 00 00 # data size (uninitialised, not used) 00 02 00 00 # entry point 00 02 00 00 # code base address 00 00 00 00 00 00 00 00 # image base address 00 02 00 00 # section alignment (512 byte) 00 02 00 00 # file alignment (512 byte) 00 00 00 00 # OS version (unused) 00 00 00 00 # image version (unused) 0A 00 00 00 # subsystem version: EFI application 00 00 00 00 # Win32 version (unused) 00 04 00 00 # image size (512 byte header, 512 byte code) 00 02 00 00 # header size (512 bytes) 00 00 00 00 # checksum (TODO!) 0A 00 # subsystem (TODO) 40 00 # DLL characteristics: relocatable 00 00 00 10 00 00 00 00 # stack size (reserve): 16M 00 00 00 10 00 00 00 00 # stack size (commit): 16M 00 00 01 00 00 00 00 00 # heap size (reserve): 64k 00 00 00 00 00 00 00 00 # heap size (commit): 0k 00 00 00 00 # loader flags (TODO) 00 00 00 00 # data-directory entries (not needed) ### SECTION TABLE ### 2E 74 65 78 74 00 00 00 # ".text" 00 02 00 00 # virtual size 00 02 00 00 # virtual address 00 02 00 00 # raw size 00 02 00 00 # raw address 00*12 # unused 20 00 00 60 # characteristics: code, readable, executable 00*208 # padding to 512 (TODO: shorter header?) #################### ### CODE (.text) ### #################### ## INIT ## # register usage: # - R1: Code offset (for position independent code) # - R2: &SystemTable # - R3: &BootServices 2A 11 # STORESP R1,IP // R1=0x202 (shouldn't it be 0x200?) (+ real address after loading) 72 82 01 21 # MOVnw R2,@R0(+1,+16) // EFI_SYSTEM_TABLE*SystemTable (16 byte is the stack offset, 1 natural is skipping the first arguemnt (EFI_HANDLE)) 72 A3 89 21 # MOVnw R3,@R2(+9,+24) // EFI_BOOT_SERVICES*BootServices ## SWITCH TO GRAPHICS MODE ## 72 B4 25 36 # MOVnw R4,@R3(+37,+24) // EFI_LOCATE_PROTOCOL*LocateProtocol 35 06 # PUSHn R6 // reserve space for return value on stack 33 06 # MOVnd R6,R0 35 06 # PUSHn R6 // VOID**Interface 16 55 # XOR32 R5,R5 // R5=0 35 05 # PUSHn R5 // VOID*Registration 77 15 7E 01 # MOVIww R5,0x17E // offset to GUID 4C 15 # ADD R5,R1 35 05 # PUSHn R5 // EFI_GUID*Protocol 03 24 # CALLex R4 // LocateProtocol(*Protocol,*Registration,**Interface) 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // VOID*Interface (EFI_CONSOLE_CONTROL_PROTOCOL*) 77 15 01 00 # MOVIww R5,1 // EfiConsoleControlScreenGraphics 35 05 # PUSHn R5 // EFI_CONSOLE_CONTROL_SCREEN_MODE Mode 35 04 # PUSHn R4 // EFI_CONSOLE_CONTROL_PROTOCOL*This 72 C4 01 20 # MOVnw R4,@R4(+1,+0) // SetModeImp 03 24 # CALLex R4 // SetModeImp(*This,Mode); call native code 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack ## GET GOP MODE & CLEAR SCREEN ## 72 B4 25 36 # MOVnw R4,@R3(+37,+24) // EFI_LOCATE_PROTOCOL*LocateProtocol 35 06 # PUSHn R6 // reserve space for return value on stack 33 06 # MOVnd R6,R0 35 06 # PUSHn R6 // VOID**Interface 16 55 # XOR32 R5,R5 // R5=0 35 05 # PUSHn R5 // VOID*Registration 77 15 8E 01 # MOVIww R5,0x18E // offset to GUID 4C 15 # ADD R5,R1 35 05 # PUSHn R5 // EFI_GUID*Protocol 03 24 # CALLex R4 // LocateProtocol(*Protocol,*Registration,**Interface) 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // VOID*Interface (EFI_GRAPHICS_OUTPUT_PROTOCOL*) 72 C5 03 20 # MOVnw R5,@R4(3,0) // EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE*Mode 6B 04 # PUSH64 R4 // save R4 (EFI_GRAPHICS_OUTPUT_PROTOCOL) 6B 05 # PUSH64 R5 // save R5 (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE) 5F D5 40 20 # MOVdw R5,@R5(0,4) // UINT32 Mode 2B 05 # PUSH32 R5 // UINT32 Mode 35 04 # PUSHn R4 // EFI_GRAPHICS_OUTPUT_PROTOCOL*This 72 C4 01 20 # MOVnw R4,@R4(+1,+0) // SetMode 03 24 # CALLex R4 // SetMode(*This,Mode) 36 04 # POPn R4 // restore stack 2C 04 # POP32 R4 // restore stack 6C 05 # POP64 R5 // restore R5 6C 04 # POP64 R4 // restore R4 72 D6 80 20 # MOVnw R6,@R5(0,8) // EFI_GRAPHICS_OUTPUT_MODE_INFORMATION*Info 5F E7 80 20 # MOVdw R7,@R6(0,8) // UINT32 VerticalResolution 5F E6 40 20 # MOVdw R6,@R6(0,4) // UINT32 HorizontalResolution 28 75 # MOVqq R5,R7 4F 65 # MULU64 R5,R6 4C 55 # ADD R5,R5 4C 55 # ADD R5,R5 6B 04 # PUSH64 R4 6B 06 # PUSH64 R6 6B 07 # PUSH64 R7 35 05 # PUSHn R5 // EFI_PHYSICAL_ADDRESS*Memory (dummy) 77 17 00 10 # MOVIww R7,4096 // PageSize 51 75 # DIVU64 R5,R7 77 17 01 00 # MOVIww R7,1 // possible overflow 4C 75 # ADD R5,R7 35 07 # PUSHn R5 // UINTN Pages 77 17 04 00 # MOVIww R7,4 // EfiBootServicesData 35 07 # PUSHn R7 // EFI_MEMORY_TYPE MemoryType 16 77 # XOR32 R7,R7 // AllocateAnyPages 35 07 # PUSHn R7 // EFI_ALLOCATE_TYPE Type 72 B4 82 21 # MOVnw R4,@R3(+2,+24) // AllocatePages 03 24 # CALLex R4 // AllocatePages(Type,MemoryType,Pages,*Memory) 36 05 # POPn R5 // restore stack 36 05 # POPn R5 // restore stack 36 05 # POPn R5 // restore stack 36 05 # POPn R5 // EFI_PHYSICAL_ADDRESS*Memory 6C 07 # POP64 R7 6C 06 # POP64 R6 6C 04 # POP64 R4 # LOOP Y header 6B 07 # PUSH64 R7 6B 05 # PUSH64 R5 6B 04 # PUSH64 R4 77 14 01 00 # MOVIw R4,1 # LOOP Y body # LOOP X header 6B 06 # PUSH64 R6 # LOOP X body 77 0D 00 00 # MOVIb @R5,0 4C 45 # ADD64 R5,R4 1D 1D # MOVI @R5,R1 4C 45 # ADD64 R5,R4 77 0D FF 00 # MOVIb @R5,0xFF 4C 45 # ADD64 R5,R4 77 0D 00 00 # MOVIb @R5,0 4C 45 # ADD64 R5,R4 # LOOP X trailer 4D 46 # SUB64 R6,R4 6D 06 00 00 # CMP64Ieq R6,0 82 F1 # JMP8cc -15*2 6C 06 # POP64 R6 # LOOP Y trailer 4D 47 # SUB64 R7,R4 6D 07 00 00 # CMP64Ieq R7,0 82 EB # JMP8cc -21*2 4C 41 # ADD64 R1,R4 6C 04 # POP64 R4 6C 05 # POP64 R5 6C 07 # POP64 R7 16 33 # XOR32 R3,R3 // R3=0 35 03 # PUSHn R3 // UINTN Delta (bytes) 35 07 # PUSHn R7 // UINTN Height (pixels) 35 06 # PUSHn R6 // UINTN Width (pixels) 35 03 # PUSHn R3 // UINTN DestinationY 35 03 # PUSHn R3 // UINTN DestinationX 35 03 # PUSHn R3 // UINTN SourceY 35 03 # PUSHn R3 // UINTN SourceX 77 13 02 00 # MOVIww R3,2 // EfiBltBufferToVideo 35 03 # PUSHn R3 // EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation 35 05 # PUSHn R5 // EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer 35 04 # PUSHn R4 // EFI_GRAPHICS_OUTPUT_PROTOCOL *This 72 C4 02 20 # MOVnw R4,@R4(+2,+0) // Blt 03 24 # CALLex R4 // Blt(*This,*BltBuffer,BltOperation,SourceX,SourceY,DestinationX,DestinationY,Width,Height,Delta) 36 04 # POPn R4 // restore stack 36 05 # POPn R5 // restore stack 36 03 # POPn R3 // restore stack 36 03 # POPn R3 // restore stack 36 03 # POPn R3 // restore stack 36 03 # POPn R3 // restore stack 36 03 # POPn R3 // restore stack 36 06 # POPn R6 // restore stack 36 07 # POPn R7 // restore stack 36 03 # POPn R3 // restore stack #04 00 # RET 02 C7 # JMP8 -57*2 00*76 # Padding to 0x0380 ### DATA (but also in .text) ### # 0380: 82 77 2F F4 2E 01 12 4C 99 56 49 F9 43 04 F7 21 # EFI_CONSOLE_CONTROL_PROTOCOL_GUID: F42F7782-012E-4C12-9956-49F94304F721 # 0390: DE A9 42 90 DC 23 38 4A 96 FB 7A DE D0 80 51 6A # EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID: 9042A9DE-23DC-4A38-96FB-7ADED080516A #8B 29 2C 98 FA F4 CB 41 B8 38 77 AA 68 8F B8 39 # EFI_UGA_DRAW_PROTOCOL_GUID: 982C298B-F4FA-41CB-B838-77AA688FB839
18/10/2014
Added native x64 code for PDE. This works both on MacBook Pro and some Mac mini:
- fire.hex
# Compile line: # cat fire.hex | perl -pe 's/#.*//;s/([[:xdigit:]]{2})\*(\d+)/"$1 " x $2/e;s/\s+//sg' | xxd -r -p > fire.efi # ###################### ### HEADER (PE32+) ### ###################### ### MZ HEADER ### 4D 5A # magic: "MZ" 00*22 40 00 # TODO: address of DOS stub? somehow needed for "file" command to work 00*34 # dummy 80 00 00 00 # address of PE header 00*64 # dummy DOS stub ### PE HEADER ### 50 45 00 00 # magic: "PE\0\0" BC 0E # machine: efi byte code 01 00 # number of sections (we have only one!) 00 00 00 00 # file creation (TODO...) 00 00 00 00 # symbol table 00 00 00 00 # number of symbols 70 00 # size of optional header 2E 20 # characteristics: executable (TODO...) ### PE OPTIONAL HEADER ### 0B 02 # magic: PE32+ 00 00 # linker version 00 04 00 00 # code size (2*512 bytes) 00 00 00 00 # data size (initialised, not used, all constant data in code segment) 00 00 00 00 # data size (uninitialised, not used) 00 02 00 00 # entry point 00 02 00 00 # code base address 00 00 00 00 00 00 00 00 # image base address 00 02 00 00 # section alignment (512 byte) 00 02 00 00 # file alignment (512 byte) 00 00 00 00 # OS version (unused) 00 00 00 00 # image version (unused) 0A 00 00 00 # subsystem version: EFI application 00 00 00 00 # Win32 version (unused) 00 06 00 00 # image size (512 byte header, 2*512 byte code) 00 02 00 00 # header size (512 bytes) 00 00 00 00 # checksum (TODO!) 0A 00 # subsystem (TODO) 40 00 # DLL characteristics: relocatable 00 00 00 10 00 00 00 00 # stack size (reserve): 16M 00 00 00 10 00 00 00 00 # stack size (commit): 16M 00 00 01 00 00 00 00 00 # heap size (reserve): 64k 00 00 00 00 00 00 00 00 # heap size (commit): 0k 00 00 00 00 # loader flags (TODO) 00 00 00 00 # data-directory entries (not needed) ### SECTION TABLE ### 2E 74 65 78 74 00 00 00 # ".text" 00 04 00 00 # virtual size 00 02 00 00 # virtual address 00 04 00 00 # raw size 00 02 00 00 # raw address 00*12 # unused 20 00 00 60 # characteristics: code, readable, executable 00*208 # padding to 512 (TODO: shorter header?) #################### ### CODE (.text) ### #################### ## INIT ## # register usage: # - R1: Code offset (for position independent code) # - R2: &SystemTable # - R3: &BootServices 2A 11 # STORESP R1,IP // R1=0x202 (shouldn't it be 0x200?) (+ real address after loading) 72 82 01 21 # MOVnw R2,@R0(+1,+16) // EFI_SYSTEM_TABLE*SystemTable (16 byte is the stack offset, 1 natural is skipping the first arguemnt (EFI_HANDLE)) 72 A3 89 21 # MOVnw R3,@R2(+9,+24) // EFI_BOOT_SERVICES*BootServices ## SWITCH TO GRAPHICS MODE ## 72 B4 25 36 # MOVnw R4,@R3(+37,+24) // EFI_LOCATE_PROTOCOL*LocateProtocol 35 06 # PUSHn R6 // reserve space for return value on stack 33 06 # MOVnd R6,R0 35 06 # PUSHn R6 // VOID**Interface 16 55 # XOR32 R5,R5 // R5=0 35 05 # PUSHn R5 // VOID*Registration 77 15 3E 01 # MOVIww R5,0x13E // offset to GUID 4C 15 # ADD R5,R1 35 05 # PUSHn R5 // EFI_GUID*Protocol 03 24 # CALLex R4 // LocateProtocol(*Protocol,*Registration,**Interface) 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // VOID*Interface (EFI_CONSOLE_CONTROL_PROTOCOL*) 77 15 01 00 # MOVIww R5,1 // EfiConsoleControlScreenGraphics 35 05 # PUSHn R5 // EFI_CONSOLE_CONTROL_SCREEN_MODE Mode 35 04 # PUSHn R4 // EFI_CONSOLE_CONTROL_PROTOCOL*This 72 C4 01 20 # MOVnw R4,@R4(+1,+0) // SetModeImp 03 24 # CALLex R4 // SetModeImp(*This,Mode); call native code 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack ## GET GOP MODE & CLEAR SCREEN ## 72 B4 25 36 # MOVnw R4,@R3(+37,+24) // EFI_LOCATE_PROTOCOL*LocateProtocol 35 06 # PUSHn R6 // reserve space for return value on stack 33 06 # MOVnd R6,R0 35 06 # PUSHn R6 // VOID**Interface 16 55 # XOR32 R5,R5 // R5=0 35 05 # PUSHn R5 // VOID*Registration 77 15 4E 01 # MOVIww R5,0x14E // offset to GUID 4C 15 # ADD R5,R1 35 05 # PUSHn R5 // EFI_GUID*Protocol 03 24 # CALLex R4 // LocateProtocol(*Protocol,*Registration,**Interface) 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // restore stack 36 04 # POPn R4 // VOID*Interface (EFI_GRAPHICS_OUTPUT_PROTOCOL*) 72 C5 03 20 # MOVnw R5,@R4(3,0) // EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE*Mode 6B 04 # PUSH64 R4 // save R4 (EFI_GRAPHICS_OUTPUT_PROTOCOL) 6B 05 # PUSH64 R5 // save R5 (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE) 5F D5 40 20 # MOVdw R5,@R5(0,4) // UINT32 Mode 35 05 # PUSH32 R5 // UINT32 Mode (TODO: all arguments passed as natural values?) 35 04 # PUSHn R4 // EFI_GRAPHICS_OUTPUT_PROTOCOL*This 72 C4 01 20 # MOVnw R4,@R4(+1,+0) // SetMode 03 24 # CALLex R4 // SetMode(*This,Mode) 36 04 # POPn R4 // restore stack 36 04 # POP32 R4 // restore stack 6C 05 # POP64 R5 // restore R5 6C 04 # POP64 R4 // restore R4 72 D6 80 20 # MOVnw R6,@R5(0,8) // EFI_GRAPHICS_OUTPUT_MODE_INFORMATION*Info 5F E7 80 20 # MOVdw R7,@R6(0,8) // UINT32 VerticalResolution 5F E6 40 20 # MOVdw R6,@R6(0,4) // UINT32 HorizontalResolution 28 75 # MOVqq R5,R7 4F 65 # MULU64 R5,R6 4C 55 # ADD R5,R5 4C 55 # ADD R5,R5 6B 04 # PUSH64 R4 6B 06 # PUSH64 R6 6B 07 # PUSH64 R7 35 05 # PUSHn R5 // EFI_PHYSICAL_ADDRESS*Memory (dummy) 77 17 00 10 # MOVIww R7,4096 // PageSize 51 75 # DIVU64 R5,R7 77 17 01 00 # MOVIww R7,1 // possible overflow 4C 75 # ADD R5,R7 35 07 # PUSHn R5 // UINTN Pages 77 17 04 00 # MOVIww R7,4 // EfiBootServicesData 35 07 # PUSHn R7 // EFI_MEMORY_TYPE MemoryType 16 77 # XOR32 R7,R7 // AllocateAnyPages 35 07 # PUSHn R7 // EFI_ALLOCATE_TYPE Type 72 B4 82 21 # MOVnw R4,@R3(+2,+24) // AllocatePages 03 24 # CALLex R4 // AllocatePages(Type,MemoryType,Pages,*Memory) 36 05 # POPn R5 // restore stack 36 05 # POPn R5 // restore stack 36 05 # POPn R5 // restore stack 36 05 # POPn R5 // EFI_PHYSICAL_ADDRESS*Memory 6C 07 # POP64 R7 6C 06 # POP64 R6 6C 04 # POP64 R4 ## LOOP Y header #6B 07 # PUSH64 R7 #6B 05 # PUSH64 R5 #6B 04 # PUSH64 R4 #77 14 01 00 # MOVIw R4,1 ## LOOP Y body ## LOOP X header #6B 06 # PUSH64 R6 ## LOOP X body #77 0D 00 00 # MOVIb @R5,0 #4C 45 # ADD64 R5,R4 #1D 1D # MOVI @R5,R1 #4C 45 # ADD64 R5,R4 #77 0D FF 00 # MOVIb @R5,0xFF #4C 45 # ADD64 R5,R4 #77 0D 00 00 # MOVIb @R5,0 #4C 45 # ADD64 R5,R4 ## LOOP X trailer #4D 46 # SUB64 R6,R4 #6D 06 00 00 # CMP64Ieq R6,0 #82 F1 # JMP8cc -15*2 #6C 06 # POP64 R6 ## LOOP Y trailer #4D 47 # SUB64 R7,R4 #6D 07 00 00 # CMP64Ieq R7,0 #82 EB # JMP8cc -21*2 #4C 41 # ADD64 R1,R4 #6C 04 # POP64 R4 #6C 05 # POP64 R5 #6C 07 # POP64 R7 6B 07 # PUSH64 R7 6B 04 # PUSH64 R4 77 14 01 00 # MOVIww R4,1 // 4C 42 # ADD R2,R4 // 77 14 FF 02 # MOVIww R4,0x2FE // 13 42 # MOD R2,R4 // 35 02 # PUSHn R2 // rnd 35 07 # PUSHn R7 // ny 35 06 # PUSHn R6 // nx 35 05 # PUSHn R5 // ptr 77 14 5E 01 # MOVIww R4,15E // 4C 14 # ADD R4,R1 03 24 # CALLex R4 // 03 24 # CALLex R4 // 36 05 # POPn R5 // restore stack 36 06 # POPn R6 // restore stack 36 07 # POPn R7 // restore stack 36 07 # POPn R7 // restore stack 6C 04 # POP64 R4 6C 07 # POP64 R7 16 33 # XOR32 R3,R3 // R3=0 35 03 # PUSHn R3 // UINTN Delta (bytes) 35 07 # PUSHn R7 // UINTN Height (pixels) 35 06 # PUSHn R6 // UINTN Width (pixels) 35 03 # PUSHn R3 // UINTN DestinationY 35 03 # PUSHn R3 // UINTN DestinationX 35 03 # PUSHn R3 // UINTN SourceY 35 03 # PUSHn R3 // UINTN SourceX 77 13 02 00 # MOVIww R3,2 // EfiBltBufferToVideo 35 03 # PUSHn R3 // EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation 35 05 # PUSHn R5 // EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer 35 04 # PUSHn R4 // EFI_GRAPHICS_OUTPUT_PROTOCOL *This 72 C4 02 20 # MOVnw R4,@R4(+2,+0) // Blt 03 24 # CALLex R4 // Blt(*This,*BltBuffer,BltOperation,SourceX,SourceY,DestinationX,DestinationY,Width,Height,Delta) 36 04 # POPn R4 // restore stack 36 05 # POPn R5 // restore stack 36 03 # POPn R3 // restore stack 36 03 # POPn R3 // restore stack 36 03 # POPn R3 // restore stack 36 03 # POPn R3 // restore stack 36 03 # POPn R3 // restore stack 36 06 # POPn R6 // restore stack 36 07 # POPn R7 // restore stack 36 03 # POPn R3 // restore stack #04 00 # RET 02 CE # JMP8 -50*2 00*26 # Padding to 0x0340 ### DATA (but also in .text) ### # 0340: 82 77 2F F4 2E 01 12 4C 99 56 49 F9 43 04 F7 21 # EFI_CONSOLE_CONTROL_PROTOCOL_GUID: F42F7782-012E-4C12-9956-49F94304F721 # 0350: DE A9 42 90 DC 23 38 4A 96 FB 7A DE D0 80 51 6A # EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID: 9042A9DE-23DC-4A38-96FB-7ADED080516A #8B 29 2C 98 FA F4 CB 41 B8 38 77 AA 68 8F B8 39 # EFI_UGA_DRAW_PROTOCOL_GUID: 982C298B-F4FA-41CB-B838-77AA688FB839 # 0360: #in: # rcx: *frame buffer # rdx: nx # r8 : ny,iy # r9 : rnd -> rax (return) #temp: # r10 : ix # r11 : sum # rsi : rptr # rdi : wptr 57 # push rdi 56 # push rsi ### SOLVE PDE FOR TOP NY-1 ROWS ### 49 FF C8 # dec r8 # loopy: 49 89 D2 # mov r10,rdx # loopx: 48 89 CE # mov rsi,rcx 4D 31 DB # xor r11,r11 E8 8B 00 00 00 # call getv 49 01 C3 # add r11,rax 48 01 D6 # add rsi,rdx 48 01 D6 # add rsi,rdx 48 01 D6 # add rsi,rdx 48 01 D6 # add rsi,rdx 48 83 EE 04 # sub rsi,4 E8 73 00 00 00 # call getv 49 01 C3 # add r11,rax 48 83 C6 04 # add rsi,4 E8 67 00 00 00 # call getv 49 01 C3 # add r11,rax 48 83 C6 04 # add rsi,4 E8 5B 00 00 00 # call getv 4C 01 D8 # add rax,r11 C1 E8 02 # shr eax,2 74 02 # jz zero FF C8 # dec eax # zero: 48 89 CF # mov rdi,rcx E8 57 00 00 00 # call setv 48 83 C1 04 # add rcx,4 49 FF CA # dec r10 75 AA # jnz loopx 49 FF C8 # dec r8 75 A2 # jnz loopy ### RANDOMIZE LAST ROW ### 49 89 D2 # mov r10,rdx 48 89 CF # mov rdi,rcx # loopx0: 44 89 C8 # mov eax,r9d BA 19 36 00 00 # mov edx,13849 F7 E2 # mul edx 05 19 36 00 00 # add eax,13849 41 89 C1 # mov r9d,eax 31 C0 # xor eax,eax 66 41 81 F9 00 7D # cmp r9w,32000 72 05 # jb rnd_next B8 FE 02 00 00 # mov eax,0x2FE # rnd_next: E8 1D 00 00 00 # call setv 48 83 C7 04 # add rdi,4 49 FF CA # dec r10 75 D1 # jnz loopx0 ### RETURN NEW RANDOM SEED ### 44 89 C8 # mov eax,r9d 5E # pop rsi 5F # pop rdi C3 # ret # getv: ### GET HEAT IN PIXEL AT rsi TO rax 31 C0 # xor eax,eax 8A 06 # mov al,[rsi+0] # B 02 46 01 # add al,[rsi+1] # G 10 E4 # adc ah,ah 66 03 46 02 # add ax,[rsi+2] # R,0 C3 # ret # setv: ### SET PIXEL AT rdi TO HEAT ax 66 C7 07 FF FF # movw [rdi+0],0xFFFF 66 C7 47 02 FF 00 # movw [rdi+2],0x00FF 66 3D 00 01 # cmp ax,0x100 72 12 # jb setv_red 66 3D FF 01 # cmp ax,0x1FF 72 07 # jb setv_yellow 66 2D FF 01 # sub ax,0x1FF 88 07 # mov [rdi+0],al # B C3 # ret # setv_yellow: 88 47 01 # mov [rdi+1],al # G EB 07 # jmp setv_yellow_end # setv_red: 88 47 02 # mov [rdi+2],al # R C6 47 01 00 # movb [rdi+1],0x00 # G # setv_yellow_end: C6 07 00 # movb [rdi+0],0x00 # B C3 # ret
… HFS and GPT part to be documented soon. Anyhow, with minimal GPT and HFS it fits in 46.5 kB, i.e. one sector is still available on lua-stick!
09/11/2014
Here a small script (see warning within) to create a bootable HFS+ volume with rEFIt on OS X for VirtualBox.org:
- make_image_osx.sh
#!/bin/bash # !!! WARNING !!! # DO NOT USE UNLESS YOU KNOW WHAT YOU ARE DOING # NO PROTECTION FOR SPECIAL CASES INCLUDED # MIGHT OVERWRITE FILES/HARDDRIVES NBLOCKS=8192 RAW_IMAGE_FILE=test.img VMBOX_IMAGE_FILE=test.vmdk REFIT_ROOT=/Volumes/rEFIt dd if=/dev/zero of=${RAW_IMAGE_FILE} bs=512 count=${NBLOCKS} gpt create ${RAW_IMAGE_FILE} gpt add -t hfs ${RAW_IMAGE_FILE} HANDLE=$(hdiutil attach -nomount ${RAW_IMAGE_FILE} | grep Apple_HFS | sed 's/ .*//') newfs_hfs ${HANDLE} hdiutil detach ${HANDLE} MOUNT=$(hdiutil attach ${RAW_IMAGE_FILE} | grep Apple_HFS | sed 's/.* //') ls ${MOUNT} cp -r ${REFIT_ROOT}/efi/refit/refit.efi ${MOUNT} bless --folder ${MOUNT} --file ${MOUNT}/refit.efi ls -lrth ${MOUNT} bless --info ${MOUNT} hdiutil detach ${MOUNT} VBoxManage internalcommands createrawvmdk -filename ${VMBOX_IMAGE_FILE} -rawdisk ${RAW_IMAGE_FILE}
Liens externes
(U)EFI general
- EFI specs (PDF warning): http://www.intel.com/content/dam/doc/product-specification/efi-v1-10-specification.pdf (still including UGA)
- UEFI sepcs: http://www.uefi.org/specifications (already with GOP)
- rEFIt, an EFI boot loader that works on Mac: http://refit.sourceforge.net
EFI byte code (EBC)
- Article with EBC hello world: http://sysmagazine.com/posts/201954/
- EBC debugger http://www.uefi.org/node/550
File formats
- Neat project giving insight in the PE format: http://www.phreedom.org/research/tinype/
- A bit more info (including the “MZ” DOS stub): http://www.csn.ul.ie/~caolan/pub/winresdump/winresdump/doc/pefile.html
x86 assembly
- An online assembler: https://defuse.ca/online-x86-assembler.htm
- An online disassembler: http://www.onlinedisassembler.com/odaweb/
- Opcode reference: http://ref.x86asm.net
- Polyglot 32 vs 64 bit detection: http://stackoverflow.com/a/38063530
- EICAR AV Test file (ASCII text file that can be executed as x86 machine code): Wikipedia