├── carbefi ├── load.c ├── carbefi.vcxproj.filters └── carbefi.vcxproj ├── boot.zip ├── ss └── 1.png ├── carblegacy ├── load.bin ├── disk.asm ├── load.asm ├── fat32.asm └── pe32.asm ├── .gitignore ├── examples ├── multi_basic │ ├── release │ │ ├── hal.exp │ │ ├── hal.lib │ │ ├── hal.sys │ │ ├── kernel.exp │ │ ├── kernel.lib │ │ └── kernel.sys │ ├── hal │ │ ├── hal.vcxproj.filters │ │ ├── hal.c │ │ └── hal.vcxproj │ ├── kernel │ │ ├── kernel.vcxproj.filters │ │ ├── memory.h │ │ ├── kernel.vcxproj │ │ └── initos.c │ └── multi_example.sln └── single_basic │ ├── kernel │ ├── kernel.filters │ ├── kernel.vcxproj │ ├── memory.h │ └── initos.c │ └── single_basic.sln ├── carbload ├── carbload.vcxproj.filters ├── bios │ ├── disk.c │ ├── vbe.c │ ├── bioscall.asm │ ├── file.c │ └── map.c ├── x86_64 │ └── boot64.asm ├── inc │ ├── ldef.h │ ├── fat32.h │ ├── loader.h │ ├── x86_64.h │ └── pe64.h ├── format │ ├── fat32.c │ └── pe64.c ├── carbload.vcxproj ├── rtl.c └── initload.c ├── carboot.sln ├── .gitattributes └── README.md /carbefi/load.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /boot.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irql/carboot/HEAD/boot.zip -------------------------------------------------------------------------------- /ss/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irql/carboot/HEAD/ss/1.png -------------------------------------------------------------------------------- /carblegacy/load.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irql/carboot/HEAD/carblegacy/load.bin -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.suo 2 | *.user 3 | 4 | x64/ 5 | x86/ 6 | 7 | .vs/ 8 | boot.vhd 9 | build/ 10 | !./build/ -------------------------------------------------------------------------------- /examples/multi_basic/release/hal.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irql/carboot/HEAD/examples/multi_basic/release/hal.exp -------------------------------------------------------------------------------- /examples/multi_basic/release/hal.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irql/carboot/HEAD/examples/multi_basic/release/hal.lib -------------------------------------------------------------------------------- /examples/multi_basic/release/hal.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irql/carboot/HEAD/examples/multi_basic/release/hal.sys -------------------------------------------------------------------------------- /examples/multi_basic/release/kernel.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irql/carboot/HEAD/examples/multi_basic/release/kernel.exp -------------------------------------------------------------------------------- /examples/multi_basic/release/kernel.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irql/carboot/HEAD/examples/multi_basic/release/kernel.lib -------------------------------------------------------------------------------- /examples/multi_basic/release/kernel.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irql/carboot/HEAD/examples/multi_basic/release/kernel.sys -------------------------------------------------------------------------------- /carbefi/carbefi.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /examples/multi_basic/hal/hal.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /examples/single_basic/kernel/kernel.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/multi_basic/kernel/kernel.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/multi_basic/hal/hal.c: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | // 5 | // Import KiDisplayString from initos.c, kernel.sys. 6 | // 7 | 8 | __declspec( dllimport ) 9 | void 10 | KiDisplayString( 11 | char* String 12 | ); 13 | 14 | __declspec( dllexport ) 15 | void 16 | HalExtExample( 17 | 18 | ) 19 | { 20 | // 21 | // This creates a cyclic dependency, build as a 22 | // static library before-hand 23 | // 24 | 25 | KiDisplayString( "Hello from hal.sys!\n" ); 26 | } 27 | -------------------------------------------------------------------------------- /carblegacy/disk.asm: -------------------------------------------------------------------------------- 1 | 2 | BITS 16 3 | 4 | %DEFINE BdDiskId BootDisk 5 | 6 | BdDap: 7 | db 10h ;DapLength 8 | db 0 ;Reserved 9 | dw 0 ;ReadCount 10 | dd 0 ;MemoryAddress 11 | dq 0 ;BlockAddress 12 | 13 | BdReadSectors: 14 | pushad 15 | 16 | mov dword ptr [BdDap+08h], eax 17 | mov dword ptr [BdDap+0ch], edx 18 | mov word ptr [BdDap+02h], cx 19 | mov byte ptr [BdDap+00h], 10h 20 | mov dword ptr [BdDap+04h], ebx 21 | 22 | mov ah, 42h 23 | mov dl, byte ptr [BdDiskId] 24 | mov si, BdDap 25 | int 13h 26 | 27 | popad 28 | ret -------------------------------------------------------------------------------- /carbload/carbload.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/single_basic/single_basic.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.1401 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kernel", "kernel\kernel.vcxproj", "{61486F4C-5BDB-4107-BD0C-94A6F0956F64}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | release|x86_64 = release|x86_64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {61486F4C-5BDB-4107-BD0C-94A6F0956F64}.release|x86_64.ActiveCfg = release|x64 14 | {61486F4C-5BDB-4107-BD0C-94A6F0956F64}.release|x86_64.Build.0 = release|x64 15 | EndGlobalSection 16 | GlobalSection(SolutionProperties) = preSolution 17 | HideSolutionNode = FALSE 18 | EndGlobalSection 19 | GlobalSection(ExtensibilityGlobals) = postSolution 20 | SolutionGuid = {23B65FE3-1376-44F3-82EE-EF3B9B125ADF} 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /carbload/bios/disk.c: -------------------------------------------------------------------------------- 1 | 2 | #include "loader.h" 3 | 4 | VOID 5 | BPAPI 6 | BdDiskRead( 7 | _Out_ PVOID Buffer, 8 | _In_ ULONG32 BlockAddress, 9 | _In_ USHORT SectorCount 10 | ) 11 | { 12 | // 13 | // TODO: Must re-read over & over if the buffer is 14 | // outside the segment, this function should deal 15 | // with that. 16 | // 17 | 18 | X86_DISK_ACCESS_BLOCK Access = { 0 }; 19 | X86_BIOS_INTERRUPT BiosFrame = { 0 }; 20 | PCHAR Low = ( PCHAR )0x10000; 21 | 22 | Access.Length = 0x10; 23 | Access.Zero = 0; 24 | X86_BIOS_ENCODE_FAR_PTR( Access.Buffer.Segment, 25 | Access.Buffer.Offset, 26 | Low ); 27 | Access.BlockAddress = BlockAddress; 28 | Access.SectorCount = SectorCount; 29 | 30 | BiosFrame.Eax = 0x4200; 31 | BiosFrame.Edx = BpBootDisk; 32 | X86_BIOS_ENCODE_FAR_PTR( BiosFrame.SegDs, 33 | BiosFrame.Esi, 34 | &Access ); 35 | x86BiosCall( 0x13, &BiosFrame ); 36 | 37 | __movsb( Buffer, Low, SectorCount * 512 ); 38 | } 39 | -------------------------------------------------------------------------------- /examples/multi_basic/multi_example.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.1401 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hal", "hal\hal.vcxproj", "{4BAEE8C7-3989-4921-AB74-E6B3055158D2}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kernel", "kernel\kernel.vcxproj", "{61486F4C-5BDB-4107-BD0C-94A6F0956F64}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | release|x86_64 = release|x86_64 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {4BAEE8C7-3989-4921-AB74-E6B3055158D2}.release|x86_64.ActiveCfg = release|x64 16 | {61486F4C-5BDB-4107-BD0C-94A6F0956F64}.release|x86_64.ActiveCfg = release|x64 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {3BDC8929-A7A6-475E-917A-3D7743FD42A0} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /carbload/bios/vbe.c: -------------------------------------------------------------------------------- 1 | 2 | #include "loader.h" 3 | 4 | VOID 5 | BPAPI 6 | BdInitGraphics( 7 | 8 | ) 9 | { 10 | X86_BIOS_INTERRUPT BiosFrame = { 0 }; 11 | X86_VESA_INFO VesaInfo; 12 | X86_VESA_MODE_INFO ModeInfo; 13 | USHORT* ModeList; 14 | 15 | BiosFrame.Eax = 0x4F00; 16 | X86_BIOS_ENCODE_FAR_PTR( BiosFrame.SegEs, 17 | BiosFrame.Edi, 18 | &VesaInfo ); 19 | x86BiosCall( 0x10, &BiosFrame ); 20 | 21 | X86_BIOS_DECODE_FAR_PTR( VesaInfo.ModeList.Segment, 22 | VesaInfo.ModeList.Offset, 23 | ModeList ); 24 | 25 | while ( *ModeList != 0xFFFF ) { 26 | 27 | BiosFrame.Eax = 0x4F01; 28 | BiosFrame.Ecx = *ModeList; 29 | X86_BIOS_ENCODE_FAR_PTR( BiosFrame.SegEs, 30 | BiosFrame.Edi, 31 | &ModeInfo ); 32 | x86BiosCall( 0x10, &BiosFrame ); 33 | 34 | if ( ModeInfo.Width == 640 && 35 | ModeInfo.Height == 480 && 36 | ModeInfo.BitsPerPixel == 32 ) { 37 | 38 | BiosFrame.Eax = 0x4F02; 39 | BiosFrame.Ebx = *ModeList; 40 | x86BiosCall( 0x10, &BiosFrame ); 41 | 42 | Loader.Graphics.Width = 640; 43 | Loader.Graphics.Height = 480; 44 | Loader.Graphics.Bpp = 32; 45 | 46 | Loader.Graphics.Pitch = ModeInfo.Pitch; 47 | Loader.Graphics.Frame = ModeInfo.Framebuffer; 48 | break; 49 | } 50 | 51 | ModeList++; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /carbefi/carbefi.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | build 6 | x64 7 | 8 | 9 | 10 | 15.0 11 | {93F8545D-C42B-40A7-A2F4-924E5767AE3C} 12 | carbefi 13 | 10.0.17763.0 14 | 15 | 16 | 17 | v141 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | false 27 | 28 | 29 | 30 | EFI Boot Service Driver 31 | EfiMain 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /carbload/x86_64/boot64.asm: -------------------------------------------------------------------------------- 1 | 2 | BITS 32 3 | 4 | %DEFINE ptr 5 | 6 | %DEFINE GDT_SEGMENT_R0_CODE64 28h 7 | %DEFINE GDT_SEGMENT_R0_DATA64 30h 8 | 9 | %DEFINE IA32_MSR_EFER 0C0000080h 10 | 11 | %DEFINE CR4_PAE (1 << 5) 12 | %DEFINE CR4_OSFXSR (1 << 9) 13 | %DEFINE CR4_OSXMMEXCPT (1 << 10) 14 | 15 | %DEFINE EFER_LME (1 << 8) 16 | 17 | %DEFINE CR0_PG (1 << 31) 18 | %DEFINE CR0_MP (1 << 1) 19 | %DEFINE CR0_EM (1 << 2) 20 | %DEFINE CR0_NW (1 << 29) 21 | %DEFINE CR0_CD (1 << 30) 22 | 23 | SECTION .text 24 | 25 | GLOBAL _x86Boot64@16 26 | 27 | _x86Boot64@16: 28 | 29 | %DEFINE EntryAddress 4 30 | %DEFINE LoaderBlock 12 31 | 32 | mov eax, cr4 33 | or eax, CR4_PAE 34 | or eax, CR4_OSFXSR 35 | or eax, CR4_OSXMMEXCPT 36 | mov cr4, eax 37 | 38 | mov ecx, IA32_MSR_EFER 39 | rdmsr 40 | or eax, EFER_LME 41 | wrmsr 42 | 43 | mov eax, cr0 44 | or eax, CR0_PG 45 | mov cr0, eax 46 | 47 | mov ax, GDT_SEGMENT_R0_DATA64 48 | mov ds, ax 49 | mov es, ax 50 | mov fs, ax 51 | mov gs, ax 52 | mov ss, ax 53 | jmp GDT_SEGMENT_R0_CODE64:.x86_64_Entry 54 | 55 | .x86_64_Entry: 56 | 57 | BITS 64 58 | 59 | mov rax, cr0 60 | or rax, CR0_MP 61 | and rax, ~CR0_EM 62 | and rax, ~CR0_NW 63 | and rax, ~CR0_CD 64 | mov cr0, rax 65 | 66 | mov rcx, qword ptr [rsp+LoaderBlock] 67 | mov rdx, qword ptr [rsp+EntryAddress] 68 | sub rsp, 30h 69 | and rsp, ~0Fh 70 | jmp rdx 71 | 72 | -------------------------------------------------------------------------------- /carboot.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.1401 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "carbload", "carbload\carbload.vcxproj", "{BE6CBE06-016A-4C65-8EB8-D8C7422CC2C1}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "carbefi", "carbefi\carbefi.vcxproj", "{93F8545D-C42B-40A7-A2F4-924E5767AE3C}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "carblegacy", "carblegacy", "{B7F38E44-CF8B-4095-AE9F-FD463661FEBE}" 11 | ProjectSection(SolutionItems) = preProject 12 | carblegacy\disk.asm = carblegacy\disk.asm 13 | carblegacy\fat32.asm = carblegacy\fat32.asm 14 | carblegacy\load.asm = carblegacy\load.asm 15 | carblegacy\pe32.asm = carblegacy\pe32.asm 16 | EndProjectSection 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | build|x86_32 = build|x86_32 21 | build|x86_64 = build|x86_64 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {BE6CBE06-016A-4C65-8EB8-D8C7422CC2C1}.build|x86_32.ActiveCfg = build|Win32 25 | {BE6CBE06-016A-4C65-8EB8-D8C7422CC2C1}.build|x86_32.Build.0 = build|Win32 26 | {BE6CBE06-016A-4C65-8EB8-D8C7422CC2C1}.build|x86_64.ActiveCfg = build|Win32 27 | {BE6CBE06-016A-4C65-8EB8-D8C7422CC2C1}.build|x86_64.Build.0 = build|Win32 28 | {93F8545D-C42B-40A7-A2F4-924E5767AE3C}.build|x86_32.ActiveCfg = build|x64 29 | {93F8545D-C42B-40A7-A2F4-924E5767AE3C}.build|x86_64.ActiveCfg = build|x64 30 | {93F8545D-C42B-40A7-A2F4-924E5767AE3C}.build|x86_64.Build.0 = build|x64 31 | EndGlobalSection 32 | GlobalSection(SolutionProperties) = preSolution 33 | HideSolutionNode = FALSE 34 | EndGlobalSection 35 | GlobalSection(ExtensibilityGlobals) = postSolution 36 | SolutionGuid = {1A717AD0-6ACD-40DC-B8BF-EAF7672F30AC} 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /carbload/inc/ldef.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | // loader definitions for 64 bit. 5 | // 8 byte packing. 6 | 7 | #ifndef C_ASSERT 8 | #define C_ASSERT( x ) static_assert( x, #x ) 9 | #endif 10 | 11 | #ifndef LOADER_BASIC_TYPES_DEFINED 12 | typedef unsigned long long ULONG64; 13 | typedef unsigned long ULONG32; 14 | typedef char CHAR; 15 | #endif 16 | 17 | #if defined(_M_AMD64) && (_M_AMD64 == 100) 18 | #define LDR_PTR( TYPE, NAME ) \ 19 | TYPE NAME 20 | #else 21 | #define LDR_PTR( TYPE, NAME ) \ 22 | union { \ 23 | TYPE NAME; \ 24 | ULONG64 _##NAME##64; \ 25 | } 26 | #endif 27 | 28 | #define LOADER_REGION_USABLE 0x00000001 29 | #define LOADER_REGION_RESERVED 0x00000002 30 | #define LOADER_REGION_ACPI_RECLAIM 0x00000003 31 | #define LOADER_REGION_ACPI_NVS 0x00000004 32 | #define LOADER_REGION_BAD 0x00000005 33 | #define LOADER_REGION_LOADER 0x00000006 34 | 35 | typedef struct _LOADER_LOGICAL_REGION { 36 | ULONG64 BaseAddress; 37 | ULONG64 Length; 38 | ULONG32 Type; 39 | } LOADER_LOGICAL_REGION, *PLOADER_LOGICAL_REGION; 40 | 41 | #define LOADER_REGION_LIST_LENGTH 0x10 42 | 43 | typedef struct _LOADER_BOOT_FILE { 44 | ULONG64 BaseAddress; 45 | ULONG32 Length; 46 | CHAR FileName[ 12 ]; 47 | } LOADER_BOOT_FILE, *PLOADER_BOOT_FILE; 48 | 49 | #define LOADER_FILE_LIST_LENGTH 0x10 50 | 51 | typedef struct _LOADER_SYSTEM_MAP { 52 | ULONG64 BaseAddress; 53 | ULONG32 Length; 54 | LDR_PTR( PLOADER_BOOT_FILE, BootFile ); 55 | 56 | } LOADER_SYSTEM_MAP, *PLOADER_SYSTEM_MAP; 57 | 58 | #define LOADER_MAP_LIST_LENGTH 0x10 59 | 60 | typedef struct _LOADER_BOOT_GRAPHICS { 61 | ULONG32 Width; 62 | ULONG32 Height; 63 | ULONG32 Pitch; 64 | ULONG32 Bpp; 65 | ULONG32 Frame; 66 | } LOADER_BOOT_GRAPHICS, *PLOADER_BOOT_GRAPHICS; 67 | 68 | C_ASSERT( sizeof( LOADER_LOGICAL_REGION ) == 24 ); 69 | C_ASSERT( sizeof( LOADER_BOOT_FILE ) == 24 ); 70 | C_ASSERT( sizeof( LOADER_SYSTEM_MAP ) == 24 ); 71 | C_ASSERT( sizeof( LOADER_BOOT_GRAPHICS ) == 20 ); 72 | 73 | typedef struct _LOADER_BLOCK { 74 | ULONG32 LoaderSig; 75 | ULONG32 RootSerial; 76 | 77 | ULONG32 RegionCount; 78 | ULONG32 FileCount; 79 | ULONG32 MapCount; 80 | 81 | LOADER_LOGICAL_REGION RegionList[ LOADER_REGION_LIST_LENGTH ]; 82 | LOADER_BOOT_FILE FileList[ LOADER_FILE_LIST_LENGTH ]; 83 | LOADER_SYSTEM_MAP MapList[ LOADER_MAP_LIST_LENGTH ]; 84 | LOADER_BOOT_GRAPHICS Graphics; 85 | 86 | } LOADER_BLOCK, *PLOADER_BLOCK; 87 | 88 | C_ASSERT( sizeof( LOADER_BLOCK ) == 1200 ); 89 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # carboot 2 | This project is a small x86_64 bootloader capable of reading FAT32 and mapping PE32+ images. 3 | It is the bootloader for carbon and is designed to do the bare minimum required for loading a kernel, 4 | it will simply load your kernel from inside the `/SYSTEM/` directory, and load all files under `/SYSTEM/BOOT/`, 5 | it can deal with imports too, as long as the imported module is placed inside `/SYSTEM/BOOT/` and will relocate 6 | your kernel and any dependencies into the upper 2MB of the 64 bit address space (`0xFFFFFFFFFFE00000`), all bootloader 7 | structures are placed in the 2MB of memory starting at `0xFFFFFFFFFFC00000`, just before your kernel. The project is still 8 | very under-developed but hopefully that will change over time. 9 | 10 | ## `LOADER_BLOCK` 11 | This structure is passed to your kernel's entry point and contains all information about the environment. 12 | ```c 13 | typedef struct _LOADER_BLOCK { 14 | ULONG32 LoaderSig; 15 | ULONG32 RootSerial; 16 | 17 | ULONG32 RegionCount; 18 | ULONG32 FileCount; 19 | ULONG32 MapCount; 20 | 21 | LOADER_LOGICAL_REGION RegionList[ LOADER_REGION_LIST_LENGTH ]; 22 | LOADER_BOOT_FILE FileList[ LOADER_FILE_LIST_LENGTH ]; 23 | LOADER_SYSTEM_MAP MapList[ LOADER_MAP_LIST_LENGTH ]; 24 | LOADER_BOOT_GRAPHICS Graphics; 25 | } LOADER_BLOCK, *PLOADER_BLOCK; 26 | ``` 27 | Your kernel entry point should look something like this: 28 | ```c 29 | void 30 | KiSystemStartup( 31 | PLOADER_BLOCK Loader 32 | ); 33 | ``` 34 | ![Example](https://github.com/irql0/carboot/blob/master/ss/1.png) 35 | All loader structures are inside [ldef.h](/carbload/inc/ldef.h). 36 | 37 | ## Memory map 38 | ``` 39 | 1: 0x0000000000000000-0x0000000000200000 identity mapped, contains the bootloader module & some structures. 40 | 2: 0x0000000000200000-0x0000000000400000 2MB usable, for parts of the LOADER_BLOCK structure and system modules. 41 | 3: 0xFFFFFFFFFFC00000-0xFFFFFFFFFFE00000 maps to 1. 42 | 4: 0xFFFFFFFFFFE00000-0xFFFFFFFFFFFFFFFF maps to 2. 43 | ``` 44 | 45 | ## Examples 46 | ###### Single-module example which prints Hello World can be found [here](/examples/single_basic). 47 | ###### Multi-module example which prints Hello World, and imports functions from an external boot dependency can be found [here](/examples/multi_basic). 48 | 49 | ## Usage 50 | Extract boot.zip to boot.vhd, open an administrator command prompt in the root directory, type `build` and 51 | the script will use diskpart to read/write to the FAT32 VHD. It will copy `CARBLOAD.SYS`, `KERNEL.SYS` and `HAL.SYS` from the multi-module example onto the VHD 52 | and then detach the VHD in-order to run it with QEMU. 53 | 54 | ## Build 55 | This project was written using Visual Studio 2017, compile as `build` `x86_64`. 56 | -------------------------------------------------------------------------------- /carbload/format/fat32.c: -------------------------------------------------------------------------------- 1 | 2 | #include "loader.h" 3 | 4 | VOID 5 | BPAPI 6 | BdFat32QueryFatTable( 7 | _In_ PVOLUME_BOOT_RECORD BootRecord, 8 | _In_ ULONG32 Index, 9 | _Out_ ULONG32* Link 10 | ) 11 | { 12 | ULONG32 FatSector; 13 | ULONG32 FatSectorIndex; 14 | ULONG32 FatTable[ 128 ]; 15 | 16 | FatSector = Index / 128; 17 | FatSectorIndex = Index % 128; 18 | 19 | BdDiskRead( &FatTable, 20 | BootRecord->Bpb3_31.HiddenSectors + 21 | BootRecord->Bpb2_00.ReservedSectors + FatSector, 22 | 1 ); 23 | *Link = FatTable[ FatSectorIndex ] & 0x0FFFFFFF; 24 | } 25 | 26 | VOID 27 | BPAPI 28 | BdFat32ReadCluster( 29 | _In_ PVOLUME_BOOT_RECORD BootRecord, 30 | _In_ ULONG32 Number, 31 | _Out_ PVOID Buffer 32 | ) 33 | { 34 | ULONG32 Sector; 35 | 36 | Sector = FIRST_SECTOR_OF_CLUSTER( BootRecord, Number ); 37 | 38 | BdDiskRead( Buffer, 39 | BootRecord->Bpb3_31.HiddenSectors + 40 | Sector, 41 | BootRecord->Bpb2_00.SectorsPerCluster ); 42 | } 43 | 44 | ULONG32 45 | BPAPI 46 | BdFat32ReadClusterChain( 47 | _In_ PVOLUME_BOOT_RECORD BootRecord, 48 | _In_ ULONG32 Number, 49 | _Out_ PVOID Buffer 50 | ) 51 | { 52 | ULONG32 Length; 53 | 54 | Length = 0; 55 | do { 56 | BdFat32ReadCluster( BootRecord, 57 | Number, 58 | Buffer ); 59 | Buffer = ( PCHAR )Buffer + 60 | BootRecord->Bpb2_00.SectorsPerCluster * 512; 61 | Length += BootRecord->Bpb2_00.SectorsPerCluster * 512; 62 | 63 | BdFat32QueryFatTable( BootRecord, 64 | Number, 65 | &Number ); 66 | 67 | } while ( Number != FAT32_END_OF_CHAIN ); 68 | 69 | return Length; 70 | } 71 | 72 | int memcmp( const void* ptr1, void* ptr2, unsigned long num ) { 73 | const unsigned char* m1 = ptr1; 74 | const unsigned char* m2 = ptr2; 75 | 76 | while ( num && *m1 == *m2 ) 77 | if ( --num ) 78 | m1++, m2++; 79 | return *m1 - *m2; 80 | } 81 | 82 | ULONG32 83 | BPAPI 84 | BdFat32ReadDirectoryFile( 85 | _In_ PVOLUME_BOOT_RECORD BootRecord, 86 | _In_ PFAT_DIRECTORY Directory, 87 | _In_ PCHAR Name, 88 | _Out_ PVOID Buffer 89 | ) 90 | { 91 | ULONG32 Entry; 92 | 93 | Entry = 0; 94 | do { 95 | 96 | if ( memcmp( Name, Directory[ Entry ].Short.Name, 11 ) == 0 ) { 97 | 98 | return BdFat32ReadClusterChain( BootRecord, 99 | Directory[ Entry ].Short.ClusterLow | 100 | Directory[ Entry ].Short.ClusterHigh << 16, 101 | Buffer ); 102 | } 103 | 104 | Entry++; 105 | } while ( Directory[ Entry ].Short.Name[ 0 ] != 0 ); 106 | 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /carbload/bios/bioscall.asm: -------------------------------------------------------------------------------- 1 | 2 | BITS 32 3 | 4 | %DEFINE ptr 5 | 6 | %DEFINE GDT_SEGMENT_R0_CODE32 08h 7 | %DEFINE GDT_SEGMENT_R0_DATA32 10h 8 | %DEFINE GDT_SEGMENT_R0_CODE16 18h 9 | %DEFINE GDT_SEGMENT_R0_DATA16 20h 10 | 11 | SECTION .text 12 | 13 | EXTERN _BdExitPagedMode@0 14 | EXTERN _BdEnterPagedMode@0 15 | 16 | GLOBAL _x86BiosCall@8 17 | 18 | _x86BiosCall@8: 19 | 20 | %DEFINE Vector 20 21 | %DEFINE BiosFrame 24 22 | 23 | push edi 24 | push esi 25 | push ebp 26 | push ebx 27 | 28 | call _BdExitPagedMode@0 29 | mov ecx, dword ptr [esp+BiosFrame] 30 | mov edx, dword ptr [esp+Vector] 31 | mov byte ptr [.x86_16_Intr+1], dl 32 | 33 | ; 34 | ; mov eax, cr0 35 | ; and eax, ~1 36 | ; mov cr0, eax 37 | ; jmp far ptr .x86_16_Enter 38 | ; 39 | mov dword ptr [0x1000], 0x83C0200F 40 | mov dword ptr [0x1004], 0x220FFEE0 41 | mov word ptr [0x1008], 0xEAC0 42 | mov edx, .x86_16_Enter 43 | shr edx, 16 44 | shl edx, 12 45 | mov word ptr [0x100C], dx 46 | mov edx, .x86_16_Enter 47 | and edx, 0ffffh 48 | mov word ptr [0x100A], dx 49 | 50 | mov ax, GDT_SEGMENT_R0_DATA16 51 | mov ds, ax 52 | mov es, ax 53 | mov fs, ax 54 | mov gs, ax 55 | mov ss, ax 56 | 57 | jmp GDT_SEGMENT_R0_CODE16:0x1000 58 | 59 | .x86_16_Enter: 60 | 61 | BITS 16 62 | xor ax, ax 63 | mov ds, ax 64 | mov es, ax 65 | mov fs, ax 66 | mov gs, ax 67 | mov ss, ax 68 | 69 | mov dword ptr [ecx+16], esp 70 | mov esp, ecx 71 | pop ax 72 | mov fs, ax 73 | pop ax 74 | mov es, ax 75 | popad 76 | mov esp, dword ptr [esp-20] 77 | push ax 78 | mov ax, fs 79 | mov ds, ax 80 | xor ax, ax 81 | mov fs, ax 82 | pop ax 83 | 84 | .x86_16_Intr: 85 | int 0 86 | 87 | .x86_16_Leave: 88 | 89 | mov dword ptr [esp-4], ecx 90 | mov cx, ds 91 | mov fs, cx 92 | xor cx, cx 93 | mov ds, cx 94 | mov ecx, dword ptr [esp+BiosFrame] 95 | mov dword ptr [ecx+4], edi 96 | mov dword ptr [ecx+8], esi 97 | mov dword ptr [ecx+12], ebp 98 | mov dword ptr [ecx+20], ebx 99 | mov dword ptr [ecx+24], edx 100 | mov edx, dword ptr [esp-4] 101 | mov dword ptr [ecx+28], edx 102 | mov dword ptr [ecx+32], eax 103 | mov ax, fs 104 | mov word ptr [ecx], ax 105 | mov ax, es 106 | mov word ptr [ecx+2], ax 107 | 108 | mov eax, cr0 109 | or eax, 1 110 | mov cr0, eax 111 | 112 | mov ax, GDT_SEGMENT_R0_DATA32 113 | mov ds, ax 114 | mov es, ax 115 | mov fs, ax 116 | mov gs, ax 117 | mov ss, ax 118 | 119 | sub esp, 8 120 | mov dword ptr [esp+4], GDT_SEGMENT_R0_CODE32 121 | mov dword ptr [esp], .x86_32_Done 122 | o32 retf 123 | .x86_32_Done: 124 | 125 | BITS 32 126 | call _BdEnterPagedMode@0 127 | pop ebx 128 | pop ebp 129 | pop esi 130 | pop edi 131 | ret 8 132 | -------------------------------------------------------------------------------- /carbload/carbload.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | build 6 | Win32 7 | 8 | 9 | 10 | 15.0 11 | {BE6CBE06-016A-4C65-8EB8-D8C7422CC2C1} 12 | carbload 13 | 10.0.17763.0 14 | 15 | 16 | 17 | v141 18 | false 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | false 30 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\inc 31 | 32 | 33 | 34 | BpLoadSystem 35 | Native 36 | false 37 | 38 | 39 | MultiThreaded 40 | 41 | 42 | false 43 | NoExtensions 44 | Disabled 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Document 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/single_basic/kernel/kernel.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | release 6 | x64 7 | 8 | 9 | 10 | 15.0 11 | {61486F4C-5BDB-4107-BD0C-94A6F0956F64} 12 | kernel 13 | 10.0.17763.0 14 | 15 | 16 | 17 | Application 18 | false 19 | v141 20 | false 21 | MultiByte 22 | false 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\carboot\carbload\inc\ 35 | false 36 | $(SolutionDir)$(Configuration)\ 37 | kernel 38 | .sys 39 | 40 | 41 | 42 | Level3 43 | MaxSpeed 44 | true 45 | true 46 | 47 | 48 | true 49 | false 50 | MultiThreaded 51 | false 52 | $(SolutionDir)..\..\..\carboot\carbload\inc\ 53 | 54 | 55 | Native 56 | true 57 | true 58 | false 59 | KiSystemStartup 60 | true 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /examples/multi_basic/kernel/memory.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | // 5 | // These define basic x86_64 specific structures 6 | // and macros for accessing page tables when using 7 | // recursive mappings, most are taken from Carbon. 8 | // Refer to the intel manual for more information. 9 | // 10 | 11 | typedef union _MMPTE_HARDWARE { 12 | struct { 13 | unsigned long long Present : 1; 14 | unsigned long long Write : 1; 15 | unsigned long long User : 1; 16 | unsigned long long WriteThrough : 1; 17 | unsigned long long CacheDisable : 1; 18 | unsigned long long Accessed : 1; 19 | unsigned long long Dirty : 1; 20 | unsigned long long Large : 1; 21 | unsigned long long Global : 1; 22 | unsigned long long Available0 : 3; 23 | unsigned long long PageFrame : 36; 24 | unsigned long long Reserved1 : 4; 25 | unsigned long long Available1 : 7; 26 | unsigned long long ProtectionKey : 4; 27 | unsigned long long ExecuteDisable : 1; 28 | } Table; 29 | 30 | struct { 31 | unsigned long long Present : 1; 32 | unsigned long long Write : 1; 33 | unsigned long long User : 1; 34 | unsigned long long WriteThrough : 1; 35 | unsigned long long CacheDisable : 1; 36 | unsigned long long Accessed : 1; 37 | unsigned long long Dirty : 1; 38 | unsigned long long PageAttribute : 1; 39 | unsigned long long Global : 1; 40 | unsigned long long Available0 : 3; 41 | unsigned long long PageFrame : 36; 42 | unsigned long long Reserved1 : 4; 43 | unsigned long long Available1 : 7; 44 | unsigned long long ProtectionKey : 4; 45 | unsigned long long ExecuteDisable : 1; 46 | } Entry; 47 | 48 | unsigned long long Long; 49 | } MMPTE_HARDWARE, *PMMPTE_HARDWARE; 50 | 51 | C_ASSERT( sizeof( MMPTE_HARDWARE ) == 8 ); 52 | 53 | #define MI_RECURSIVE_TABLE 0xFFFFFF0000000000ULL 54 | #define MI_RECURSIVE_INDEX 0x1FEULL 55 | 56 | #define MiReferenceLevel4Entry( index4 ) \ 57 | ( ( PMMPTE_HARDWARE )( MI_RECURSIVE_TABLE | \ 58 | ( MI_RECURSIVE_INDEX << 30ULL ) | \ 59 | ( MI_RECURSIVE_INDEX << 21ULL ) | \ 60 | ( ( ( unsigned long long ) ( index4 ) & 0x1FFULL ) << 12ULL) ) ) 61 | 62 | #define MiReferenceLevel3Entry( index4, index3 ) \ 63 | ( ( PMMPTE_HARDWARE )( MI_RECURSIVE_TABLE | \ 64 | ( MI_RECURSIVE_INDEX << 30ULL ) | \ 65 | ( ( ( unsigned long long )( index4 ) & 0x1FFULL ) << 21ULL) | \ 66 | ( ( ( unsigned long long )( index3 ) & 0x1FFULL ) << 12ULL) ) ) 67 | 68 | #define MiReferenceLevel2Entry( index4, index3, index2 ) \ 69 | ( ( PMMPTE_HARDWARE )( MI_RECURSIVE_TABLE | \ 70 | ( ( ( unsigned long long )( index4 ) & 0x1FFULL ) << 30ULL ) | \ 71 | ( ( ( unsigned long long )( index3 ) & 0x1FFULL ) << 21ULL ) | \ 72 | ( ( ( unsigned long long )( index2 ) & 0x1FFULL ) << 12ULL ) ) ) 73 | 74 | #define MiIndexLevel4( address ) ( ( ( unsigned long long ) ( address ) & ( 0x1FFULL << 39ULL ) ) >> 39ULL ) 75 | #define MiIndexLevel3( address ) ( ( ( unsigned long long ) ( address ) & ( 0x1FFULL << 30ULL ) ) >> 30ULL ) 76 | #define MiIndexLevel2( address ) ( ( ( unsigned long long ) ( address ) & ( 0x1FFULL << 21ULL ) ) >> 21ULL ) 77 | #define MiIndexLevel1( address ) ( ( ( unsigned long long ) ( address ) & ( 0x1FFULL << 12ULL ) ) >> 12ULL ) 78 | 79 | #define MiConstructAddress( index4, index3, index2, index1 ) \ 80 | ( ( void* )( ( ( unsigned long long )( index4 ) << 39ULL ) |\ 81 | ( ( unsigned long long )( index3 ) << 30ULL ) |\ 82 | ( ( unsigned long long )( index2 ) << 21ULL ) |\ 83 | ( ( unsigned long long )( index1 ) << 12ULL ) |\ 84 | ( ( ( unsigned long long )( index4 ) / 256 ) * 0xFFFF000000000000 ) ) ) 85 | -------------------------------------------------------------------------------- /examples/single_basic/kernel/memory.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | // 5 | // These define basic x86_64 specific structures 6 | // and macros for accessing page tables when using 7 | // recursive mappings, most are taken from Carbon. 8 | // Refer to the intel manual for more information. 9 | // 10 | 11 | typedef union _MMPTE_HARDWARE { 12 | struct { 13 | unsigned long long Present : 1; 14 | unsigned long long Write : 1; 15 | unsigned long long User : 1; 16 | unsigned long long WriteThrough : 1; 17 | unsigned long long CacheDisable : 1; 18 | unsigned long long Accessed : 1; 19 | unsigned long long Dirty : 1; 20 | unsigned long long Large : 1; 21 | unsigned long long Global : 1; 22 | unsigned long long Available0 : 3; 23 | unsigned long long PageFrame : 36; 24 | unsigned long long Reserved1 : 4; 25 | unsigned long long Available1 : 7; 26 | unsigned long long ProtectionKey : 4; 27 | unsigned long long ExecuteDisable : 1; 28 | } Table; 29 | 30 | struct { 31 | unsigned long long Present : 1; 32 | unsigned long long Write : 1; 33 | unsigned long long User : 1; 34 | unsigned long long WriteThrough : 1; 35 | unsigned long long CacheDisable : 1; 36 | unsigned long long Accessed : 1; 37 | unsigned long long Dirty : 1; 38 | unsigned long long PageAttribute : 1; 39 | unsigned long long Global : 1; 40 | unsigned long long Available0 : 3; 41 | unsigned long long PageFrame : 36; 42 | unsigned long long Reserved1 : 4; 43 | unsigned long long Available1 : 7; 44 | unsigned long long ProtectionKey : 4; 45 | unsigned long long ExecuteDisable : 1; 46 | } Entry; 47 | 48 | unsigned long long Long; 49 | } MMPTE_HARDWARE, *PMMPTE_HARDWARE; 50 | 51 | C_ASSERT( sizeof( MMPTE_HARDWARE ) == 8 ); 52 | 53 | #define MI_RECURSIVE_TABLE 0xFFFFFF0000000000ULL 54 | #define MI_RECURSIVE_INDEX 0x1FEULL 55 | 56 | #define MiReferenceLevel4Entry( index4 ) \ 57 | ( ( PMMPTE_HARDWARE )( MI_RECURSIVE_TABLE | \ 58 | ( MI_RECURSIVE_INDEX << 30ULL ) | \ 59 | ( MI_RECURSIVE_INDEX << 21ULL ) | \ 60 | ( ( ( unsigned long long ) ( index4 ) & 0x1FFULL ) << 12ULL) ) ) 61 | 62 | #define MiReferenceLevel3Entry( index4, index3 ) \ 63 | ( ( PMMPTE_HARDWARE )( MI_RECURSIVE_TABLE | \ 64 | ( MI_RECURSIVE_INDEX << 30ULL ) | \ 65 | ( ( ( unsigned long long )( index4 ) & 0x1FFULL ) << 21ULL) | \ 66 | ( ( ( unsigned long long )( index3 ) & 0x1FFULL ) << 12ULL) ) ) 67 | 68 | #define MiReferenceLevel2Entry( index4, index3, index2 ) \ 69 | ( ( PMMPTE_HARDWARE )( MI_RECURSIVE_TABLE | \ 70 | ( ( ( unsigned long long )( index4 ) & 0x1FFULL ) << 30ULL ) | \ 71 | ( ( ( unsigned long long )( index3 ) & 0x1FFULL ) << 21ULL ) | \ 72 | ( ( ( unsigned long long )( index2 ) & 0x1FFULL ) << 12ULL ) ) ) 73 | 74 | #define MiIndexLevel4( address ) ( ( ( unsigned long long ) ( address ) & ( 0x1FFULL << 39ULL ) ) >> 39ULL ) 75 | #define MiIndexLevel3( address ) ( ( ( unsigned long long ) ( address ) & ( 0x1FFULL << 30ULL ) ) >> 30ULL ) 76 | #define MiIndexLevel2( address ) ( ( ( unsigned long long ) ( address ) & ( 0x1FFULL << 21ULL ) ) >> 21ULL ) 77 | #define MiIndexLevel1( address ) ( ( ( unsigned long long ) ( address ) & ( 0x1FFULL << 12ULL ) ) >> 12ULL ) 78 | 79 | #define MiConstructAddress( index4, index3, index2, index1 ) \ 80 | ( ( void* )( ( ( unsigned long long )( index4 ) << 39ULL ) |\ 81 | ( ( unsigned long long )( index3 ) << 30ULL ) |\ 82 | ( ( unsigned long long )( index2 ) << 21ULL ) |\ 83 | ( ( unsigned long long )( index1 ) << 12ULL ) |\ 84 | ( ( ( unsigned long long )( index4 ) / 256 ) * 0xFFFF000000000000 ) ) ) 85 | -------------------------------------------------------------------------------- /examples/multi_basic/kernel/kernel.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | release 6 | x64 7 | 8 | 9 | 10 | 15.0 11 | {61486F4C-5BDB-4107-BD0C-94A6F0956F64} 12 | carbootexample 13 | 10.0.17763.0 14 | kernel 15 | 16 | 17 | 18 | Application 19 | false 20 | v141 21 | false 22 | MultiByte 23 | false 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\carboot\carbload\inc\ 36 | false 37 | $(SolutionDir)$(Configuration)\ 38 | kernel 39 | .sys 40 | 41 | 42 | 43 | Level3 44 | MaxSpeed 45 | true 46 | true 47 | 48 | 49 | true 50 | false 51 | MultiThreaded 52 | false 53 | $(SolutionDir)..\..\..\carboot\carbload\inc\ 54 | 55 | 56 | Native 57 | true 58 | true 59 | false 60 | KiSystemStartup 61 | true 62 | $(SolutionDir)$(Configuration)\hal.lib 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /carbload/inc/fat32.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #pragma pack( push, 1 ) 5 | 6 | typedef struct _MBR_PARTITION_ENTRY { 7 | UCHAR Attributes; 8 | UCHAR StartChs[ 3 ]; 9 | UCHAR Type; 10 | UCHAR EndChs[ 3 ]; 11 | ULONG32 StartLba; 12 | ULONG32 SectorCount; 13 | } MBR_PARTITION_ENTRY, *PMBR_PARTITION_ENTRY; 14 | 15 | typedef struct _MASTER_BOOT_RECORD { 16 | UCHAR BootCode[ 440 ]; 17 | ULONG32 UniqueDiskId; 18 | USHORT Reserved; 19 | MBR_PARTITION_ENTRY Table[ 4 ]; 20 | USHORT BootSignature; 21 | } MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD; 22 | 23 | typedef struct _BPB2_00 { 24 | CHAR FileSystemIdentifier[ 8 ]; 25 | USHORT BytesPerSector; 26 | UCHAR SectorsPerCluster; 27 | USHORT ReservedSectors; 28 | UCHAR FatCount; 29 | USHORT RootDirectoryEntriesCount; 30 | USHORT TotalSectors16; 31 | UCHAR MediaDesciptor; 32 | USHORT SectorsPerFat; 33 | } BPB2_00, *PBPB2_00; 34 | 35 | typedef struct _BPB3_31 { 36 | USHORT SectorsPerTrack; 37 | USHORT NumberOfHeads; 38 | ULONG32 HiddenSectors; 39 | ULONG32 TotalSectors32; 40 | } BPB3_31, *PBPB3_31; 41 | 42 | typedef struct _BPB7_01 { 43 | ULONG32 SectorsPerFat; 44 | USHORT MirroringFlags; 45 | USHORT FatVersion; 46 | ULONG32 RootDirectoryCluster; 47 | USHORT FileSystemInfoSector; 48 | USHORT BackupSectors; 49 | UCHAR Reserved[ 12 ]; 50 | UCHAR BootDisk; 51 | UCHAR NtFlags; 52 | UCHAR ExtendedBootSignature; 53 | ULONG32 SerialNumber; 54 | UCHAR VolumeLabel[ 11 ]; 55 | UCHAR SystemIdentifierString[ 8 ]; 56 | } BPB7_01, *PBPB7_01; 57 | 58 | typedef struct _VOLUME_BOOT_RECORD { 59 | CHAR Jump[ 3 ]; 60 | BPB2_00 Bpb2_00; 61 | BPB3_31 Bpb3_31; 62 | BPB7_01 Bpb7_01; 63 | UCHAR BootCode[ 420 ]; 64 | USHORT BootSignature; 65 | } VOLUME_BOOT_RECORD, *PVOLUME_BOOT_RECORD; 66 | 67 | #define FAT32_READ_ONLY 0x01 68 | #define FAT32_HIDDEN 0x02 69 | #define FAT32_SYSTEM 0x04 70 | #define FAT32_VOLUME_ID 0x08 71 | #define FAT32_DIRECTORY 0x10 72 | #define FAT32_ARCHIVE 0x20 73 | #define FAT32_LFN (FAT32_READ_ONLY | FAT32_HIDDEN | FAT32_SYSTEM | FAT32_VOLUME_ID) 74 | 75 | #define FAT32_END_OF_CHAIN 0x0FFFFFFF 76 | #define FAT32_DIRECTORY_ENTRY_FREE 0xE5 77 | #define FAT32_LAST_LFN_ENTRY 0x40 78 | 79 | typedef union _FAT_DIRECTORY { 80 | struct { 81 | CHAR Name[ 8 ]; 82 | CHAR Extension[ 3 ]; 83 | UCHAR Attributes; 84 | UCHAR Reserved; 85 | UCHAR CreateTimeTenth; 86 | USHORT CreateTime; 87 | USHORT CreateDate; 88 | USHORT AccessDate; 89 | USHORT ClusterHigh; 90 | USHORT ModifiedTime; 91 | USHORT ModifiedDate; 92 | USHORT ClusterLow; 93 | ULONG32 FileSize; 94 | } Short; 95 | 96 | struct { 97 | UCHAR OrderOfEntry; 98 | WCHAR First5Chars[ 5 ]; 99 | UCHAR Attributes; 100 | UCHAR LongEntryType; 101 | UCHAR NameChecksum; 102 | WCHAR Next6Chars[ 6 ]; 103 | USHORT Zero; 104 | WCHAR Next2Chars[ 2 ]; 105 | } Long; 106 | } FAT_DIRECTORY, *PFAT_DIRECTORY; 107 | 108 | #define FIRST_DATA_SECTOR( b ) ( ( b )->Bpb2_00.ReservedSectors + ( ( b )->Bpb2_00.FatCount * ( b )->Bpb7_01.SectorsPerFat ) ) 109 | #define FIRST_SECTOR_OF_CLUSTER( b, n ) ( ( ( ( n ) - 2 ) * ( b )->Bpb2_00.SectorsPerCluster ) + FIRST_DATA_SECTOR( b ) ) 110 | 111 | #pragma pack( pop ) 112 | -------------------------------------------------------------------------------- /carblegacy/load.asm: -------------------------------------------------------------------------------- 1 | 2 | BITS 16 3 | ORG 7c00h 4 | 5 | jmp InitLoad 6 | nop 7 | 8 | Bpb2_00: 9 | FileSystemIdentifier db "MSDOS5.0" 10 | BytesPerSector dw 512 11 | SectorsPerCluster db 0 12 | ReservedSectors dw 0 13 | FatCount db 2 14 | RootDirectoryEntriesCount dw 0 15 | TotalSectors16 dw 0 16 | MediaDescriptor db 0f8h 17 | SectorsPerFat16 dw 0 18 | 19 | Bpb3_31: 20 | SectorsPerTrack dw 0 21 | NumberOfHeads dw 0 22 | HiddenSectors dd 0 23 | TotalSectors32 dd 0 24 | 25 | Bpb7_01: 26 | SectorsPerFat32 dd 0 27 | MirroringFlags dw 0 28 | FatVersion dw 0 29 | RootDirectoryCluster dd 2 30 | FileSystemInfoSector dw 1 31 | BackupSectors dw 6 32 | TIMES 12 db 0 33 | BootDisk db 80h 34 | NtFlags db 0 35 | ExtendedBootSignature db 29h 36 | VolumeSerialNumber dd 0 37 | VolumeLabel db "NO NAME " 38 | SystemIdentifierString db "FAT32 " 39 | 40 | TIMES 90 - ($ - $$) db ' ' 41 | 42 | %DEFINE ptr 43 | 44 | ALIGN 4 45 | InitLoad: 46 | 47 | cli 48 | xor ax, ax 49 | mov ds, ax 50 | mov es, ax 51 | mov fs, ax 52 | mov gs, ax 53 | mov ss, ax 54 | mov esp, 7c00h 55 | mov byte [BootDisk], dl 56 | jmp 0:Load 57 | 58 | %INCLUDE "disk.asm" 59 | 60 | BdSystemDirectory db "SYSTEM " 61 | BdLoaderDirectoryFile db "CARBLOADSYS" 62 | 63 | BdLoaderBuffer dd 2000_0000h 64 | 65 | ALIGN 4 66 | 67 | Load: 68 | 69 | in al, 92h 70 | or al, 02h 71 | out 92h, al 72 | 73 | movzx eax, word ptr [BackupSectors] 74 | add eax, dword ptr [HiddenSectors] 75 | add eax, 3 76 | xor edx, edx 77 | mov ecx, 3 78 | mov ebx, 7e00h 79 | call BdReadSectors 80 | 81 | mov edx, 2 82 | mov ebx, dword ptr [BdLoaderBuffer] 83 | call BdFat32ReadCluster 84 | 85 | mov ebx, dword ptr [BdLoaderBuffer] 86 | mov eax, ebx 87 | mov ecx, BdSystemDirectory 88 | call BdFat32ReadDirectoryFile 89 | 90 | mov ebx, dword ptr [BdLoaderBuffer] 91 | mov eax, ebx 92 | mov ecx, BdLoaderDirectoryFile 93 | call BdFat32ReadDirectoryFile 94 | 95 | lgdt [GlobalDescriptorTable] 96 | mov eax, cr0 97 | or eax, 1 98 | mov cr0, eax 99 | 100 | mov ax, 16 101 | mov ds, ax 102 | mov es, ax 103 | mov fs, ax 104 | mov gs, ax 105 | mov ss, ax 106 | jmp 8:Load2 107 | 108 | BITS 32 109 | 110 | Load2: 111 | 112 | ; 32 bit code is all stdcall 113 | 114 | mov ecx, dword ptr [BdLoaderBuffer] 115 | shr ecx, 12 116 | add cx, word ptr [BdLoaderBuffer] 117 | push ecx 118 | call BdPe32LoadImage 119 | jmp eax 120 | 121 | SegmentTable: 122 | dq 0 123 | 124 | dw 0ffffh 125 | dw 0 126 | db 0 127 | db 10011010b ;db 10011010b 128 | db 11001111b 129 | db 0 130 | 131 | dw 0ffffh 132 | dw 0 133 | db 0 134 | db 10010010b 135 | db 11001111b 136 | db 0 137 | 138 | GlobalDescriptorTable: 139 | dw 17h 140 | dd SegmentTable 141 | 142 | %ASSIGN BYTES_LEFT 510 - ($ - $$) 143 | %WARNING SECTOR 0 HAS BYTES_LEFT BYTES LEFT. 144 | TIMES BYTES_LEFT db 0 145 | dw 0xAA55 146 | 147 | %INCLUDE "fat32.asm" 148 | %INCLUDE "pe32.asm" 149 | 150 | %ASSIGN BYTES_LEFT 2046 - ($ - $$) 151 | %WARNING SECTOR 1 HAS BYTES_LEFT BYTES LEFT. 152 | TIMES BYTES_LEFT db 0 153 | dw 0xAA55 -------------------------------------------------------------------------------- /examples/multi_basic/hal/hal.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | release 6 | x64 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15.0 14 | {4baee8c7-3989-4921-ab74-e6b3055158d2} 15 | hal 16 | 10.0.17763.0 17 | 18 | 19 | 20 | DynamicLibrary 21 | false 22 | v141 23 | 24 | 25 | Unicode 26 | 27 | 28 | 29 | false 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | .sys 42 | $(SolutionDir)\carbkrnl\inc\;$(VC_IncludePath); 43 | 44 | $(SolutionDir)$(Platform)\$(Configuration)\ 45 | 46 | $(VC_SourcePath); 47 | false 48 | $(SolutionDir)$(Configuration)\ 49 | 50 | 51 | 52 | Level4 53 | MaxSpeed 54 | true 55 | true 56 | 57 | 58 | true 59 | true 60 | 61 | true 62 | false 63 | MultiThreaded 64 | 8Bytes 65 | false 66 | false 67 | 68 | 69 | NoListing 70 | false 71 | 72 | 73 | FastCall 74 | CompileAsC 75 | false 76 | Speed 77 | 78 | 79 | true 80 | false 81 | $(SolutionDir)$(Configuration)\kernel.lib 82 | true 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Native 91 | false 92 | 93 | 94 | false 95 | false 96 | 97 | false 98 | true 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /carblegacy/fat32.asm: -------------------------------------------------------------------------------- 1 | 2 | BITS 16 3 | 4 | %DEFINE CLUSTER_LOWER 26 5 | %DEFINE CLUSTER_UPPER 20 6 | 7 | BpFat32FirstClusterBlockAddress: 8 | 9 | ; 10 | ; evaluates the formula below, taken 11 | ; from fatgen103. 12 | ; 13 | ; Bpb->Dos2_00Bpb.ReservedSectors + 14 | ; Bpb->Dos3_31Bpb.HiddenSectors + 15 | ; Bpb->Dos2_00Bpb.FatCount * 16 | ; Bpb->Dos7_01Bpb.SectorsPerFat 17 | ; 18 | 19 | push ebx 20 | push edx 21 | 22 | movzx ax, byte ptr [FatCount] 23 | mul word ptr [SectorsPerFat32] 24 | 25 | mov bx, dx 26 | shl ebx, 16 27 | mov bx, ax 28 | 29 | add bx, word ptr [ReservedSectors] 30 | add ebx, dword ptr [HiddenSectors] 31 | 32 | mov eax, ebx 33 | pop edx 34 | pop ebx 35 | ret 36 | 37 | BdFat32ReadCluster: 38 | 39 | ; 40 | ; EDX = ClusterNumber 41 | ; EBX = Segment:Offset 42 | ; Read's the cluster specified by EDX 43 | ; into the buffer specified by EBX. 44 | ; 45 | 46 | pushad 47 | push ebx 48 | 49 | call BpFat32FirstClusterBlockAddress 50 | mov ebx, eax 51 | 52 | ; 53 | ; the fat32, 2 cluster sub 54 | ; 55 | 56 | sub edx, 2 57 | 58 | ; 59 | ; calculate FirstCluster + SectorsPerCluster * ClusterNumber 60 | ; 61 | 62 | movzx eax, byte ptr [SectorsPerCluster] 63 | mul edx 64 | add eax, ebx 65 | 66 | pop ebx 67 | movzx cx, byte ptr [SectorsPerCluster] 68 | call BdReadSectors 69 | 70 | popad 71 | ret 72 | 73 | BdFat32ReadClusterChain: 74 | 75 | ; 76 | ; EDX = ClusterNumber 77 | ; EBX = Segment:Offset 78 | ; 79 | ; returns: 80 | ; EBX = Segment:Offset of next free memory 81 | ; region. 82 | ; 83 | ; Reads a chain of clusters. 84 | ; 85 | 86 | pushad 87 | 88 | .BpFat32ChainLoop: 89 | call BdFat32ReadCluster 90 | push ebx 91 | 92 | ; 93 | ; calculates the EDX = FatSectorIndex and 94 | ; EAX = FatSectorOffset 95 | ; 96 | 97 | mov eax, 4 98 | mul edx 99 | movzx ecx, word ptr [BytesPerSector] 100 | div ecx 101 | 102 | ; 103 | ; this code reads the FatSectorIndex into memory 104 | ; 105 | 106 | push edx 107 | xor edx, edx 108 | 109 | add ax, word ptr [ReservedSectors] 110 | add eax, dword ptr [HiddenSectors] 111 | mov ebx, 4000h 112 | mov cx, 1 113 | call BdReadSectors 114 | 115 | ; 116 | ; load the new cluster number in edx 117 | ; and use (SectorsPerCluster * BytesPerSector) / 0x10 to 118 | ; calculate a new segment:offset pointer. (we're currently 119 | ; ignoring the offset field of segment:offset pointers) 120 | ; 121 | 122 | pop edx 123 | mov edx, dword ptr [edx+4000h] 124 | push edx 125 | 126 | movzx eax, byte ptr [SectorsPerCluster] 127 | mov cx, word ptr [BytesPerSector] 128 | mul cx 129 | mov bx, 16 130 | div bx 131 | 132 | mov ecx, eax 133 | shl ecx, 16 134 | 135 | pop edx 136 | pop ebx 137 | add ebx, ecx 138 | cmp edx, 0x0fffffff 139 | jne .BpFat32ChainLoop 140 | 141 | mov dword [esp+16], ebx 142 | popad 143 | ret 144 | 145 | BdFat32ReadDirectoryFile: 146 | 147 | ; 148 | ; EAX = Directory 149 | ; EBX = Segment:Offset 150 | ; CX = FileNameOffset 151 | ; reads a fat32 file from a directory 152 | ; uses 4000h as a temporary buffer. 153 | ; 154 | 155 | pushad 156 | mov ax, es 157 | push eax 158 | push ebx 159 | mov bx, cx 160 | 161 | mov di, ax 162 | shr eax, 16 163 | mov es, ax 164 | 165 | ; 166 | ; check each entry in the directory 167 | ; comparing the 11 char name to the one 168 | ; passed to this function, if the first byte 169 | ; is 0, we can assume that is the end of the 170 | ; directory listing, and jump to a failure 171 | ; handler. 172 | ; 173 | 174 | .BpFat32DirectoryEntry: 175 | add di, 32 176 | mov si, bx 177 | cmp byte ptr es:[di], 0 178 | je .BpFat32Failure 179 | 180 | push edi 181 | mov cx, 11 182 | repe cmpsb 183 | pop edi 184 | jne .BpFat32DirectoryEntry 185 | 186 | ; 187 | ; the code escaped the directory loop, 188 | ; meaning it must've found our entry. 189 | ; EDX = ClusterNumber 190 | ; 191 | 192 | mov dx, word ptr es:[di+CLUSTER_UPPER] 193 | shl edx, 16 194 | mov dx, word ptr es:[di+CLUSTER_LOWER] 195 | 196 | pop ebx 197 | 198 | call BdFat32ReadClusterChain 199 | jmp .BpFat32Success 200 | 201 | .BpFat32Failure: 202 | mov eax, 0D3ADB00Bh 203 | cli 204 | hlt 205 | .BpFat32Success: 206 | 207 | pop eax 208 | mov es, ax 209 | mov dword ptr [esp+16], ebx 210 | popad 211 | ret -------------------------------------------------------------------------------- /carblegacy/pe32.asm: -------------------------------------------------------------------------------- 1 | 2 | BITS 32 3 | 4 | %DEFINE sizeof_FileHeader 14h 5 | %DEFINE sizeof_SectionHeader 28h 6 | %DEFINE sizeof_DataDirectory 08h 7 | %DEFINE sizeof_BaseReloc 08h 8 | 9 | %DEFINE dos_e_lfanew 3ch 10 | 11 | %DEFINE nt_FileHeader 4h 12 | %DEFINE nt_OptionalHeader nt_FileHeader+sizeof_FileHeader 13 | 14 | %DEFINE fh_SizeOfOptionalHeader 10h 15 | %DEFINE fh_NumberOfSections 2h 16 | 17 | %DEFINE oh_AddressOfEntryPoint 10h 18 | %DEFINE oh_ImageBase 1ch 19 | %DEFINE oh_SizeOfHeaders 3ch 20 | %DEFINE oh_DataDirectory 60h 21 | 22 | %DEFINE sh_VirtualSize 8h 23 | %DEFINE sh_VirtualAddress 0ch 24 | %DEFINE sh_RawSize 10h 25 | %DEFINE sh_RawAddress 14h 26 | %DEFINE sh_Characteristics 24h 27 | 28 | %DEFINE br_VirtualAddress 0h 29 | %DEFINE br_SizeOfBlock 4h 30 | 31 | BdPe32LoadImage: 32 | 33 | ; STDCALL ULONG32 BdPe32( ULONG32 FileBase ); 34 | 35 | %DEFINE FileBase +64 36 | %DEFINE HeaderDos +4 37 | %DEFINE HeaderNt +8 38 | %DEFINE ImageBase +12 39 | %DEFINE HeaderSections +16 40 | %DEFINE CurrentSection +20 41 | %DEFINE CurrentSectionAddress +24 42 | %DEFINE PreviousSectionImage +28 43 | %DEFINE PreviousSectionFile +32 44 | %DEFINE BaseReloc +36 45 | %DEFINE BaseDelta +40 46 | %DEFINE CurrentReloc +44 47 | 48 | push ebp 49 | push esi 50 | push edi 51 | sub esp, 48 52 | 53 | mov esi, dword ptr FileBase[esp] 54 | mov edx, esi 55 | add edx, dword ptr [esi+dos_e_lfanew] 56 | 57 | movzx eax, word ptr [edx+nt_FileHeader+fh_SizeOfOptionalHeader] 58 | lea eax, [eax+edx+nt_OptionalHeader] 59 | mov ecx, dword ptr [edx+nt_OptionalHeader+oh_SizeOfHeaders] 60 | mov edi, 40000h 61 | 62 | ; Esi = Dos 63 | ; Edx = Nt 64 | ; Ecx = SizeOfHeaders 65 | ; Eax = SectionHeaders 66 | ; Edi = ImageBase 67 | 68 | mov dword ptr HeaderDos[esp], esi 69 | mov dword ptr ImageBase[esp], edi 70 | mov dword ptr HeaderNt[esp], edx 71 | mov dword ptr HeaderSections[esp], eax 72 | 73 | cld 74 | rep movsb 75 | 76 | mov esi, dword ptr HeaderDos[esp] 77 | mov edi, dword ptr ImageBase[esp] 78 | 79 | movzx ebp, word ptr [edx+nt_FileHeader+fh_NumberOfSections] 80 | xor ecx, ecx 81 | .BpPe32LoadSection: 82 | mov dword ptr CurrentSection[esp], ecx 83 | imul ecx, sizeof_SectionHeader 84 | 85 | mov eax, dword ptr HeaderSections[esp] 86 | add eax, ecx 87 | mov dword ptr CurrentSectionAddress[esp], eax 88 | 89 | mov esi, dword ptr HeaderDos[esp] 90 | mov edi, dword ptr ImageBase[esp] 91 | add esi, dword ptr [eax+sh_RawAddress] 92 | add edi, dword ptr [eax+sh_VirtualAddress] 93 | 94 | cld 95 | mov ecx, dword ptr [eax+sh_VirtualAddress] 96 | mov dword ptr PreviousSectionFile[esp], esi 97 | mov dword ptr PreviousSectionImage[esp], edi 98 | xor eax, eax 99 | rep stosb 100 | mov eax, dword ptr HeaderSections[esp] 101 | mov ecx, dword ptr [eax+sh_VirtualSize] 102 | mov esi, dword ptr PreviousSectionFile[esp] 103 | mov edi, dword ptr PreviousSectionImage[esp] 104 | rep movsb 105 | 106 | mov ecx, dword ptr CurrentSection[esp] 107 | inc ecx 108 | cmp ecx, ebp 109 | jne .BpPe32LoadSection 110 | 111 | mov esi, dword ptr HeaderDos[esp] 112 | mov edi, dword ptr ImageBase[esp] 113 | mov edx, dword ptr HeaderNt[esp] 114 | mov ecx, edi 115 | sub ecx, dword ptr [edx+nt_OptionalHeader+oh_ImageBase] 116 | 117 | mov eax, dword ptr [edx+nt_OptionalHeader+oh_DataDirectory+5*sizeof_DataDirectory] 118 | test eax, eax 119 | jz .BpPe32Success 120 | add eax, edi 121 | 122 | ; Ecx = BaseDelta 123 | ; Eax = BaseReloc 124 | 125 | mov dword ptr BaseDelta[esp], ecx 126 | mov dword ptr BaseReloc[esp], eax 127 | 128 | .BpPe32Reloc: 129 | cmp dword ptr [eax+br_VirtualAddress], 0 130 | je .BpPe32Success 131 | 132 | mov dword ptr BaseReloc[esp], eax 133 | mov ecx, dword ptr [eax+br_SizeOfBlock] 134 | cmp ecx, sizeof_BaseReloc 135 | jle .BpPe32AdvanceReloc 136 | 137 | sub ecx, sizeof_BaseReloc 138 | add eax, sizeof_BaseReloc 139 | .BpPe32RelocThunk: 140 | cmp word ptr [eax], 0 141 | je .BpPe32ThunkClean 142 | 143 | mov dword ptr CurrentReloc[esp], ecx 144 | movzx ecx, word ptr [eax] 145 | and ecx, 0fffh 146 | mov ebp, dword ptr BaseReloc[esp] 147 | add ecx, dword ptr [ebp+br_VirtualAddress] 148 | add ecx, dword ptr ImageBase[esp] 149 | mov ebp, dword ptr BaseDelta[esp] 150 | add dword ptr [ecx], ebp 151 | mov ecx, dword ptr CurrentReloc[esp] 152 | 153 | .BpPe32ThunkClean: 154 | add eax, 2 155 | sub ecx, 2 156 | jnz .BpPe32RelocThunk 157 | .BpPe32AdvanceReloc: 158 | mov eax, dword ptr BaseReloc[esp] 159 | add eax, dword ptr [eax+br_SizeOfBlock] 160 | jmp .BpPe32Reloc 161 | 162 | .BpPe32Failure: 163 | mov eax, 0D3ADB00Bh 164 | cli 165 | hlt 166 | .BpPe32Success: 167 | mov eax, dword ptr HeaderNt[esp] 168 | mov eax, dword ptr [eax+nt_OptionalHeader+oh_AddressOfEntryPoint] 169 | add eax, dword ptr ImageBase[esp] 170 | 171 | add esp, 48 172 | pop edi 173 | pop esi 174 | pop ebp 175 | ret 4 176 | -------------------------------------------------------------------------------- /carbload/inc/loader.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #define KERNEL_FILE_NAME "KERNEL.SYS" 5 | 6 | #define _In_ 7 | #define _Out_ 8 | 9 | #define EXTERN extern 10 | #define STATIC static 11 | #define NORETURN __declspec(noreturn) 12 | #define BPAPI __stdcall 13 | #define FIELD_OFFSET(x, y) ( ( ULONG32 )&( ( ( x* )0 )->y ) ) 14 | 15 | #define C_ASSERT( x ) static_assert( x, #x ) 16 | 17 | #define VOID void 18 | #define NULL 0 19 | 20 | #define LOADER_BASIC_TYPES_DEFINED 21 | 22 | typedef unsigned long long ULONG64, *PULONG64; 23 | typedef unsigned long ULONG32, *PULONG32; 24 | typedef unsigned short USHORT, *PUSHORT; 25 | typedef unsigned char UCHAR, *PUCHAR; 26 | 27 | typedef long long LONG64, *PLONG64; 28 | typedef long LONG32, *PLONG32; 29 | typedef short SHORT, *PSHORT; 30 | typedef char CHAR, *PCHAR, *PSTR; 31 | 32 | typedef VOID* PVOID; 33 | 34 | typedef short WCHAR, *PWCHAR; 35 | 36 | typedef char* va_list; 37 | 38 | typedef long NTSTATUS; 39 | 40 | #define STATUS_SUCCESS ( 0x00000000 ) 41 | #define STATUS_INVALID_IMAGE ( 0xC0000000 ) 42 | #define STATUS_NOT_FOUND ( 0xC0000001 ) 43 | 44 | #define NT_SUCCESS( status ) ( status >= 0 ) 45 | 46 | #include "pe64.h" 47 | #include "fat32.h" 48 | #include "x86_64.h" 49 | 50 | #include "ldef.h" 51 | 52 | EXTERN LOADER_BLOCK Loader; 53 | EXTERN ULONG32 BpBootDisk; 54 | 55 | #define ROUND_TO_PAGES( Length ) ( ( ( Length ) + 0xFFF ) & ~0xFFF ) 56 | 57 | VOID 58 | BpDisplayString( 59 | _In_ PSTR Format, 60 | _In_ ... 61 | ); 62 | 63 | NORETURN 64 | VOID 65 | BpFatalException( 66 | _In_ PSTR Format, 67 | _In_ ... 68 | ); 69 | 70 | VOID 71 | BPAPI 72 | BdInitMap( 73 | 74 | ); 75 | 76 | VOID 77 | BPAPI 78 | BdInitGraphics( 79 | 80 | ); 81 | 82 | VOID 83 | BPAPI 84 | BdInitFile( 85 | 86 | ); 87 | 88 | VOID 89 | BPAPI 90 | BdDiskRead( 91 | _Out_ PVOID Buffer, 92 | _In_ ULONG32 BlockAddress, 93 | _In_ USHORT SectorCount 94 | ); 95 | 96 | VOID 97 | BPAPI 98 | BdFat32QueryFatTable( 99 | _In_ PVOLUME_BOOT_RECORD BootRecord, 100 | _In_ ULONG32 Index, 101 | _Out_ ULONG32* Link 102 | ); 103 | 104 | VOID 105 | BPAPI 106 | BdFat32ReadCluster( 107 | _In_ PVOLUME_BOOT_RECORD BootRecord, 108 | _In_ ULONG32 Number, 109 | _Out_ PVOID Buffer 110 | ); 111 | 112 | ULONG32 113 | BPAPI 114 | BdFat32ReadClusterChain( 115 | _In_ PVOLUME_BOOT_RECORD BootRecord, 116 | _In_ ULONG32 Number, 117 | _Out_ PVOID Buffer 118 | ); 119 | 120 | ULONG32 121 | BPAPI 122 | BdFat32ReadDirectoryFile( 123 | _In_ PVOLUME_BOOT_RECORD BootRecord, 124 | _In_ PFAT_DIRECTORY Directory, 125 | _In_ PCHAR Name, 126 | _Out_ PVOID Buffer 127 | ); 128 | 129 | ULONG64 130 | BPAPI 131 | BdAddress64( 132 | _In_ ULONG32 Address32 133 | ); 134 | 135 | VOID 136 | BPAPI 137 | BdTranslateLoader( 138 | 139 | ); 140 | 141 | NTSTATUS 142 | LdrGetExportAddressByName( 143 | _In_ PVOID Base, 144 | _In_ PCHAR Name, 145 | _Out_ ULONG64* Address 146 | ); 147 | 148 | NTSTATUS 149 | LdrGetExportAddressByOrdinal( 150 | _In_ PVOID Base, 151 | _In_ USHORT Ordinal, 152 | _Out_ ULONG64* Address 153 | ); 154 | 155 | NTSTATUS 156 | LdrResolveBaseReloc( 157 | _In_ ULONG32 BaseAddress 158 | ); 159 | 160 | NTSTATUS 161 | LdrResolveImportTable( 162 | _In_ PVOID Importer, 163 | _In_ PVOID Importee, 164 | _In_ PIMAGE_IMPORT_DESCRIPTOR Import 165 | ); 166 | 167 | NTSTATUS 168 | LdrLoadSystemModule( 169 | _In_ PVOLUME_BOOT_RECORD BootRecord, 170 | _In_ PLOADER_BOOT_FILE BootFile, 171 | _In_ ULONG32 BaseAddress 172 | ); 173 | 174 | ULONG32 175 | LdrEntryPoint( 176 | _In_ ULONG32 BaseAddress 177 | ); 178 | 179 | void __cdecl __va_start( va_list*, ... ); 180 | void* __cdecl __va_arg( va_list*, ... ); 181 | void __cdecl __va_end( va_list* ); 182 | 183 | #define _ADDRESSOF(v) (&(v)) 184 | #define _SLOTSIZEOF(t) (sizeof(t)) 185 | #define _APALIGN(t,ap) (__alignof(t)) 186 | 187 | #define __crt_va_start(ap, v) ((void)(__va_start(&ap, _ADDRESSOF(v), _SLOTSIZEOF(v), __alignof(v), _ADDRESSOF(v)))) 188 | #define __crt_va_arg(ap, t) (*(t *)__va_arg(&ap, _SLOTSIZEOF(t), _APALIGN(t,ap), (t*)0)) 189 | #define __crt_va_end(ap) ((void)(__va_end(&ap))) 190 | 191 | VOID 192 | BPAPI 193 | RtlFormatAnsiStringFromList( 194 | _In_ PSTR Buffer, 195 | _In_ PSTR Format, 196 | _In_ va_list List 197 | ); 198 | 199 | VOID 200 | RtlFormatAnsiString( 201 | _In_ PSTR Buffer, 202 | _In_ PSTR Format, 203 | _In_ ... 204 | ); 205 | 206 | LONG32 207 | RtlCompareAnsiString( 208 | _In_ PSTR String1, 209 | _In_ PSTR String2, 210 | _In_ UCHAR CaseInsensitive 211 | ); 212 | 213 | VOID 214 | RtlFillMemory( 215 | _In_ PVOID Destination, 216 | _In_ ULONG32 Fill, 217 | _In_ ULONG32 Length 218 | ); 219 | 220 | VOID 221 | RtlCopyMemory( 222 | _In_ PVOID Destination, 223 | _In_ PVOID Source, 224 | _In_ ULONG32 Length 225 | ); 226 | 227 | #define RtlUpperChar( c ) ( ( c ) >= 'a' && ( c ) <= 'z' ? ( c ) - ' ' : ( c ) ) 228 | #define RtlLowerChar( c ) ( ( c ) >= 'A' && ( c ) <= 'Z' ? ( c ) + ' ' : ( c ) ) 229 | 230 | VOID 231 | BPAPI 232 | BdFindSystemFile( 233 | _In_ PSTR Name, 234 | _Out_ PLOADER_SYSTEM_MAP* Map 235 | ); 236 | 237 | VOID 238 | BPAPI 239 | BdFindBootFile( 240 | _In_ PSTR Name, 241 | _Out_ PLOADER_BOOT_FILE* BootFile 242 | ); 243 | -------------------------------------------------------------------------------- /carbload/rtl.c: -------------------------------------------------------------------------------- 1 | 2 | #include "loader.h" 3 | 4 | VOID 5 | RtlFillMemory( 6 | _In_ PVOID Destination, 7 | _In_ ULONG32 Fill, 8 | _In_ ULONG32 Length 9 | ) 10 | { 11 | __stosb( Destination, Fill, Length ); 12 | } 13 | 14 | VOID 15 | RtlCopyMemory( 16 | _In_ PVOID Destination, 17 | _In_ PVOID Source, 18 | _In_ ULONG32 Length 19 | ) 20 | { 21 | __movsb( Destination, Source, Length ); 22 | } 23 | 24 | LONG32 25 | RtlCompareAnsiString( 26 | _In_ PSTR String1, 27 | _In_ PSTR String2, 28 | _In_ UCHAR CaseInsensitive 29 | ) 30 | { 31 | if ( CaseInsensitive ) { 32 | while ( *String1 && *String2 && RtlUpperChar( *String1 ) == RtlUpperChar( *String2 ) ) 33 | String1++, String2++; 34 | return RtlUpperChar( *String1 ) - RtlUpperChar( *String2 ); 35 | } 36 | else { 37 | while ( *String1 && *String2 && *String1 == *String2 ) 38 | String1++, String2++; 39 | return *String1 - *String2; 40 | } 41 | } 42 | 43 | ULONG32 44 | RtlLengthAnsiString( 45 | _In_ PSTR Buffer 46 | ) 47 | { 48 | ULONG32 Index = 0; 49 | 50 | while ( Buffer[ Index ] ) 51 | Index++; 52 | 53 | return Index; 54 | } 55 | 56 | VOID 57 | RtlReverseAnsiString( 58 | _In_ PSTR Buffer 59 | ) 60 | { 61 | ULONG32 Char_1, Char_2; 62 | CHAR Intermediate; 63 | 64 | Char_1 = 0; 65 | Char_2 = RtlLengthAnsiString( Buffer ) - 1; 66 | 67 | for ( ; Char_1 < Char_2; Char_1++, Char_2-- ) { 68 | 69 | Intermediate = Buffer[ Char_1 ]; 70 | Buffer[ Char_1 ] = Buffer[ Char_2 ]; 71 | Buffer[ Char_2 ] = Intermediate; 72 | } 73 | } 74 | 75 | VOID 76 | RtlIntToAnsiString( 77 | _In_ LONG32 Long, 78 | _In_ ULONG32 Base, 79 | _In_ PSTR Buffer 80 | ) 81 | { 82 | UCHAR Temp; 83 | ULONG32 Index; 84 | ULONG32 Neg; 85 | 86 | Index = 0; 87 | Neg = 0; 88 | if ( Long == 0 ) { 89 | Buffer[ Index++ ] = '0'; 90 | Buffer[ Index ] = 0; 91 | return; 92 | } 93 | 94 | if ( Base == 10 && Long < 0 ) { 95 | Neg = 1; 96 | Long = -Long; 97 | } 98 | 99 | while ( Long != 0 ) { 100 | Temp = Long % Base; 101 | Buffer[ Index++ ] = Temp > 9 ? Temp - 10 + 'a' : Temp + '0'; 102 | Long /= Base; 103 | } 104 | 105 | if ( Neg ) { 106 | 107 | Buffer[ Index++ ] = '-'; 108 | } 109 | Buffer[ Index ] = 0; 110 | 111 | RtlReverseAnsiString( Buffer ); 112 | } 113 | 114 | VOID 115 | BPAPI 116 | RtlFormatAnsiStringFromList( 117 | _In_ PSTR Buffer, 118 | _In_ PSTR Format, 119 | _In_ va_list List 120 | ) 121 | { 122 | ULONG32 Index; 123 | ULONG32 Base; 124 | ULONG32 Lower; 125 | ULONG32 Upper; 126 | ULONG32 Prepad; 127 | ULONG32 Current; 128 | CHAR LowerBuffer[ 16 ]; 129 | CHAR UpperBuffer[ 16 ]; 130 | PSTR String; 131 | 132 | Index = 0; 133 | while ( *Format ) { 134 | if ( *Format != '%' ) { 135 | 136 | Buffer[ Index++ ] = *Format++; 137 | continue; 138 | } 139 | else { 140 | 141 | Format++; 142 | } 143 | 144 | switch ( *Format ) { 145 | case '%': 146 | Buffer[ Index++ ] = *Format++; 147 | break; 148 | case 'l': 149 | Format++; 150 | 151 | Base = 10; 152 | 153 | if ( *Format == 'l' ) { 154 | Format++; 155 | 156 | if ( *Format == 'x' ) { 157 | 158 | Base = 16; 159 | Format++; 160 | } 161 | 162 | Lower = __crt_va_arg( List, ULONG32 ); 163 | Upper = __crt_va_arg( List, ULONG32 ); 164 | 165 | RtlIntToAnsiString( Lower, Base, LowerBuffer ); 166 | RtlIntToAnsiString( Upper, Base, UpperBuffer ); 167 | Prepad = 8 - RtlLengthAnsiString( LowerBuffer ); 168 | 169 | for ( Current = 0; Current < Prepad; Current++, Index++ ) { 170 | Buffer[ Index ] = '0'; 171 | } 172 | 173 | for ( Current = 0; UpperBuffer[ Current ]; Current++, Index++ ) { 174 | Buffer[ Index ] = UpperBuffer[ Current ]; 175 | } 176 | 177 | for ( Current = 0; LowerBuffer[ Current ]; Current++, Index++ ) { 178 | Buffer[ Index ] = LowerBuffer[ Current ]; 179 | } 180 | } 181 | else { 182 | 183 | if ( *Format == 'x' ) { 184 | 185 | Base = 16; 186 | Format++; 187 | } 188 | 189 | Lower = __crt_va_arg( List, ULONG32 ); 190 | 191 | RtlIntToAnsiString( Lower, Base, LowerBuffer ); 192 | 193 | for ( Current = 0; LowerBuffer[ Current ]; Current++, Index++ ) { 194 | Buffer[ Index ] = LowerBuffer[ Current ]; 195 | } 196 | } 197 | break; 198 | case 's': 199 | Format++; 200 | String = __crt_va_arg( List, PSTR ); 201 | 202 | for ( Current = 0; String[ Current ]; Current++, Index++ ) { 203 | Buffer[ Index ] = String[ Current ]; 204 | } 205 | break; 206 | default: 207 | break; 208 | } 209 | } 210 | 211 | Buffer[ Index ] = 0; 212 | } 213 | 214 | VOID 215 | RtlFormatAnsiString( 216 | _In_ PSTR Buffer, 217 | _In_ PSTR Format, 218 | _In_ ... 219 | ) 220 | { 221 | va_list List; 222 | __crt_va_start( List, Format ); 223 | RtlFormatAnsiStringFromList( Buffer, 224 | Format, 225 | List ); 226 | __crt_va_end( List ); 227 | } 228 | -------------------------------------------------------------------------------- /carbload/bios/file.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | VOID 5 | BPAPI 6 | BdLoadBootFile( 7 | _In_ PVOLUME_BOOT_RECORD BootRecord, 8 | _In_ ULONG32 BaseAddress, 9 | _In_ PFAT_DIRECTORY Directory, 10 | _In_ PSTR FileName, 11 | _Out_ PLOADER_BOOT_FILE BootFile 12 | ) 13 | { 14 | BootFile->BaseAddress = BaseAddress; 15 | BootFile->Length = BdFat32ReadDirectoryFile( BootRecord, 16 | Directory, 17 | FileName, 18 | ( PVOID )BaseAddress ); 19 | RtlCopyMemory( BootFile->FileName, FileName, 11 ); 20 | BootFile->FileName[ 11 ] = 0; 21 | } 22 | 23 | VOID 24 | BPAPI 25 | BdFatName( 26 | _In_ PSTR Name, 27 | _Out_ PSTR FatName 28 | ) 29 | { 30 | ULONG32 Index; 31 | 32 | RtlFillMemory( FatName, ' ', 11 ); 33 | FatName[ 11 ] = 0; 34 | 35 | for ( Index = 0; 36 | Index < 11 && 37 | Name[ Index ] != '.' && 38 | Name[ Index ] != 0; 39 | Index++ ) { 40 | 41 | FatName[ Index ] = RtlUpperChar( Name[ Index ] ); 42 | } 43 | 44 | if ( Name[ Index ] == '.' ) { 45 | 46 | FatName[ 8 ] = RtlUpperChar( Name[ Index + 1 ] ); 47 | FatName[ 9 ] = RtlUpperChar( Name[ Index + 2 ] ); 48 | FatName[ 10 ] = RtlUpperChar( Name[ Index + 3 ] ); 49 | } 50 | } 51 | 52 | VOID 53 | BPAPI 54 | BdFindSystemFile( 55 | _In_ PSTR Name, 56 | _Out_ PLOADER_SYSTEM_MAP* Map 57 | ) 58 | { 59 | ULONG32 CurrentMap; 60 | CHAR FileName[ 12 ]; 61 | 62 | BdFatName( Name, FileName ); 63 | 64 | *Map = NULL; 65 | 66 | for ( CurrentMap = 0; CurrentMap < Loader.MapCount; CurrentMap++ ) { 67 | 68 | if ( Loader.MapList[ CurrentMap ].BootFile == NULL ) { 69 | 70 | continue; 71 | } 72 | 73 | if ( RtlCompareAnsiString( FileName, 74 | Loader.MapList[ CurrentMap ].BootFile->FileName, 75 | 1 ) == 0 ) { 76 | 77 | *Map = &Loader.MapList[ CurrentMap ]; 78 | return; 79 | } 80 | } 81 | } 82 | 83 | VOID 84 | BPAPI 85 | BdFindBootFile( 86 | _In_ PSTR Name, 87 | _Out_ PLOADER_BOOT_FILE* BootFile 88 | ) 89 | { 90 | ULONG32 CurrentFile; 91 | CHAR FileName[ 12 ]; 92 | 93 | BdFatName( Name, FileName ); 94 | 95 | *BootFile = NULL; 96 | 97 | for ( CurrentFile = 0; CurrentFile < Loader.FileCount; CurrentFile++ ) { 98 | 99 | if ( RtlCompareAnsiString( FileName, Loader.FileList[ CurrentFile ].FileName, 1 ) == 0 ) { 100 | 101 | *BootFile = &Loader.FileList[ CurrentFile ]; 102 | return; 103 | } 104 | } 105 | } 106 | 107 | VOID 108 | BPAPI 109 | BdInitFile( 110 | 111 | ) 112 | { 113 | PVOLUME_BOOT_RECORD BootRecord = ( PVOLUME_BOOT_RECORD )0x7C00; 114 | PFAT_DIRECTORY RootDirectory = ( PFAT_DIRECTORY )0x200000; 115 | PFAT_DIRECTORY CurrentDirectory; 116 | ULONG32 Length; 117 | ULONG32 CurrentFile; 118 | ULONG32 CurrentBase; 119 | CHAR FatName[ 12 ]; 120 | 121 | BpBootDisk = BootRecord->Bpb7_01.BootDisk; 122 | 123 | Loader.LoaderSig = 'BRAC'; 124 | Loader.RootSerial = BootRecord->Bpb7_01.SerialNumber; 125 | 126 | BdFat32ReadCluster( BootRecord, 127 | 2, 128 | RootDirectory ); 129 | 130 | CurrentDirectory = RootDirectory + BootRecord->Bpb2_00.SectorsPerCluster * 512; 131 | CurrentBase = ( ULONG32 )CurrentDirectory; 132 | Length = BdFat32ReadDirectoryFile( BootRecord, 133 | RootDirectory, 134 | "SYSTEM ", 135 | CurrentDirectory ); 136 | if ( Length == 0 ) { 137 | 138 | BpFatalException( "FATAL: failed to find SYSTEM directory." ); 139 | } 140 | 141 | BdFatName( KERNEL_FILE_NAME, FatName ); 142 | 143 | CurrentBase += Length; 144 | BdLoadBootFile( BootRecord, 145 | CurrentBase, 146 | CurrentDirectory, 147 | FatName, 148 | &Loader.FileList[ Loader.FileCount ] ); 149 | if ( Loader.FileList[ Loader.FileCount ].Length == 0 ) { 150 | 151 | BpFatalException( "FATAL: failed to find kernel module." ); 152 | } 153 | 154 | CurrentBase += Loader.FileList[ Loader.FileCount++ ].Length; 155 | 156 | Length = BdFat32ReadDirectoryFile( BootRecord, 157 | CurrentDirectory, 158 | "BOOT ", 159 | CurrentDirectory ); 160 | 161 | if ( Length == 0 ) { 162 | 163 | BpFatalException( "FATAL: failed to find BOOT directory." ); 164 | } 165 | 166 | for ( CurrentFile = 0; 167 | CurrentDirectory[ CurrentFile ].Short.Name[ 0 ] != 0; 168 | CurrentFile++ ) { 169 | 170 | if ( ( UCHAR )CurrentDirectory[ CurrentFile ].Short.Name[ 0 ] == ( UCHAR )0xE5 ) { 171 | 172 | continue; 173 | } 174 | 175 | if ( ( UCHAR )CurrentDirectory[ CurrentFile ].Short.Attributes & FAT32_DIRECTORY || 176 | ( UCHAR )CurrentDirectory[ CurrentFile ].Short.Attributes & FAT32_VOLUME_ID || 177 | ( ( UCHAR )CurrentDirectory[ CurrentFile ].Short.Attributes & FAT32_ARCHIVE ) == 0 ) { 178 | 179 | continue; 180 | } 181 | 182 | Loader.FileList[ Loader.FileCount ].BaseAddress = CurrentBase; 183 | Loader.FileList[ Loader.FileCount ].Length = 184 | BdFat32ReadClusterChain( BootRecord, 185 | CurrentDirectory[ CurrentFile ].Short.ClusterLow | 186 | CurrentDirectory[ CurrentFile ].Short.ClusterHigh << 16, 187 | ( PVOID )CurrentBase ); 188 | RtlCopyMemory( Loader.FileList[ Loader.FileCount ].FileName, 189 | CurrentDirectory[ CurrentFile ].Short.Name, 190 | 11 ); 191 | Loader.FileList[ Loader.FileCount ].FileName[ 11 ] = 0; 192 | 193 | CurrentBase += Loader.FileList[ Loader.FileCount ].Length; 194 | /* 195 | BpDisplayString( "BdInitFile: %s %llx %lx\n", 196 | Loader.FileList[ Loader.FileCount ].FileName, 197 | Loader.FileList[ Loader.FileCount ].BaseAddress, 198 | Loader.FileList[ Loader.FileCount ].Length ); 199 | */ 200 | Loader.FileCount++; 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /carbload/inc/x86_64.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #pragma pack( push, 1 ) 5 | 6 | typedef union _KGDT_SEGMENT { 7 | struct { 8 | ULONG64 LimitPart0 : 16; 9 | ULONG64 BasePart0 : 16; 10 | ULONG64 BasePart1 : 8; 11 | ULONG64 Accessed : 1; 12 | ULONG64 Write : 1; 13 | ULONG64 Direction : 1; 14 | ULONG64 Execute : 1; 15 | ULONG64 DescriptorType : 1; 16 | ULONG64 PrivilegeLevel : 2; 17 | ULONG64 Present : 1; 18 | ULONG64 LimitPart1 : 4; 19 | ULONG64 System : 1; 20 | ULONG64 LongMode : 1; 21 | ULONG64 DefaultBig : 1; 22 | ULONG64 Granularity : 1; 23 | ULONG64 BasePart2 : 8; 24 | }; 25 | 26 | ULONG64 Long; 27 | } KGDT_SEGMENT, *PKGDT_SEGMENT; 28 | 29 | typedef union _KGDT_SYSTEM_SEGMENT { 30 | 31 | struct { 32 | ULONG64 LimitPart0 : 16; 33 | ULONG64 BasePart0 : 16; 34 | ULONG64 BasePart1 : 8; 35 | ULONG64 Type : 4; 36 | ULONG64 System : 1; 37 | ULONG64 PrivilegeLevel : 2; 38 | ULONG64 Present : 1; 39 | ULONG64 LimitPart1 : 4; 40 | ULONG64 Avail : 1; 41 | ULONG64 Reserved1 : 2; 42 | ULONG64 Granularity : 1; 43 | ULONG64 BasePart2 : 8; 44 | ULONG64 BasePart3 : 32; 45 | ULONG64 Reserved2 : 32; 46 | }; 47 | 48 | struct { 49 | ULONG64 Long0; 50 | ULONG64 Long1; 51 | }; 52 | } KGDT_SYSTEM_SEGMENT, *PKGDT_SYSTEM_SEGMENT; 53 | 54 | C_ASSERT( sizeof( KGDT_SYSTEM_SEGMENT ) == 16 ); 55 | 56 | typedef struct _KDESCRIPTOR_TABLE { 57 | USHORT Limit; 58 | ULONG32 Base; 59 | } KDESCRIPTOR_TABLE, *PKDESCRIPTOR_TABLE; 60 | 61 | C_ASSERT( sizeof( KDESCRIPTOR_TABLE ) == 6 ); 62 | 63 | typedef struct _X86_BIOS_INTERRUPT { 64 | USHORT SegDs; 65 | USHORT SegEs; 66 | 67 | ULONG32 Edi; 68 | ULONG32 Esi; 69 | ULONG32 Ebp; 70 | ULONG32 Esp; 71 | ULONG32 Ebx; 72 | ULONG32 Edx; 73 | ULONG32 Ecx; 74 | ULONG32 Eax; 75 | } X86_BIOS_INTERRUPT, *PX86_BIOS_INTERRUPT; 76 | 77 | C_ASSERT( ( ULONG32 )( &( ( PX86_BIOS_INTERRUPT )0 )->Esp ) == 16 ); 78 | C_ASSERT( sizeof( X86_BIOS_INTERRUPT ) ); 79 | 80 | typedef struct _X86_FAR_PTR { 81 | USHORT Offset; 82 | USHORT Segment; 83 | } X86_FAR_PTR, *PX86_FAR_PTR; 84 | 85 | typedef struct _X86_VESA_INFO { 86 | ULONG32 Signature; 87 | USHORT Version; 88 | X86_FAR_PTR OemString; 89 | ULONG32 Caps; 90 | X86_FAR_PTR ModeList; 91 | USHORT TotalMemory; 92 | USHORT OemSoftwareRevision; 93 | X86_FAR_PTR OemVendorName; 94 | X86_FAR_PTR OemProductName; 95 | X86_FAR_PTR OemProductRevision; 96 | UCHAR Reserved[ 222 ]; 97 | UCHAR OemData[ 256 ]; 98 | } X86_VESA_INFO, *PX86_VESA_INFO; 99 | 100 | C_ASSERT( sizeof( X86_VESA_INFO ) == 512 ); 101 | 102 | typedef struct _X86_VESA_MODE_INFO { 103 | USHORT Attributes; 104 | UCHAR WindowA; 105 | UCHAR WindowB; 106 | USHORT Granularity; 107 | USHORT WindowSize; 108 | USHORT SegmentA; 109 | USHORT SegmentB; 110 | ULONG32 WindowFunction; 111 | USHORT Pitch; 112 | USHORT Width; 113 | USHORT Height; 114 | UCHAR CharWidth; 115 | UCHAR CharHeight; 116 | UCHAR Planes; 117 | UCHAR BitsPerPixel; 118 | UCHAR Banks; 119 | UCHAR MemoryModel; 120 | UCHAR BankSize; 121 | UCHAR ImagePages; 122 | UCHAR Reserved0; 123 | UCHAR RedMask; 124 | UCHAR RedPosition; 125 | UCHAR GreenMask; 126 | UCHAR GreenPosition; 127 | UCHAR BlueMask; 128 | UCHAR BluePosition; 129 | UCHAR AlphaMask; 130 | UCHAR AlphaPosition; 131 | UCHAR DirectColourAttributes; 132 | ULONG32 Framebuffer; 133 | ULONG32 Reserved1; 134 | USHORT Reserved2; 135 | // VBE 3.0 136 | UCHAR Reserved3[ 206 ]; 137 | } X86_VESA_MODE_INFO; 138 | 139 | C_ASSERT( sizeof( X86_VESA_MODE_INFO ) == 256 ); 140 | 141 | typedef struct _X86_DISK_ACCESS_BLOCK { 142 | UCHAR Length; 143 | UCHAR Zero; 144 | USHORT SectorCount; 145 | //ULONG32 Buffer; 146 | X86_FAR_PTR Buffer; 147 | ULONG64 BlockAddress; 148 | } X86_DISK_ACCESS_BLOCK, *PX86_DISK_ACCESS_BLOCK; 149 | 150 | typedef struct _X86_MEMORY_MAP_ENTRY { 151 | ULONG64 BaseAddress; 152 | ULONG64 Length; 153 | ULONG32 Type; 154 | ULONG32 AcpiEa; 155 | } X86_MEMORY_MAP_ENTRY, *PX86_MEMORY_MAP_ENTRY; 156 | 157 | #define X86_BIOS_ENCODE_FAR_PTR( Segment, Offset, Address ) \ 158 | Segment = ( ( ULONG32 )( Address ) & 0x000FFFF0 ) >> 4; \ 159 | Offset = ( ( ULONG32 )( Address ) & 0x0000000F ) 160 | 161 | #define X86_BIOS_DECODE_FAR_PTR( Segment, Offset, Address ) \ 162 | ( ULONG32 )Address = ( ( Segment ) << 4 ) + ( Offset ) 163 | 164 | VOID 165 | BPAPI 166 | x86BiosCall( 167 | _In_ ULONG32 Vector, 168 | _In_ PX86_BIOS_INTERRUPT Interrupt 169 | ); 170 | 171 | NORETURN 172 | VOID 173 | BPAPI 174 | x86Boot64( 175 | _In_ ULONG64 EntryAddress, 176 | _In_ ULONG64 LoaderBlock 177 | ); 178 | 179 | typedef union _MMPTE_HARDWARE { 180 | struct { 181 | ULONG64 Present : 1; 182 | ULONG64 Write : 1; 183 | ULONG64 User : 1; 184 | ULONG64 WriteThrough : 1; 185 | ULONG64 CacheDisable : 1; 186 | ULONG64 Accessed : 1; 187 | ULONG64 Dirty : 1; 188 | ULONG64 Large : 1; 189 | ULONG64 Global : 1; 190 | ULONG64 Available0 : 3; 191 | ULONG64 PageFrame : 36; 192 | ULONG64 Reserved1 : 4; 193 | ULONG64 Available1 : 7; 194 | ULONG64 ProtectionKey : 4; 195 | ULONG64 ExecuteDisable : 1; 196 | } Table; 197 | 198 | struct { 199 | ULONG64 Present : 1; 200 | ULONG64 Write : 1; 201 | ULONG64 User : 1; 202 | ULONG64 WriteThrough : 1; 203 | ULONG64 CacheDisable : 1; 204 | ULONG64 Accessed : 1; 205 | ULONG64 Dirty : 1; 206 | ULONG64 PageAttribute : 1; 207 | ULONG64 Global : 1; 208 | ULONG64 Available0 : 3; 209 | ULONG64 PageFrame : 36; 210 | ULONG64 Reserved1 : 4; 211 | ULONG64 Available1 : 7; 212 | ULONG64 ProtectionKey : 4; 213 | ULONG64 ExecuteDisable : 1; 214 | } Entry; 215 | 216 | ULONG64 Long; 217 | } MMPTE_HARDWARE, *PMMPTE_HARDWARE; 218 | 219 | C_ASSERT( sizeof( MMPTE_HARDWARE ) == 8 ); 220 | 221 | #pragma pack( pop ) 222 | 223 | VOID 224 | BPAPI 225 | BdEnterPagedMode( 226 | 227 | ); 228 | 229 | VOID 230 | BPAPI 231 | BdExitPagedMode( 232 | 233 | ); 234 | 235 | #define IA32_MSR_EFER 0xC0000080 236 | 237 | #define CR4_PAE (1 << 5) 238 | 239 | #define CR0_PG (1 << 31) 240 | 241 | #define EFER_LME (1 << 8) 242 | #define EFER_LMA (1 << 10) 243 | -------------------------------------------------------------------------------- /carbload/bios/map.c: -------------------------------------------------------------------------------- 1 | 2 | #include "loader.h" 3 | 4 | VOID 5 | BdReserveRegion( 6 | _In_ ULONG32 LogicalAddress, 7 | _In_ ULONG32 Length 8 | ) 9 | { 10 | ULONG32 CurrentRegion; 11 | 12 | for ( CurrentRegion = 0; CurrentRegion < Loader.RegionCount; CurrentRegion++ ) { 13 | 14 | if ( Loader.RegionList[ CurrentRegion ].Type != LOADER_REGION_USABLE || 15 | Loader.RegionList[ CurrentRegion ].BaseAddress >= LogicalAddress + Length || 16 | Loader.RegionList[ CurrentRegion ].BaseAddress + 17 | Loader.RegionList[ CurrentRegion ].Length <= LogicalAddress + Length ) { 18 | 19 | continue; 20 | } 21 | 22 | if ( Loader.RegionList[ CurrentRegion ].BaseAddress != LogicalAddress ) { 23 | 24 | Loader.RegionList[ Loader.RegionCount ].BaseAddress = 25 | Loader.RegionList[ CurrentRegion ].BaseAddress; 26 | Loader.RegionList[ Loader.RegionCount ].Length = 27 | LogicalAddress - Loader.RegionList[ CurrentRegion ].BaseAddress; 28 | Loader.RegionList[ Loader.RegionCount ].Type = LOADER_REGION_USABLE; 29 | 30 | Loader.RegionList[ CurrentRegion ].BaseAddress += 31 | Loader.RegionList[ Loader.RegionCount ].Length; 32 | Loader.RegionList[ CurrentRegion ].Length -= 33 | Loader.RegionList[ Loader.RegionCount ].Length; 34 | 35 | Loader.RegionCount++; 36 | 37 | } 38 | 39 | Loader.RegionList[ Loader.RegionCount ].BaseAddress = 40 | LogicalAddress; 41 | Loader.RegionList[ Loader.RegionCount ].Length = 42 | LogicalAddress + Length - Loader.RegionList[ CurrentRegion ].BaseAddress; 43 | Loader.RegionList[ Loader.RegionCount ].Type = LOADER_REGION_LOADER; 44 | 45 | Loader.RegionList[ CurrentRegion ].BaseAddress += 46 | Loader.RegionList[ Loader.RegionCount ].Length; 47 | Loader.RegionList[ CurrentRegion ].Length -= 48 | Loader.RegionList[ Loader.RegionCount ].Length; 49 | 50 | Loader.RegionCount++; 51 | } 52 | } 53 | 54 | ULONG32 55 | BdClosestLogical( 56 | _In_ ULONG32 LogicalAddress, 57 | _In_ ULONG32 MinimumLength 58 | ) 59 | { 60 | ULONG32 CurrentRegion; 61 | ULONG64 ClosestLogical; 62 | 63 | ClosestLogical = 0; 64 | for ( CurrentRegion = 0; CurrentRegion < Loader.RegionCount; CurrentRegion++ ) { 65 | 66 | if ( Loader.RegionList[ CurrentRegion ].Type != LOADER_REGION_USABLE || 67 | Loader.RegionList[ CurrentRegion ].BaseAddress >= LogicalAddress || 68 | Loader.RegionList[ CurrentRegion ].BaseAddress + 69 | Loader.RegionList[ CurrentRegion ].Length <= LogicalAddress || 70 | Loader.RegionList[ CurrentRegion ].BaseAddress - 71 | LogicalAddress + 72 | Loader.RegionList[ CurrentRegion ].Length < MinimumLength ) { 73 | 74 | continue; 75 | } 76 | 77 | return LogicalAddress; 78 | } 79 | 80 | for ( CurrentRegion = 0; CurrentRegion < Loader.RegionCount; CurrentRegion++ ) { 81 | 82 | if ( Loader.RegionList[ CurrentRegion ].Type != LOADER_REGION_USABLE || 83 | Loader.RegionList[ CurrentRegion ].Length < MinimumLength ) { 84 | 85 | continue; 86 | } 87 | 88 | if ( Loader.RegionList[ CurrentRegion ].BaseAddress - LogicalAddress < 89 | ClosestLogical - LogicalAddress ) { 90 | 91 | ClosestLogical = Loader.RegionList[ CurrentRegion ].BaseAddress; 92 | } 93 | } 94 | 95 | return ClosestLogical; 96 | } 97 | 98 | ULONG32 PagedMode = 0; 99 | 100 | VOID 101 | BPAPI 102 | BdEnterPagedMode( 103 | 104 | ) 105 | { 106 | if ( PagedMode == 1 ) { 107 | __writecr4( __readcr4( ) | CR4_PAE ); 108 | __writemsr( IA32_MSR_EFER, __readmsr( IA32_MSR_EFER ) | EFER_LME ); 109 | __writecr0( __readcr0( ) | CR0_PG ); 110 | PagedMode = 2; 111 | } 112 | } 113 | 114 | VOID 115 | BPAPI 116 | BdExitPagedMode( 117 | 118 | ) 119 | { 120 | if ( PagedMode == 2 ) { 121 | //__writemsr( IA32_MSR_EFER, __readmsr( IA32_MSR_EFER ) & ~EFER_LMA ); 122 | __writecr0( __readcr0( ) & ~CR0_PG ); 123 | __writecr4( __readcr4( ) & ~CR4_PAE ); 124 | __writemsr( IA32_MSR_EFER, __readmsr( IA32_MSR_EFER ) & ~EFER_LME ); 125 | PagedMode = 1; 126 | } 127 | } 128 | 129 | VOID 130 | BPAPI 131 | BdInitMap( 132 | 133 | ) 134 | { 135 | X86_BIOS_INTERRUPT BiosFrame = { 0 }; 136 | X86_MEMORY_MAP_ENTRY MapEntry; 137 | ULONG32 CurrentRegion; 138 | PMMPTE_HARDWARE Pxe; 139 | PMMPTE_HARDWARE PpeLower; 140 | PMMPTE_HARDWARE PpeUpper; 141 | PMMPTE_HARDWARE PdeLower; 142 | PMMPTE_HARDWARE PdeUpper; 143 | ULONG32 BaseReserve; 144 | 145 | BiosFrame.SegDs = 0; 146 | BiosFrame.Ebx = 0; 147 | do { 148 | 149 | BiosFrame.Eax = 0xE820; 150 | BiosFrame.Edx = 'SMAP'; 151 | BiosFrame.Ecx = sizeof( X86_MEMORY_MAP_ENTRY ); 152 | X86_BIOS_ENCODE_FAR_PTR( BiosFrame.SegEs, 153 | BiosFrame.Edi, 154 | &MapEntry ); 155 | x86BiosCall( 0x15, &BiosFrame ); 156 | 157 | Loader.RegionList[ Loader.RegionCount ].BaseAddress = MapEntry.BaseAddress; 158 | Loader.RegionList[ Loader.RegionCount ].Length = MapEntry.Length; 159 | Loader.RegionList[ Loader.RegionCount ].Type = MapEntry.Type; 160 | 161 | Loader.RegionCount++; 162 | } while ( BiosFrame.Ebx != 0 ); 163 | 164 | BdReserveRegion( 0, 0x100000 ); 165 | // could cause an issue if it is outside the 0x200000 range. 166 | BaseReserve = BdClosestLogical( 0x100000, 0x5000 ); 167 | BdReserveRegion( BaseReserve, 0x5000 ); 168 | 169 | Pxe = ( PMMPTE_HARDWARE )BaseReserve; 170 | PpeLower = ( PMMPTE_HARDWARE )( BaseReserve + 0x1000 ); 171 | PpeUpper = ( PMMPTE_HARDWARE )( BaseReserve + 0x2000 ); 172 | PdeLower = ( PMMPTE_HARDWARE )( BaseReserve + 0x3000 ); 173 | PdeUpper = ( PMMPTE_HARDWARE )( BaseReserve + 0x4000 ); 174 | __stosb( Pxe, 0, 0x1000 ); 175 | __stosb( PpeLower, 0, 0x1000 ); 176 | __stosb( PpeUpper, 0, 0x1000 ); 177 | __stosb( PdeLower, 0, 0x1000 ); 178 | __stosb( PdeUpper, 0, 0x1000 ); 179 | 180 | Pxe[ 0 ].Table.Present = 1; 181 | Pxe[ 0 ].Table.Write = 1; 182 | Pxe[ 0 ].Table.PageFrame = ( ULONG64 )( ULONG32 )PpeLower >> 12; 183 | 184 | Pxe[ 511 ].Table.Present = 1; 185 | Pxe[ 511 ].Table.Write = 1; 186 | Pxe[ 511 ].Table.PageFrame = ( ULONG64 )( ULONG32 )PpeUpper >> 12; 187 | 188 | PpeLower[ 0 ].Table.Present = 1; 189 | PpeLower[ 0 ].Table.Write = 1; 190 | PpeLower[ 0 ].Table.PageFrame = ( ULONG64 )( ULONG32 )PdeLower >> 12; 191 | 192 | PpeUpper[ 511 ].Table.Present = 1; 193 | PpeUpper[ 511 ].Table.Write = 1; 194 | PpeUpper[ 511 ].Table.PageFrame = ( ULONG64 )( ULONG32 )PdeUpper >> 12; 195 | 196 | BaseReserve = BdClosestLogical( 0x200000, 0x200000 ); 197 | 198 | PdeLower[ 0 ].Table.Present = 1; 199 | PdeLower[ 0 ].Table.Write = 1; 200 | PdeLower[ 0 ].Table.Large = 1; 201 | PdeLower[ 0 ].Table.PageFrame = 0; 202 | 203 | PdeLower[ 1 ].Table.Present = 1; 204 | PdeLower[ 1 ].Table.Write = 1; 205 | PdeLower[ 1 ].Table.Large = 1; 206 | PdeLower[ 1 ].Table.PageFrame = ( ULONG64 )( ULONG32 )BaseReserve >> 12; 207 | 208 | PdeUpper[ 510 ].Table.Present = 1; 209 | PdeUpper[ 510 ].Table.Write = 1; 210 | PdeUpper[ 510 ].Table.Large = 1; 211 | PdeUpper[ 510 ].Table.PageFrame = 0; 212 | 213 | PdeUpper[ 511 ].Table.Present = 1; 214 | PdeUpper[ 511 ].Table.Write = 1; 215 | PdeUpper[ 511 ].Table.Large = 1; 216 | PdeUpper[ 511 ].Table.PageFrame = ( ULONG64 )( ULONG32 )BaseReserve >> 12; 217 | 218 | BdReserveRegion( BaseReserve, 0x200000 ); 219 | 220 | __writecr3( Pxe ); 221 | PagedMode = 1; 222 | BdEnterPagedMode( ); 223 | } 224 | 225 | ULONG64 226 | BPAPI 227 | BdAddress64( 228 | _In_ ULONG32 Address32 229 | ) 230 | { 231 | return ( ULONG64 )Address32 + 0xFFFFFFFFFFC00000; 232 | } 233 | 234 | VOID 235 | BPAPI 236 | BdTranslateLoader( 237 | 238 | ) 239 | { 240 | ULONG32 CurrentEntry; 241 | 242 | for ( CurrentEntry = 0; CurrentEntry < Loader.FileCount; CurrentEntry++ ) { 243 | 244 | Loader.FileList[ CurrentEntry ].BaseAddress = 245 | BdAddress64( Loader.FileList[ CurrentEntry ].BaseAddress ); 246 | } 247 | 248 | for ( CurrentEntry = 0; CurrentEntry < Loader.MapCount; CurrentEntry++ ) { 249 | 250 | Loader.MapList[ CurrentEntry ].BaseAddress = 251 | BdAddress64( Loader.MapList[ CurrentEntry ].BaseAddress ); 252 | 253 | Loader.MapList[ CurrentEntry ]._BootFile64 = 254 | BdAddress64( ( ULONG32 )Loader.MapList[ CurrentEntry ].BootFile ); 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /carbload/initload.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #pragma section( ".LDRBLCK", read, write ) 5 | 6 | __declspec( allocate( ".LDRBLCK" ) ) LOADER_BLOCK Loader = { 0 }; 7 | 8 | ULONG32 BpBootDisk; 9 | 10 | #define GDT_SEGMENT_R0_CODE32 0x08 11 | #define GDT_SEGMENT_R0_DATA32 0x10 12 | #define GDT_SEGMENT_R0_CODE16 0x18 13 | #define GDT_SEGMENT_R0_DATA16 0x20 14 | #define GDT_SEGMENT_R0_CODE64 0x28 15 | #define GDT_SEGMENT_R0_DATA64 0x30 16 | #define GDT_SEGMENT_COUNT 7 17 | 18 | KGDT_SEGMENT SegmentTable[ GDT_SEGMENT_COUNT ] = { 19 | { 0 }, 20 | 21 | //GDT_SEGMENT_R0_CODE32 22 | { 23 | .LimitPart0 = 0xFFFF, 24 | .LimitPart1 = 0x0F, 25 | .BasePart0 = 0, 26 | .BasePart1 = 0, 27 | .BasePart2 = 0, 28 | 29 | .Accessed = 0, 30 | .Write = 1, 31 | .Direction = 0, 32 | .Execute = 1, 33 | .DescriptorType = 1, 34 | .PrivilegeLevel = 0, 35 | .Present = 1, 36 | 37 | .System = 0, 38 | .LongMode = 0, 39 | .DefaultBig = 1, 40 | .Granularity = 1, 41 | }, 42 | 43 | //GDT_SEGMENT_R0_DATA32 44 | { 45 | .LimitPart0 = 0xFFFF, 46 | .LimitPart1 = 0x0F, 47 | .BasePart0 = 0, 48 | .BasePart1 = 0, 49 | .BasePart2 = 0, 50 | 51 | .Accessed = 0, 52 | .Write = 1, 53 | .Direction = 0, 54 | .Execute = 0, 55 | .DescriptorType = 1, 56 | .PrivilegeLevel = 0, 57 | .Present = 1, 58 | 59 | .System = 0, 60 | .LongMode = 0, 61 | .DefaultBig = 1, 62 | .Granularity = 1, 63 | }, 64 | 65 | //GDT_SEGMENT_R0_CODE16 66 | { 67 | .LimitPart0 = 0xFFFF, 68 | .LimitPart1 = 0, 69 | .BasePart0 = 0, 70 | .BasePart1 = 0, 71 | .BasePart2 = 0, 72 | 73 | .Accessed = 0, 74 | .Write = 1, 75 | .Direction = 0, 76 | .Execute = 1, 77 | .DescriptorType = 1, 78 | .PrivilegeLevel = 0, 79 | .Present = 1, 80 | 81 | .System = 0, 82 | .LongMode = 0, 83 | .DefaultBig = 0, 84 | .Granularity = 0, 85 | }, 86 | 87 | //GDT_SEGMENT_R0_DATA16 88 | { 89 | .LimitPart0 = 0xFFFF, 90 | .LimitPart1 = 0, 91 | .BasePart0 = 0, 92 | .BasePart1 = 0, 93 | .BasePart2 = 0, 94 | 95 | .Accessed = 0, 96 | .Write = 1, 97 | .Direction = 0, 98 | .Execute = 0, 99 | .DescriptorType = 1, 100 | .PrivilegeLevel = 0, 101 | .Present = 1, 102 | 103 | .System = 0, 104 | .LongMode = 0, 105 | .DefaultBig = 0, 106 | .Granularity = 0, 107 | }, 108 | 109 | //GDT_SEGMENT_R0_CODE64 110 | { 111 | .LimitPart0 = 0xFFFF, 112 | .LimitPart1 = 0xF, 113 | .BasePart0 = 0, 114 | .BasePart1 = 0, 115 | .BasePart2 = 0, 116 | 117 | .Accessed = 0, 118 | .Write = 1, 119 | .Direction = 0, 120 | .Execute = 1, 121 | .DescriptorType = 1, 122 | .PrivilegeLevel = 0, 123 | .Present = 1, 124 | 125 | .System = 0, 126 | .LongMode = 1, 127 | .DefaultBig = 0, 128 | .Granularity = 1, 129 | }, 130 | 131 | //GDT_SEGMENT_R0_DATA64 132 | { 133 | .LimitPart0 = 0, 134 | .LimitPart1 = 0, 135 | .BasePart0 = 0, 136 | .BasePart1 = 0, 137 | .BasePart2 = 0, 138 | 139 | .Accessed = 0, 140 | .Write = 1, 141 | .Direction = 0, 142 | .Execute = 0, 143 | .DescriptorType = 1, 144 | .PrivilegeLevel = 0, 145 | .Present = 1, 146 | 147 | .System = 0, 148 | .LongMode = 0, 149 | .DefaultBig = 0, 150 | .Granularity = 0, 151 | }, 152 | }; 153 | 154 | VOID 155 | BPAPI 156 | BpDisplayRawString( 157 | _In_ PSTR String 158 | ) 159 | { 160 | STATIC ULONG32 PosX = 0; 161 | STATIC ULONG32 PosY = 0; 162 | 163 | while ( *String ) { 164 | 165 | switch ( *String ) { 166 | case '\n': 167 | PosY++; 168 | PosX = 0; 169 | break; 170 | default: 171 | ( ( USHORT* )0xB8000 )[ PosX + PosY * 80 ] = *String | 0x0F00; 172 | PosX++; 173 | break; 174 | } 175 | String++; 176 | } 177 | } 178 | 179 | VOID 180 | BpDisplayString( 181 | _In_ PSTR Format, 182 | _In_ ... 183 | ) 184 | { 185 | va_list List; 186 | CHAR Buffer[ 512 ]; 187 | 188 | __crt_va_start( List, Format ); 189 | RtlFormatAnsiStringFromList( Buffer, 190 | Format, 191 | List ); 192 | __crt_va_end( List ); 193 | BpDisplayRawString( Buffer ); 194 | } 195 | 196 | NORETURN 197 | VOID 198 | BpFatalException( 199 | _In_ PSTR Format, 200 | _In_ ... 201 | ) 202 | { 203 | va_list List; 204 | CHAR Buffer[ 512 ]; 205 | //X86_BIOS_INTERRUPT BiosFrame = { 0 }; 206 | 207 | __crt_va_start( List, Format ); 208 | RtlFormatAnsiStringFromList( Buffer, 209 | Format, 210 | List ); 211 | __crt_va_end( List ); 212 | 213 | //BiosFrame.Eax = 0x83; 214 | //x86BiosCall( 0x10, &BiosFrame ); 215 | 216 | BpDisplayRawString( Buffer ); 217 | __halt( ); 218 | } 219 | 220 | VOID 221 | BPAPI 222 | BdDisplayLoader( 223 | 224 | ) 225 | { 226 | ULONG32 CurrentEntry; 227 | CHAR LoaderSig[ 5 ]; 228 | 229 | *( ULONG32* )LoaderSig = Loader.LoaderSig; 230 | LoaderSig[ 4 ] = 0; 231 | 232 | BpDisplayString( "LOADERSIG: %s\n", LoaderSig ); 233 | BpDisplayString( "ROOTSERIAL: %lx\n", Loader.RootSerial ); 234 | 235 | for ( CurrentEntry = 0; CurrentEntry < Loader.RegionCount; CurrentEntry++ ) { 236 | 237 | BpDisplayString( "REGION %l: %llx %llx %l\n", 238 | CurrentEntry, 239 | Loader.RegionList[ CurrentEntry ].BaseAddress, 240 | Loader.RegionList[ CurrentEntry ].Length, 241 | Loader.RegionList[ CurrentEntry ].Type ); 242 | } 243 | 244 | for ( CurrentEntry = 0; CurrentEntry < Loader.FileCount; CurrentEntry++ ) { 245 | 246 | BpDisplayString( "FILE %l: %s %llx %lx\n", 247 | CurrentEntry, 248 | Loader.FileList[ CurrentEntry ].FileName, 249 | BdAddress64( Loader.FileList[ CurrentEntry ].BaseAddress ), 250 | Loader.FileList[ CurrentEntry ].Length ); 251 | } 252 | 253 | for ( CurrentEntry = 0; CurrentEntry < Loader.MapCount; CurrentEntry++ ) { 254 | 255 | if ( Loader.MapList[ CurrentEntry ].BootFile != NULL && 256 | ( Loader.MapList[ CurrentEntry ]._BootFile64 >> 32 ) == NULL ) { 257 | BpDisplayString( "MAP %l: %s: %llx %lx\n", 258 | CurrentEntry, 259 | Loader.MapList[ CurrentEntry ].BootFile->FileName, 260 | BdAddress64( Loader.MapList[ CurrentEntry ].BaseAddress ), 261 | Loader.MapList[ CurrentEntry ].Length ); 262 | } 263 | else { 264 | BpDisplayString( "MAP %l: %llx %lx\n", 265 | CurrentEntry, 266 | BdAddress64( Loader.MapList[ CurrentEntry ].BaseAddress ), 267 | Loader.MapList[ CurrentEntry ].Length ); 268 | } 269 | } 270 | 271 | BpDisplayString( "GRAPHICS: %l,%l,%l,%lx\n", 272 | Loader.Graphics.Width, 273 | Loader.Graphics.Height, 274 | Loader.Graphics.Bpp, 275 | Loader.Graphics.Frame ); 276 | } 277 | 278 | VOID 279 | BPAPI 280 | BpLoadSystem( 281 | 282 | ) 283 | { 284 | KDESCRIPTOR_TABLE GlobalDescriptor = { 285 | sizeof( KGDT_SEGMENT[ GDT_SEGMENT_COUNT ] ) - 1, 286 | ( ULONG32 )&SegmentTable 287 | }; 288 | 289 | PVOLUME_BOOT_RECORD BootRecord = ( PVOLUME_BOOT_RECORD )0x7C00; 290 | PLOADER_BOOT_FILE KernelFile; 291 | ULONG32 LoadAddress; 292 | ULONG64 EntryPoint; 293 | ULONG64 LoaderBlock; 294 | 295 | __outbyte( 0xA1, 0xFF ); 296 | __outbyte( 0x21, 0xFF ); 297 | 298 | _lgdt( &GlobalDescriptor ); 299 | 300 | BdInitMap( ); 301 | BdInitFile( ); 302 | 303 | BdFindBootFile( KERNEL_FILE_NAME, &KernelFile ); 304 | 305 | LoadAddress = ROUND_TO_PAGES( 306 | Loader.FileList[ Loader.FileCount - 1 ].BaseAddress + 307 | ( ULONG64 )Loader.FileList[ Loader.FileCount - 1 ].Length ); 308 | 309 | LdrLoadSystemModule( BootRecord, 310 | KernelFile, 311 | LoadAddress ); 312 | 313 | EntryPoint = BdAddress64( LdrEntryPoint( ( ULONG32 )Loader.MapList[ 0 ].BaseAddress ) ); 314 | LoaderBlock = BdAddress64( ( ULONG32 )&Loader ); 315 | 316 | BdDisplayLoader( ); 317 | BdTranslateLoader( ); 318 | 319 | BdInitGraphics( ); 320 | x86Boot64( EntryPoint, LoaderBlock ); 321 | } 322 | -------------------------------------------------------------------------------- /carbload/format/pe64.c: -------------------------------------------------------------------------------- 1 | 2 | #include "loader.h" 3 | 4 | NTSTATUS 5 | LdrGetExportAddressByName( 6 | _In_ PVOID Base, 7 | _In_ PCHAR Name, 8 | _Out_ ULONG64* Address 9 | ) 10 | { 11 | PIMAGE_DOS_HEADER HeaderDos; 12 | PIMAGE_NT_HEADERS HeaderNt; 13 | PIMAGE_EXPORT_DIRECTORY Export; 14 | PULONG32 FunctionTable; 15 | PULONG32 NameTable; 16 | PUSHORT OrdinalTable; 17 | ULONG32 CurrentOrdinal; 18 | PCHAR CurrentName; 19 | 20 | HeaderDos = ( PIMAGE_DOS_HEADER )Base; 21 | 22 | if ( HeaderDos->e_magic != IMAGE_DOS_SIGNATURE ) { 23 | 24 | return STATUS_INVALID_IMAGE; 25 | } 26 | 27 | HeaderNt = ( PIMAGE_NT_HEADERS )( ( PUCHAR )Base + HeaderDos->e_lfanew ); 28 | 29 | if ( HeaderNt->Signature != IMAGE_NT_SIGNATURE ) { 30 | 31 | return STATUS_INVALID_IMAGE; 32 | } 33 | 34 | if ( HeaderNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].Size == 0 ) { 35 | 36 | return STATUS_INVALID_IMAGE; 37 | } 38 | 39 | Export = ( PIMAGE_EXPORT_DIRECTORY )( ( PUCHAR )Base + HeaderNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress ); 40 | FunctionTable = ( PULONG32 )( ( PUCHAR )Base + Export->AddressOfFunctions ); 41 | NameTable = ( PULONG32 )( ( PUCHAR )Base + Export->AddressOfNames ); 42 | OrdinalTable = ( PUSHORT )( ( PUCHAR )Base + Export->AddressOfNameOrdinals ); 43 | 44 | for ( CurrentOrdinal = 0; CurrentOrdinal < Export->NumberOfNames; CurrentOrdinal++ ) { 45 | CurrentName = ( ( PCHAR )Base + NameTable[ CurrentOrdinal ] ); 46 | 47 | if ( RtlCompareAnsiString( Name, CurrentName, 0 ) == 0 ) { 48 | *Address = ( ULONG64 )( ( PUCHAR )Base + FunctionTable[ OrdinalTable[ CurrentOrdinal ] ] ); 49 | return STATUS_SUCCESS; 50 | } 51 | } 52 | 53 | return STATUS_NOT_FOUND; 54 | } 55 | 56 | NTSTATUS 57 | LdrGetExportAddressByOrdinal( 58 | _In_ PVOID Base, 59 | _In_ USHORT Ordinal, 60 | _Out_ ULONG64* Address 61 | ) 62 | { 63 | PIMAGE_DOS_HEADER HeaderDos; 64 | PIMAGE_NT_HEADERS HeaderNt; 65 | PIMAGE_EXPORT_DIRECTORY Export; 66 | PULONG32 FunctionTable; 67 | PUSHORT OrdinalTable; 68 | ULONG32 CurrentOrdinal; 69 | USHORT OrdinalValue; 70 | 71 | HeaderDos = ( PIMAGE_DOS_HEADER )Base; 72 | 73 | if ( HeaderDos->e_magic != IMAGE_DOS_SIGNATURE ) { 74 | 75 | return STATUS_INVALID_IMAGE; 76 | } 77 | 78 | HeaderNt = ( PIMAGE_NT_HEADERS )( ( PUCHAR )Base + HeaderDos->e_lfanew ); 79 | 80 | if ( HeaderNt->Signature != IMAGE_NT_SIGNATURE ) { 81 | 82 | return STATUS_INVALID_IMAGE; 83 | } 84 | 85 | if ( HeaderNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].Size == 0 ) { 86 | 87 | return STATUS_NOT_FOUND; 88 | } 89 | 90 | Export = ( PIMAGE_EXPORT_DIRECTORY )( ( PUCHAR )Base + HeaderNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress ); 91 | FunctionTable = ( PULONG32 )( ( PUCHAR )Base + Export->AddressOfFunctions ); 92 | OrdinalTable = ( PUSHORT )( ( PUCHAR )Base + Export->AddressOfNameOrdinals ); 93 | 94 | for ( CurrentOrdinal = 0; CurrentOrdinal < Export->NumberOfFunctions; CurrentOrdinal++ ) { 95 | OrdinalValue = *( PUSHORT )( ( PUCHAR )Base + OrdinalTable[ CurrentOrdinal ] ); 96 | 97 | if ( OrdinalValue == Ordinal ) { 98 | *Address = ( ULONG64 )( ( PUCHAR )Base + FunctionTable[ OrdinalTable[ CurrentOrdinal ] ] ); 99 | return STATUS_SUCCESS; 100 | } 101 | } 102 | 103 | return STATUS_NOT_FOUND; 104 | } 105 | 106 | NTSTATUS 107 | LdrResolveBaseReloc( 108 | _In_ ULONG32 BaseAddress 109 | ) 110 | { 111 | PIMAGE_DOS_HEADER HeaderDos; 112 | PIMAGE_NT_HEADERS HeaderNt; 113 | PIMAGE_BASE_RELOCATION BaseReloc; 114 | LONG64 BaseDelta; 115 | ULONG64 RelocCount; 116 | PUSHORT RelocList; 117 | ULONG64 CurrentReloc; 118 | PLONG64 Address; 119 | 120 | HeaderDos = ( PIMAGE_DOS_HEADER )( BaseAddress ); 121 | 122 | if ( HeaderDos->e_magic != IMAGE_DOS_SIGNATURE ) { 123 | 124 | return STATUS_INVALID_IMAGE; 125 | } 126 | 127 | HeaderNt = ( PIMAGE_NT_HEADERS )( BaseAddress + HeaderDos->e_lfanew ); 128 | 129 | if ( HeaderNt->Signature != IMAGE_NT_SIGNATURE ) { 130 | 131 | return STATUS_INVALID_IMAGE; 132 | } 133 | 134 | if ( HeaderNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].Size == 0 || 135 | ( HeaderNt->OptionalHeader.DllCharacteristics & IMAGE_FILE_RELOCS_STRIPPED ) != 0 ) { 136 | 137 | return STATUS_INVALID_IMAGE; 138 | } 139 | 140 | BaseReloc = ( PIMAGE_BASE_RELOCATION )( BaseAddress + HeaderNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].VirtualAddress ); 141 | BaseDelta = BdAddress64( BaseAddress ) - HeaderNt->OptionalHeader.ImageBase; 142 | 143 | if ( BaseDelta == 0 ) { 144 | 145 | return STATUS_SUCCESS; 146 | } 147 | 148 | while ( BaseReloc->VirtualAddress ) { 149 | 150 | if ( BaseReloc->SizeOfBlock > sizeof( IMAGE_BASE_RELOCATION ) ) { 151 | RelocCount = ( BaseReloc->SizeOfBlock - sizeof( IMAGE_BASE_RELOCATION ) ) / sizeof( USHORT ); 152 | RelocList = ( PUSHORT )( ( PUCHAR )BaseReloc + sizeof( IMAGE_BASE_RELOCATION ) ); 153 | 154 | for ( CurrentReloc = 0; CurrentReloc < RelocCount; CurrentReloc++ ) { 155 | 156 | if ( RelocList[ CurrentReloc ] != 0 ) { 157 | Address = ( PLONG64 )( BaseAddress + BaseReloc->VirtualAddress + ( RelocList[ CurrentReloc ] & 0xfff ) ); 158 | *Address += BaseDelta; 159 | } 160 | } 161 | } 162 | 163 | BaseReloc = ( PIMAGE_BASE_RELOCATION )( ( PUCHAR )BaseReloc + BaseReloc->SizeOfBlock ); 164 | } 165 | 166 | return STATUS_SUCCESS; 167 | } 168 | 169 | NTSTATUS 170 | LdrResolveImportTable( 171 | _In_ PVOID Importer, 172 | _In_ PVOID Importee, 173 | _In_ PIMAGE_IMPORT_DESCRIPTOR Import 174 | ) 175 | { 176 | NTSTATUS ntStatus; 177 | PIMAGE_THUNK_DATA OriginalFirstThunk; 178 | PIMAGE_THUNK_DATA FirstThunk; 179 | PIMAGE_IMPORT_BY_NAME Name; 180 | 181 | OriginalFirstThunk = ( PIMAGE_THUNK_DATA )( ( PUCHAR )Importer + Import->OriginalFirstThunk ); 182 | FirstThunk = ( PIMAGE_THUNK_DATA )( ( PUCHAR )Importer + Import->FirstThunk ); 183 | 184 | while ( OriginalFirstThunk->u1.AddressOfData ) { 185 | 186 | if ( OriginalFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG ) { 187 | ntStatus = LdrGetExportAddressByOrdinal( 188 | Importee, 189 | ( USHORT )( OriginalFirstThunk->u1.Ordinal & 0xFFFF ), 190 | &FirstThunk->u1.Function ); 191 | 192 | if ( !NT_SUCCESS( ntStatus ) ) { 193 | 194 | return ntStatus; 195 | } 196 | 197 | FirstThunk->u1.Function = BdAddress64( FirstThunk->u1.Function ); 198 | } 199 | else { 200 | Name = ( PIMAGE_IMPORT_BY_NAME )( ( PUCHAR )Importer + OriginalFirstThunk->u1.AddressOfData ); 201 | ntStatus = LdrGetExportAddressByName( 202 | Importee, 203 | ( PCHAR )Name->Name, 204 | &FirstThunk->u1.Function ); 205 | 206 | if ( !NT_SUCCESS( ntStatus ) ) { 207 | 208 | return ntStatus; 209 | } 210 | 211 | FirstThunk->u1.Function = BdAddress64( FirstThunk->u1.Function ); 212 | } 213 | 214 | OriginalFirstThunk++; 215 | FirstThunk++; 216 | } 217 | 218 | return STATUS_SUCCESS; 219 | } 220 | 221 | NTSTATUS 222 | LdrLoadSystemModule( 223 | _In_ PVOLUME_BOOT_RECORD BootRecord, 224 | _In_ PLOADER_BOOT_FILE BootFile, 225 | _In_ ULONG32 BaseAddress 226 | ) 227 | { 228 | NTSTATUS ntStatus; 229 | PIMAGE_DOS_HEADER HeaderDos; 230 | PIMAGE_NT_HEADERS HeaderNt; 231 | PIMAGE_SECTION_HEADER HeaderSection; 232 | PIMAGE_SECTION_HEADER LastSection; 233 | PIMAGE_IMPORT_DESCRIPTOR Import; 234 | ULONG32 CurrentSection; 235 | ULONG32 CurrentMap; 236 | PLOADER_SYSTEM_MAP ImportMap; 237 | PLOADER_BOOT_FILE ImportFile; 238 | 239 | HeaderDos = ( PIMAGE_DOS_HEADER )( ( ULONG32 )BootFile->BaseAddress ); 240 | 241 | if ( HeaderDos->e_magic != IMAGE_DOS_SIGNATURE ) { 242 | 243 | return STATUS_INVALID_IMAGE; 244 | } 245 | 246 | HeaderNt = ( PIMAGE_NT_HEADERS )( ( ULONG32 )BootFile->BaseAddress + HeaderDos->e_lfanew ); 247 | 248 | if ( HeaderNt->Signature != IMAGE_NT_SIGNATURE || 249 | HeaderNt->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 ) { 250 | 251 | return STATUS_INVALID_IMAGE; 252 | } 253 | 254 | HeaderSection = IMAGE_FIRST_SECTION( HeaderNt ); 255 | LastSection = &HeaderSection[ HeaderNt->FileHeader.NumberOfSections - 1 ]; 256 | 257 | CurrentMap = Loader.MapCount; 258 | Loader.MapList[ CurrentMap ].BaseAddress = BaseAddress; 259 | Loader.MapList[ CurrentMap ].Length = LastSection->VirtualAddress + 260 | ROUND_TO_PAGES( LastSection->Misc.VirtualSize ); 261 | Loader.MapList[ CurrentMap ].BootFile = BootFile; 262 | 263 | Loader.MapCount++; 264 | 265 | RtlCopyMemory( ( PVOID )BaseAddress, 266 | HeaderDos, 267 | HeaderNt->OptionalHeader.SizeOfHeaders ); 268 | 269 | for ( CurrentSection = 0; 270 | CurrentSection < HeaderNt->FileHeader.NumberOfSections; 271 | CurrentSection++ ) { 272 | 273 | RtlCopyMemory( 274 | ( PUCHAR )BaseAddress + HeaderSection[ CurrentSection ].VirtualAddress, 275 | ( PUCHAR )BootFile->BaseAddress + HeaderSection[ CurrentSection ].PointerToRawData, 276 | HeaderSection[ CurrentSection ].SizeOfRawData ); 277 | } 278 | 279 | if ( 280 | ( HeaderNt->OptionalHeader.DllCharacteristics & IMAGE_FILE_RELOCS_STRIPPED ) == 0 && 281 | ( HeaderNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].VirtualAddress ) != 0 && 282 | ( BdAddress64( BaseAddress ) != HeaderNt->OptionalHeader.ImageBase ) ) { 283 | 284 | LdrResolveBaseReloc( BaseAddress ); 285 | } 286 | 287 | if ( HeaderNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress != 0 ) { 288 | 289 | Import = ( PIMAGE_IMPORT_DESCRIPTOR )( BaseAddress + 290 | HeaderNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress ); 291 | 292 | while ( Import->Characteristics ) { 293 | 294 | BdFindSystemFile( ( PSTR )( BaseAddress + Import->Name ), 295 | &ImportMap ); 296 | 297 | if ( ImportMap == NULL ) { 298 | 299 | BdFindBootFile( ( PSTR )( BaseAddress + Import->Name ), 300 | &ImportFile ); 301 | 302 | if ( ImportFile == NULL ) { 303 | 304 | BpFatalException( "FATAL: failed to find imported module \"%s\".", ( PSTR )( BaseAddress + Import->Name ) ); 305 | } 306 | 307 | ntStatus = LdrLoadSystemModule( BootRecord, 308 | ImportFile, 309 | Loader.MapList[ Loader.MapCount - 1 ].BaseAddress + 310 | Loader.MapList[ Loader.MapCount - 1 ].Length ); 311 | 312 | if ( !NT_SUCCESS( ntStatus ) ) { 313 | 314 | BpFatalException( "FATAL: failed to load \"%s\".", ImportFile->FileName ); 315 | } 316 | 317 | BdFindSystemFile( ( PSTR )( BaseAddress + Import->Name ), 318 | &ImportMap ); 319 | } 320 | 321 | ntStatus = LdrResolveImportTable( 322 | ( PVOID )BaseAddress, 323 | ( PVOID )ImportMap->BaseAddress, 324 | Import ); 325 | 326 | if ( !NT_SUCCESS( ntStatus ) ) { 327 | 328 | BpFatalException( "FATAL: failed to resolve imports for module \"%s\".", ( PSTR )( BaseAddress + Import->Name ) ); 329 | } 330 | 331 | Import++; 332 | } 333 | } 334 | 335 | return STATUS_SUCCESS; 336 | } 337 | 338 | ULONG32 339 | LdrEntryPoint( 340 | _In_ ULONG32 BaseAddress 341 | ) 342 | { 343 | PIMAGE_NT_HEADERS HeaderNt; 344 | 345 | HeaderNt = ( PIMAGE_NT_HEADERS )( BaseAddress + ( ( PIMAGE_DOS_HEADER )( BaseAddress ) )->e_lfanew ); 346 | 347 | return BaseAddress + HeaderNt->OptionalHeader.AddressOfEntryPoint; 348 | } 349 | -------------------------------------------------------------------------------- /carbload/inc/pe64.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #pragma pack( push, 1 ) 5 | 6 | // 7 | // PE Format specific structures. 8 | // 9 | 10 | #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ 11 | #define IMAGE_NT_SIGNATURE 0x00004550 // PE00 12 | 13 | typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header 14 | USHORT e_magic; // Magic number 15 | USHORT e_cblp; // Buffer on last page of file 16 | USHORT e_cp; // Pages in file 17 | USHORT e_crlc; // Relocations 18 | USHORT e_cparhdr; // Size of header in paragraphs 19 | USHORT e_minalloc; // Minimum extra paragraphs needed 20 | USHORT e_maxalloc; // Maximum extra paragraphs needed 21 | USHORT e_ss; // Initial (relative) SS value 22 | USHORT e_sp; // Initial SP value 23 | USHORT e_csum; // Checksum 24 | USHORT e_ip; // Initial IP value 25 | USHORT e_cs; // Initial (relative) CS value 26 | USHORT e_lfarlc; // File address of relocation table 27 | USHORT e_ovno; // Overlay number 28 | USHORT e_res[ 4 ]; // Reserved USHORTs 29 | USHORT e_oemid; // OEM identifier (for e_oeminfo) 30 | USHORT e_oeminfo; // OEM information; e_oemid specific 31 | USHORT e_res2[ 10 ]; // Reserved USHORTs 32 | ULONG32 e_lfanew; // File address of new exe header 33 | } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; 34 | 35 | typedef struct _IMAGE_FILE_HEADER { 36 | USHORT Machine; 37 | USHORT NumberOfSections; 38 | ULONG32 TimeDateStamp; 39 | ULONG32 PointerToSymbolTable; 40 | ULONG32 NumberOfSymbols; 41 | USHORT SizeOfOptionalHeader; 42 | USHORT Characteristics; 43 | } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; 44 | 45 | #define IMAGE_SIZEOF_FILE_HEADER 20 46 | 47 | #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. 48 | #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). 49 | #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. 50 | #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. 51 | #define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Agressively trim working set 52 | #define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses 53 | #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Buffer of machine USHORT are reversed. 54 | #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit USHORT machine. 55 | #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file 56 | #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file. 57 | #define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file. 58 | #define IMAGE_FILE_SYSTEM 0x1000 // System File. 59 | #define IMAGE_FILE_DLL 0x2000 // File is a DLL. 60 | #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine 61 | #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Buffer of machine USHORT are reversed. 62 | 63 | #define IMAGE_FILE_MACHINE_UNKNOWN 0 64 | #define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. 65 | #define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian 66 | #define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian 67 | #define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian 68 | #define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2 69 | #define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP 70 | #define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian 71 | #define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 72 | #define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian 73 | #define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian 74 | #define IMAGE_FILE_MACHINE_SH5 0x01a8 // SH5 75 | #define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian 76 | #define IMAGE_FILE_MACHINE_THUMB 0x01c2 77 | #define IMAGE_FILE_MACHINE_AM33 0x01d3 78 | #define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian 79 | #define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 80 | #define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64 81 | #define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS 82 | #define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64 83 | #define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS 84 | #define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS 85 | #define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 86 | #define IMAGE_FILE_MACHINE_TRICORE 0x0520 // Infineon 87 | #define IMAGE_FILE_MACHINE_CEF 0x0CEF 88 | #define IMAGE_FILE_MACHINE_EBC 0x0EBC // EFI Byte Code 89 | #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) 90 | #define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian 91 | #define IMAGE_FILE_MACHINE_CEE 0xC0EE 92 | 93 | typedef struct _IMAGE_DATA_DIRECTORY { 94 | ULONG32 VirtualAddress; 95 | ULONG32 Size; 96 | } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; 97 | 98 | #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 99 | 100 | typedef struct _IMAGE_OPTIONAL_HEADER64 { 101 | // 102 | // Standard fields. 103 | // 104 | 105 | USHORT Magic; 106 | UCHAR MajorLinkerVersion; 107 | UCHAR MinorLinkerVersion; 108 | ULONG32 SizeOfCode; 109 | ULONG32 SizeOfInitializedData; 110 | ULONG32 SizeOfUninitializedData; 111 | ULONG32 AddressOfEntryPoint; 112 | ULONG32 BaseOfCode; 113 | 114 | // 115 | // NT additional fields. 116 | // 117 | 118 | ULONG64 ImageBase; 119 | ULONG32 SectionAlignment; 120 | ULONG32 FileAlignment; 121 | USHORT MajorOperatingSystemVersion; 122 | USHORT MinorOperatingSystemVersion; 123 | USHORT MajorImageVersion; 124 | USHORT MinorImageVersion; 125 | USHORT MajorSubsystemVersion; 126 | USHORT MinorSubsystemVersion; 127 | ULONG32 Win32VersionValue; 128 | ULONG32 SizeOfImage; 129 | ULONG32 SizeOfHeaders; 130 | ULONG32 CheckSum; 131 | USHORT Subsystem; 132 | USHORT DllCharacteristics; 133 | ULONG64 SizeOfStackReserve; 134 | ULONG64 SizeOfStackCommit; 135 | ULONG64 SizeOfHeapReserve; 136 | ULONG64 SizeOfHeapCommit; 137 | ULONG32 LoaderFlags; 138 | ULONG32 NumberOfRvaAndSizes; 139 | IMAGE_DATA_DIRECTORY DataDirectory[ IMAGE_NUMBEROF_DIRECTORY_ENTRIES ]; 140 | } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; 141 | 142 | #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b 143 | #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b 144 | #define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 145 | 146 | typedef struct _IMAGE_NT_HEADERS { 147 | ULONG32 Signature; 148 | IMAGE_FILE_HEADER FileHeader; 149 | IMAGE_OPTIONAL_HEADER64 OptionalHeader; 150 | } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; 151 | 152 | #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER)\ 153 | ((ULONG64)(ntheader) +\ 154 | FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) +\ 155 | ((ntheader))->FileHeader.SizeOfOptionalHeader\ 156 | )) 157 | 158 | #define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. 159 | #define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. 160 | #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. 161 | #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. 162 | #define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. 163 | #define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image runs in the Posix character subsystem. 164 | #define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 // image is a native Win9x driver. 165 | #define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 // Image runs in the Windows CE subsystem. 166 | #define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 // 167 | #define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 // 168 | #define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 // 169 | #define IMAGE_SUBSYSTEM_EFI_ROM 13 170 | #define IMAGE_SUBSYSTEM_XBOX 14 171 | #define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION 16 172 | 173 | // IMAGE_LIBRARY_PROCESS_INIT 0x0001 // Reserved. 174 | // IMAGE_LIBRARY_PROCESS_TERM 0x0002 // Reserved. 175 | // IMAGE_LIBRARY_THREAD_INIT 0x0004 // Reserved. 176 | // IMAGE_LIBRARY_THREAD_TERM 0x0008 // Reserved. 177 | #define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 // DLL can move. 178 | #define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 0x0080 // Code Integrity Image 179 | #define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 // Image is NX compatible 180 | #define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 // Image understands isolation and doesn't want it 181 | #define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 // Image does not use SEH. No SE handler may reside in this image 182 | #define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 // Do not bind this image. 183 | // 0x1000 // Reserved. 184 | #define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 // Driver uses WDM model 185 | // 0x4000 // Reserved. 186 | #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 187 | 188 | #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory 189 | #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory 190 | #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory 191 | #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory 192 | #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory 193 | #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table 194 | #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory 195 | // IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) 196 | #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data 197 | #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP 198 | #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory 199 | #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory 200 | #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers 201 | #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Base Table 202 | #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors 203 | #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor 204 | 205 | #define IMAGE_SIZEOF_SHORT_NAME 8 206 | 207 | typedef struct _IMAGE_SECTION_HEADER { 208 | UCHAR Name[ IMAGE_SIZEOF_SHORT_NAME ]; 209 | union { 210 | ULONG32 PhysicalAddress; 211 | ULONG32 VirtualSize; 212 | } Misc; 213 | ULONG32 VirtualAddress; 214 | ULONG32 SizeOfRawData; 215 | ULONG32 PointerToRawData; 216 | ULONG32 PointerToRelocations; 217 | ULONG32 PointerToLinenumbers; 218 | USHORT NumberOfRelocations; 219 | USHORT NumberOfLinenumbers; 220 | ULONG32 Characteristics; 221 | } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 222 | 223 | #define IMAGE_SIZEOF_SECTION_HEADER 40 224 | 225 | // IMAGE_SCN_TYPE_REG 0x00000000 // Reserved. 226 | // IMAGE_SCN_TYPE_DSECT 0x00000001 // Reserved. 227 | // IMAGE_SCN_TYPE_NOLOAD 0x00000002 // Reserved. 228 | // IMAGE_SCN_TYPE_GROUP 0x00000004 // Reserved. 229 | #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. 230 | // IMAGE_SCN_TYPE_COPY 0x00000010 // Reserved. 231 | 232 | #define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. 233 | #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. 234 | #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. 235 | 236 | #define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. 237 | #define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. 238 | // IMAGE_SCN_TYPE_OVER 0x00000400 // Reserved. 239 | #define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. 240 | #define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. 241 | // 0x00002000 // Reserved. 242 | // IMAGE_SCN_MEM_PROTECTED - Obsolete 0x00004000 243 | #define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 // Reset speculative exceptions handling bits in the TLB entries for this section. 244 | #define IMAGE_SCN_GPREL 0x00008000 // Section content can be accessed relative to GP 245 | #define IMAGE_SCN_MEM_FARDATA 0x00008000 246 | // IMAGE_SCN_MEM_SYSHEAP - Obsolete 0x00010000 247 | #define IMAGE_SCN_MEM_PURGEABLE 0x00020000 248 | #define IMAGE_SCN_MEM_16BIT 0x00020000 249 | #define IMAGE_SCN_MEM_LOCKED 0x00040000 250 | #define IMAGE_SCN_MEM_PRELOAD 0x00080000 251 | 252 | #define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // 253 | #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // 254 | #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // 255 | #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // 256 | #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. 257 | #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // 258 | #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // 259 | #define IMAGE_SCN_ALIGN_128BYTES 0x00800000 // 260 | #define IMAGE_SCN_ALIGN_256BYTES 0x00900000 // 261 | #define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 // 262 | #define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 // 263 | #define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 // 264 | #define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 // 265 | #define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 // 266 | // Unused 0x00F00000 267 | #define IMAGE_SCN_ALIGN_MASK 0x00F00000 268 | 269 | #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations. 270 | #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. 271 | #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. 272 | #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. 273 | #define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. 274 | #define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. 275 | #define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. 276 | #define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. 277 | 278 | typedef struct _IMAGE_EXPORT_DIRECTORY { 279 | ULONG32 Characteristics; 280 | ULONG32 TimeDateStamp; 281 | USHORT MajorVersion; 282 | USHORT MinorVersion; 283 | ULONG32 Name; 284 | ULONG32 Base; 285 | ULONG32 NumberOfFunctions; 286 | ULONG32 NumberOfNames; 287 | ULONG32 AddressOfFunctions; // RVA from base of image 288 | ULONG32 AddressOfNames; // RVA from base of image 289 | ULONG32 AddressOfNameOrdinals; // RVA from base of image 290 | } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; 291 | 292 | typedef struct _IMAGE_IMPORT_BY_NAME { 293 | USHORT Hint; 294 | UCHAR Name[ 1 ]; 295 | } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; 296 | 297 | typedef struct _IMAGE_THUNK_DATA { 298 | union { 299 | ULONG64 ForwarderString; // PBYTE 300 | ULONG64 Function; // PULONG 301 | ULONG64 Ordinal; 302 | ULONG64 AddressOfData; // PIMAGE_IMPORT_BY_NAME 303 | } u1; 304 | } IMAGE_THUNK_DATA; 305 | typedef IMAGE_THUNK_DATA * PIMAGE_THUNK_DATA; 306 | 307 | #define IMAGE_ORDINAL_FLAG 0x8000000000000000 308 | #define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) 309 | #define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0) 310 | 311 | typedef struct _IMAGE_IMPORT_DESCRIPTOR { 312 | union { 313 | ULONG32 Characteristics; // 0 for terminating null import descriptor 314 | ULONG32 OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) 315 | }; 316 | ULONG32 TimeDateStamp; // 0 if not bound, 317 | // -1 if bound, and real date\time stamp 318 | // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) 319 | // O.W. date/time stamp of DLL bound to (Old BIND) 320 | 321 | ULONG32 ForwarderChain; // -1 if no forwarders 322 | ULONG32 Name; 323 | ULONG32 FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) 324 | } IMAGE_IMPORT_DESCRIPTOR; 325 | typedef IMAGE_IMPORT_DESCRIPTOR *PIMAGE_IMPORT_DESCRIPTOR; 326 | 327 | typedef struct _IMAGE_BASE_RELOCATION { 328 | ULONG32 VirtualAddress; 329 | ULONG32 SizeOfBlock; 330 | } IMAGE_BASE_RELOCATION; 331 | typedef IMAGE_BASE_RELOCATION *PIMAGE_BASE_RELOCATION; 332 | 333 | #define IMAGE_REL_BASED_ABSOLUTE 0 334 | #define IMAGE_REL_BASED_HIGH 1 335 | #define IMAGE_REL_BASED_LOW 2 336 | #define IMAGE_REL_BASED_HIGHLOW 3 337 | #define IMAGE_REL_BASED_HIGHADJ 4 338 | #define IMAGE_REL_BASED_MACHINE_SPECIFIC_5 5 339 | #define IMAGE_REL_BASED_RESERVED 6 340 | #define IMAGE_REL_BASED_MACHINE_SPECIFIC_7 7 341 | #define IMAGE_REL_BASED_MACHINE_SPECIFIC_8 8 342 | #define IMAGE_REL_BASED_MACHINE_SPECIFIC_9 9 343 | #define IMAGE_REL_BASED_DIR64 10 344 | 345 | #pragma pack( pop ) 346 | -------------------------------------------------------------------------------- /examples/single_basic/kernel/initos.c: -------------------------------------------------------------------------------- 1 | 2 | // You must add the directory of ldef.h 3 | // in your VC++ directories or additional 4 | // header directories under C/C++. 5 | // This example uses: 6 | // "$(SolutionDir)..\..\..\carboot\carbload\inc\" 7 | // inside additional header directories. 8 | 9 | #include 10 | #include "memory.h" 11 | 12 | unsigned char KiDisplayFont[ 4096 ]; 13 | unsigned int KiDisplayWidth; 14 | unsigned int KiDisplayHeight; 15 | unsigned int KiDisplayPitch; 16 | unsigned int KiDisplayBits; 17 | void* KiDisplayFrame; 18 | 19 | // 20 | // These two functions just print 21 | // a string to the screen using 22 | // a bitmap font. 23 | // 24 | 25 | void 26 | KiDisplayChar( 27 | char Character, 28 | unsigned int x, 29 | unsigned int y 30 | ) 31 | { 32 | unsigned char Line; 33 | unsigned int x_bit, y_bit; 34 | unsigned long long Offset; 35 | 36 | x *= 8; 37 | y *= 16; 38 | 39 | for ( x_bit = 0; x_bit < 16; x_bit++ ) { 40 | Line = KiDisplayFont[ Character * 16 + x_bit ]; 41 | for ( y_bit = 0; y_bit <= 8; y_bit++ ) { 42 | //if ( ( Line >> ( 8 - y_bit - 1 ) ) & 1 ) { 43 | if ( Line & ( 1 << ( 8 - y_bit - 1 ) ) ) { 44 | 45 | if ( KiDisplayWidth * 46 | KiDisplayHeight > ( y + x_bit ) * KiDisplayWidth + x + y_bit ) { 47 | 48 | switch ( KiDisplayBits ) { 49 | case 32: 50 | Offset = ( ( y + x_bit ) * KiDisplayWidth + x + y_bit ) * 4; 51 | *( ( unsigned char* )KiDisplayFrame + Offset ) = 0xE0; 52 | *( ( unsigned char* )KiDisplayFrame + Offset + 1 ) = 0xE0; 53 | *( ( unsigned char* )KiDisplayFrame + Offset + 2 ) = 0xE0; 54 | break; 55 | case 24: 56 | Offset = ( ( y + x_bit ) * KiDisplayWidth + x + y_bit ) * 3; 57 | *( ( unsigned char* )KiDisplayFrame + Offset ) = 0xE0; 58 | *( ( unsigned char* )KiDisplayFrame + Offset + 1 ) = 0xE0; 59 | *( ( unsigned char* )KiDisplayFrame + Offset + 2 ) = 0xE0; 60 | break; 61 | case 8: 62 | Offset = ( ( y + x_bit ) * KiDisplayWidth + x + y_bit ); 63 | *( ( unsigned char* )KiDisplayFrame + Offset ) = 0xFF; 64 | break; 65 | default: 66 | __assume( 0 ); 67 | } 68 | } 69 | } 70 | } 71 | } 72 | } 73 | 74 | void 75 | KiDisplayString( 76 | char* String 77 | ) 78 | { 79 | static unsigned int x_pos = 0; 80 | static unsigned int y_pos = 0; 81 | 82 | unsigned int CurrentChar; 83 | 84 | for ( CurrentChar = 0; String[ CurrentChar ] != 0; CurrentChar++ ) { 85 | 86 | switch ( String[ CurrentChar ] ) { 87 | case '\n': 88 | y_pos++; 89 | x_pos = 0; 90 | break; 91 | case '\r': 92 | x_pos = 0; 93 | break; 94 | default: 95 | KiDisplayChar( String[ CurrentChar ], x_pos, y_pos ); 96 | x_pos++; 97 | break; 98 | } 99 | } 100 | 101 | } 102 | 103 | void 104 | KiSystemStartup( 105 | PLOADER_BLOCK Loader 106 | ) 107 | { 108 | PMMPTE_HARDWARE Pxe; 109 | 110 | // 111 | // This basic kernel example just prints Hello World. 112 | // This requires us to map the Loader->Graphics.Frame and 113 | // we do this via recursive mappings, the boot loader will 114 | // always have the CR3 identity mapped. 115 | // 116 | 117 | Pxe = ( PMMPTE_HARDWARE )( __readcr3( ) & ~0xFFF ); 118 | 119 | // 120 | // Our recursive mappings start at PML4 index 510, 121 | // this means the address is 0xFFFFFF0000000000. 122 | // 123 | 124 | Pxe[ MI_RECURSIVE_INDEX ].Table.Present = 1; 125 | Pxe[ MI_RECURSIVE_INDEX ].Table.Write = 1; 126 | Pxe[ MI_RECURSIVE_INDEX ].Table.PageFrame = ( ULONG64 )Pxe >> 12; 127 | 128 | // 129 | // The framebuffer is mapped at the beginning of the 130 | // PML4 with index 509, the address is 0xFFFFFE8000000000. 131 | // 132 | // These static variables are used as page tables, to keep 133 | // this code simple. 134 | // 135 | 136 | unsigned long long LargeOffset; 137 | unsigned long long LoaderBase; 138 | __declspec( align( 4096 ) ) static unsigned long long Level4[ 512 ]; 139 | __declspec( align( 4096 ) ) static unsigned long long Level3[ 512 ]; 140 | 141 | // 142 | // Due to the mappings generated by the loader, we know that 143 | // the address of Level4 resides in the uppermost 2MB of ram, 144 | // in large page, therefore we can get the physical address 145 | // of this large page and use it to calculate any 146 | // static address in the kernel binary. 147 | // 148 | // MiConstructAddress builds an address using page table indexes, 149 | // we take the indexes of Level4, and rebuild the address with 150 | // an index of 0 for the Level1 table, which gives us our 2MB 151 | // aligned base address. 152 | // 153 | // MiIndexLevel* are all macros to get the index of a page table 154 | // from an address. 155 | // 156 | 157 | LargeOffset = ( unsigned long long )MiConstructAddress( MiIndexLevel4( Level4 ), 158 | MiIndexLevel3( Level4 ), 159 | MiIndexLevel2( Level4 ), 160 | 0 ); 161 | 162 | // 163 | // We can now use recursive mappings to get the physical address 164 | // of our 2MB page, we store this in LoaderBase. 165 | // 166 | 167 | LoaderBase = MiReferenceLevel3Entry( 168 | MiIndexLevel4( LargeOffset ), 169 | MiIndexLevel3( LargeOffset ) )[ MiIndexLevel2( LargeOffset ) ].Entry.PageFrame << 12; 170 | 171 | // 172 | // Map the index 509 to our Level4 table. 173 | // 174 | 175 | Pxe[ 509 ].Table.Present = 1; 176 | Pxe[ 509 ].Table.Write = 1; 177 | Pxe[ 509 ].Table.PageFrame = ( ( unsigned long long )Level4 - LargeOffset + LoaderBase ) >> 12; 178 | 179 | // 180 | // Use recursive mappings to map the rest, we use large pages 181 | // and map 4MB of the frame buffer 182 | // 183 | 184 | MiReferenceLevel4Entry( 509 )[ 0 ].Table.Present = 1; 185 | MiReferenceLevel4Entry( 509 )[ 0 ].Table.Write = 1; 186 | MiReferenceLevel4Entry( 509 )[ 0 ].Table.PageFrame = ( ( unsigned long long )Level3 - LargeOffset + LoaderBase ) >> 12; 187 | 188 | MiReferenceLevel3Entry( 509, 0 )[ 0 ].Table.Present = 1; 189 | MiReferenceLevel3Entry( 509, 0 )[ 0 ].Table.Write = 1; 190 | MiReferenceLevel3Entry( 509, 0 )[ 0 ].Table.Large = 1; 191 | MiReferenceLevel3Entry( 509, 0 )[ 0 ].Table.PageFrame = ( unsigned long long )Loader->Graphics.Frame >> 12; 192 | 193 | MiReferenceLevel3Entry( 509, 0 )[ 1 ].Table.Present = 1; 194 | MiReferenceLevel3Entry( 509, 0 )[ 1 ].Table.Write = 1; 195 | MiReferenceLevel3Entry( 509, 0 )[ 1 ].Table.Large = 1; 196 | MiReferenceLevel3Entry( 509, 0 )[ 1 ].Table.PageFrame = ( ( unsigned long long )Loader->Graphics.Frame + 0x200000 ) >> 12; 197 | 198 | KiDisplayFrame = MiConstructAddress( 509, 0, 0, 0 ); 199 | 200 | KiDisplayWidth = Loader->Graphics.Width; 201 | KiDisplayHeight = Loader->Graphics.Height; 202 | KiDisplayPitch = Loader->Graphics.Pitch; 203 | KiDisplayBits = Loader->Graphics.Bpp; 204 | 205 | char LoaderName[ 5 ] = { 0 }; 206 | 207 | *( unsigned int* )LoaderName = Loader->LoaderSig; 208 | 209 | KiDisplayString( "Hello World!\n\n" ); 210 | KiDisplayString( "Loaded by " ); 211 | KiDisplayString( LoaderName ); 212 | KiDisplayString( "!\n" ); 213 | 214 | __halt( ); 215 | } 216 | 217 | unsigned char KiDisplayFont[ 4096 ] = { 218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 220 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 221 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 222 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 223 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 224 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 225 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 226 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 227 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 228 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 229 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 230 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 233 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 234 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 237 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 238 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 241 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 242 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 243 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 244 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 245 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 246 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 247 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 248 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 249 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 250 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 251 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 252 | 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 253 | 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x12, 0x7e, 0x24, 0x24, 0x7e, 0x48, 0x48, 0x48, 0x00, 0x00, 254 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x3e, 0x49, 0x48, 0x38, 0x0e, 0x09, 0x49, 0x3e, 0x08, 0x00, 0x00, 255 | 0x00, 0x00, 0x00, 0x00, 0x31, 0x4a, 0x4a, 0x34, 0x08, 0x08, 0x16, 0x29, 0x29, 0x46, 0x00, 0x00, 256 | 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x14, 0x18, 0x29, 0x45, 0x42, 0x46, 0x39, 0x00, 0x00, 257 | 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 258 | 0x00, 0x00, 0x00, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 259 | 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 260 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x2a, 0x1c, 0x2a, 0x49, 0x08, 0x00, 0x00, 0x00, 261 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 262 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x10, 263 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 264 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 265 | 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x40, 0x00, 0x00, 266 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x46, 0x4a, 0x52, 0x62, 0x42, 0x24, 0x18, 0x00, 0x00, 267 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 268 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x0c, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, 269 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x1c, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, 270 | 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x14, 0x24, 0x44, 0x44, 0x7e, 0x04, 0x04, 0x04, 0x00, 0x00, 271 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 272 | 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 273 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 274 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 275 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, 0x04, 0x38, 0x00, 0x00, 276 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 277 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x10, 0x00, 278 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 279 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 280 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 281 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x04, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 282 | 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x4a, 0x56, 0x52, 0x52, 0x52, 0x4e, 0x20, 0x1e, 0x00, 0x00, 283 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 284 | 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 285 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x00, 0x00, 286 | 0x00, 0x00, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 287 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 288 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 289 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x4e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 290 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 291 | 0x00, 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 292 | 0x00, 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x00, 293 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 294 | 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 295 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x66, 0x66, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 296 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x46, 0x42, 0x00, 0x00, 297 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 298 | 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 299 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x66, 0x3c, 0x03, 0x00, 300 | 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x48, 0x44, 0x44, 0x42, 0x42, 0x00, 0x00, 301 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, 302 | 0x00, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 303 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 304 | 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 305 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x5a, 0x66, 0x66, 0x42, 0x42, 0x00, 0x00, 306 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x00, 0x00, 307 | 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 308 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, 309 | 0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, 310 | 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x02, 0x00, 0x00, 311 | 0x00, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00, 312 | 0x00, 0x00, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 313 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 314 | 0x00, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 315 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 316 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x00, 0x00, 317 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 318 | 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 319 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 320 | 0x00, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 321 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3a, 0x44, 0x44, 0x44, 0x38, 0x20, 0x3c, 0x42, 0x42, 0x3c, 322 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 323 | 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 324 | 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x48, 0x30, 325 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 326 | 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 327 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x00, 0x00, 328 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 329 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 330 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 331 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 332 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 333 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x3c, 0x00, 0x00, 334 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0c, 0x00, 0x00, 335 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 336 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 337 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 338 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x42, 0x00, 0x00, 339 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x3c, 340 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x00, 341 | 0x00, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x08, 0x08, 0x10, 0x20, 0x10, 0x08, 0x08, 0x10, 0x10, 0x0c, 342 | 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 343 | 0x00, 0x00, 0x00, 0x30, 0x08, 0x08, 0x10, 0x10, 0x08, 0x04, 0x08, 0x10, 0x10, 0x08, 0x08, 0x30, 344 | 0x00, 0x00, 0x00, 0x31, 0x49, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 345 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x73, 0xca, 0x4b, 0xca, 0x73, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 346 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x71, 0xca, 0x73, 0xc2, 0x42, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 347 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x49, 0xca, 0x7a, 0xca, 0x49, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 348 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x73, 0xca, 0x73, 0xca, 0x72, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 349 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x4b, 0xea, 0x5b, 0xca, 0x4b, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 350 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x74, 0xa6, 0x25, 0xa4, 0x74, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 351 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x4b, 0xea, 0x5b, 0xca, 0x4b, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 352 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x31, 0x88, 0x73, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 353 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x79, 0xc2, 0x79, 0xc0, 0x7b, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 354 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x4b, 0xc9, 0x79, 0xc9, 0x49, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 355 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x25, 0xa4, 0x3c, 0xa4, 0x24, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 356 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x45, 0xc4, 0x44, 0xa8, 0x10, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 357 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x72, 0xca, 0x72, 0xc2, 0x43, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 358 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x72, 0xca, 0x72, 0xc2, 0x43, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 359 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x0e, 0x89, 0x0e, 0x8a, 0x09, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 360 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x31, 0x88, 0x73, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 361 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x31, 0x88, 0x73, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 362 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x71, 0xca, 0x4a, 0xca, 0x71, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 363 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x72, 0xca, 0x72, 0xc2, 0x41, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 364 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x72, 0xca, 0x72, 0xc2, 0x41, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 365 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x3b, 0xc1, 0x31, 0x89, 0x71, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 366 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x42, 0xc2, 0x39, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 367 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x22, 0xb6, 0x2a, 0xa2, 0x22, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 368 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x3b, 0xc2, 0x33, 0x8a, 0x72, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 369 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x7b, 0xc2, 0x7b, 0xc2, 0x7a, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 370 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x32, 0x8a, 0x71, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 371 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x33, 0xc4, 0x25, 0x94, 0x63, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 372 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x32, 0x8a, 0x71, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 373 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x41, 0xc0, 0x3b, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 374 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x0e, 0x90, 0x0c, 0x82, 0x1c, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 375 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x31, 0xca, 0x49, 0xc8, 0x33, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 376 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x1c, 0x92, 0x1c, 0x90, 0x10, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 377 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x33, 0xca, 0x7b, 0xca, 0x4a, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 378 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 379 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 380 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x49, 0x48, 0x48, 0x49, 0x3e, 0x08, 0x08, 0x00, 0x00, 381 | 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x3e, 0x61, 0x00, 0x00, 382 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x3c, 0x24, 0x42, 0x42, 0x24, 0x3c, 0x42, 0x00, 0x00, 0x00, 383 | 0x00, 0x00, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x7f, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 384 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 385 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x3c, 0x42, 0x42, 0x3c, 0x02, 0x42, 0x3c, 0x00, 0x00, 386 | 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 387 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x99, 0xa5, 0xa1, 0xa1, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 388 | 0x00, 0x00, 0x1c, 0x02, 0x1e, 0x22, 0x1e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 389 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x24, 0x24, 0x48, 0x24, 0x24, 0x12, 0x12, 0x00, 0x00, 390 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x00, 0x00, 391 | 0xaa, 0x00, 0x80, 0x3a, 0xc2, 0x33, 0x8a, 0x72, 0x80, 0x00, 0x80, 0x03, 0x80, 0x00, 0x80, 0x55, 392 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0xb9, 0xa5, 0xa5, 0xb9, 0xa9, 0xa5, 0x42, 0x3c, 0x00, 0x00, 393 | 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 394 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 395 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 396 | 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x18, 0x20, 0x40, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 397 | 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x38, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 398 | 0x00, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 399 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x66, 0x59, 0x40, 0x80, 400 | 0x00, 0x00, 0x00, 0x00, 0x3f, 0x7a, 0x7a, 0x7a, 0x3a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 401 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 402 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, 403 | 0x00, 0x00, 0x00, 0x10, 0x30, 0x50, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 404 | 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 405 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x48, 0x24, 0x24, 0x12, 0x24, 0x24, 0x48, 0x48, 0x00, 0x00, 406 | 0x00, 0x00, 0x00, 0x00, 0x22, 0x62, 0x24, 0x28, 0x28, 0x12, 0x16, 0x2a, 0x4e, 0x42, 0x00, 0x00, 407 | 0x00, 0x00, 0x00, 0x00, 0x22, 0x62, 0x24, 0x28, 0x28, 0x14, 0x1a, 0x22, 0x44, 0x4e, 0x00, 0x00, 408 | 0x00, 0x00, 0x00, 0x00, 0x62, 0x12, 0x24, 0x18, 0x68, 0x12, 0x16, 0x2a, 0x4e, 0x42, 0x00, 0x00, 409 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x20, 0x40, 0x42, 0x42, 0x3c, 0x00, 0x00, 410 | 0x30, 0x0c, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 411 | 0x0c, 0x30, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 412 | 0x18, 0x24, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 413 | 0x32, 0x4c, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 414 | 0x24, 0x24, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 415 | 0x18, 0x24, 0x18, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 416 | 0x00, 0x00, 0x00, 0x00, 0x1f, 0x28, 0x48, 0x48, 0x7f, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x00, 0x00, 417 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x08, 0x30, 418 | 0x30, 0x0c, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 419 | 0x0c, 0x30, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 420 | 0x18, 0x24, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 421 | 0x24, 0x24, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 422 | 0x18, 0x06, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 423 | 0x0c, 0x30, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 424 | 0x18, 0x24, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 425 | 0x24, 0x24, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 426 | 0x00, 0x00, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0xf2, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 427 | 0x32, 0x4c, 0x00, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x46, 0x42, 0x00, 0x00, 428 | 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 429 | 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 430 | 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 431 | 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 432 | 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 433 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x24, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x00, 434 | 0x00, 0x00, 0x00, 0x02, 0x3a, 0x44, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62, 0x22, 0x5c, 0x40, 0x00, 435 | 0x30, 0x0c, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 436 | 0x0c, 0x30, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 437 | 0x18, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 438 | 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 439 | 0x0c, 0x30, 0x00, 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 440 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x78, 0x44, 0x42, 0x42, 0x44, 0x78, 0x40, 0x40, 0x40, 0x00, 0x00, 441 | 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x48, 0x58, 0x44, 0x42, 0x42, 0x52, 0x4c, 0x00, 0x00, 442 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 443 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 444 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 445 | 0x00, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 446 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 447 | 0x00, 0x18, 0x24, 0x18, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 448 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x49, 0x09, 0x3f, 0x48, 0x48, 0x49, 0x3e, 0x00, 0x00, 449 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x08, 0x30, 450 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 451 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 452 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 453 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 454 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 455 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 456 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 457 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 458 | 0x00, 0x00, 0x32, 0x0c, 0x14, 0x22, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 459 | 0x00, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 460 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 461 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 462 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 463 | 0x00, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 464 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 465 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 466 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3c, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62, 0x3c, 0x40, 0x00, 467 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 468 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 469 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 470 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 471 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x3c, 472 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 473 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x3c, 474 | }; 475 | -------------------------------------------------------------------------------- /examples/multi_basic/kernel/initos.c: -------------------------------------------------------------------------------- 1 | 2 | // You must add the directory of ldef.h 3 | // in your VC++ directories or additional 4 | // header directories under C/C++. 5 | // This example uses: 6 | // "$(SolutionDir)..\..\..\carboot\carbload\inc\" 7 | // inside additional header directories. 8 | 9 | #include 10 | #include "memory.h" 11 | 12 | // 13 | // Import our function from hal.c, hal.sys. 14 | // 15 | 16 | __declspec( dllimport ) 17 | void 18 | HalExtExample( 19 | 20 | ); 21 | 22 | unsigned char KiDisplayFont[ 4096 ]; 23 | unsigned int KiDisplayWidth; 24 | unsigned int KiDisplayHeight; 25 | unsigned int KiDisplayPitch; 26 | unsigned int KiDisplayBits; 27 | void* KiDisplayFrame; 28 | 29 | // 30 | // These two functions just print 31 | // a string to the screen using 32 | // a bitmap font. 33 | // 34 | 35 | void 36 | KiDisplayChar( 37 | char Character, 38 | unsigned int x, 39 | unsigned int y 40 | ) 41 | { 42 | unsigned char Line; 43 | unsigned int x_bit, y_bit; 44 | unsigned long long Offset; 45 | 46 | x *= 8; 47 | y *= 16; 48 | 49 | for ( x_bit = 0; x_bit < 16; x_bit++ ) { 50 | Line = KiDisplayFont[ Character * 16 + x_bit ]; 51 | for ( y_bit = 0; y_bit <= 8; y_bit++ ) { 52 | //if ( ( Line >> ( 8 - y_bit - 1 ) ) & 1 ) { 53 | if ( Line & ( 1 << ( 8 - y_bit - 1 ) ) ) { 54 | 55 | if ( KiDisplayWidth * 56 | KiDisplayHeight > ( y + x_bit ) * KiDisplayWidth + x + y_bit ) { 57 | 58 | switch ( KiDisplayBits ) { 59 | case 32: 60 | Offset = ( ( y + x_bit ) * KiDisplayWidth + x + y_bit ) * 4; 61 | *( ( unsigned char* )KiDisplayFrame + Offset ) = 0xE0; 62 | *( ( unsigned char* )KiDisplayFrame + Offset + 1 ) = 0xE0; 63 | *( ( unsigned char* )KiDisplayFrame + Offset + 2 ) = 0xE0; 64 | break; 65 | case 24: 66 | Offset = ( ( y + x_bit ) * KiDisplayWidth + x + y_bit ) * 3; 67 | *( ( unsigned char* )KiDisplayFrame + Offset ) = 0xE0; 68 | *( ( unsigned char* )KiDisplayFrame + Offset + 1 ) = 0xE0; 69 | *( ( unsigned char* )KiDisplayFrame + Offset + 2 ) = 0xE0; 70 | break; 71 | case 8: 72 | Offset = ( ( y + x_bit ) * KiDisplayWidth + x + y_bit ); 73 | *( ( unsigned char* )KiDisplayFrame + Offset ) = 0xFF; 74 | break; 75 | default: 76 | __assume( 0 ); 77 | } 78 | } 79 | } 80 | } 81 | } 82 | } 83 | 84 | __declspec( dllexport ) 85 | void 86 | KiDisplayString( 87 | char* String 88 | ) 89 | { 90 | static unsigned int x_pos = 0; 91 | static unsigned int y_pos = 0; 92 | 93 | unsigned int CurrentChar; 94 | 95 | for ( CurrentChar = 0; String[ CurrentChar ] != 0; CurrentChar++ ) { 96 | 97 | switch ( String[ CurrentChar ] ) { 98 | case '\n': 99 | y_pos++; 100 | x_pos = 0; 101 | break; 102 | case '\r': 103 | x_pos = 0; 104 | break; 105 | default: 106 | KiDisplayChar( String[ CurrentChar ], x_pos, y_pos ); 107 | x_pos++; 108 | break; 109 | } 110 | } 111 | 112 | } 113 | 114 | void 115 | KiSystemStartup( 116 | PLOADER_BLOCK Loader 117 | ) 118 | { 119 | PMMPTE_HARDWARE Pxe; 120 | 121 | // 122 | // This basic kernel example just prints Hello World. 123 | // This requires us to map the Loader->Graphics.Frame and 124 | // we do this via recursive mappings, the boot loader will 125 | // always have the CR3 identity mapped. 126 | // 127 | 128 | Pxe = ( PMMPTE_HARDWARE )( __readcr3( ) & ~0xFFF ); 129 | 130 | // 131 | // Our recursive mappings start at PML4 index 510, 132 | // this means the address is 0xFFFFFF0000000000. 133 | // 134 | 135 | Pxe[ MI_RECURSIVE_INDEX ].Table.Present = 1; 136 | Pxe[ MI_RECURSIVE_INDEX ].Table.Write = 1; 137 | Pxe[ MI_RECURSIVE_INDEX ].Table.PageFrame = ( ULONG64 )Pxe >> 12; 138 | 139 | // 140 | // The framebuffer is mapped at the beginning of the 141 | // PML4 with index 509, the address is 0xFFFFFE8000000000. 142 | // 143 | // These static variables are used as page tables, to keep 144 | // this code simple. 145 | // 146 | 147 | unsigned long long LargeOffset; 148 | unsigned long long LoaderBase; 149 | __declspec( align( 4096 ) ) static unsigned long long Level4[ 512 ]; 150 | __declspec( align( 4096 ) ) static unsigned long long Level3[ 512 ]; 151 | 152 | // 153 | // Due to the mappings generated by the loader, we know that 154 | // the address of Level4 resides in the uppermost 2MB of ram, 155 | // in large page, therefore we can get the physical address 156 | // of this large page and use it to calculate any 157 | // static address in the kernel binary. 158 | // 159 | // MiConstructAddress builds an address using page table indexes, 160 | // we take the indexes of Level4, and rebuild the address with 161 | // an index of 0 for the Level1 table, which gives us our 2MB 162 | // aligned base address. 163 | // 164 | // MiIndexLevel* are all macros to get the index of a page table 165 | // from an address. 166 | // 167 | 168 | LargeOffset = ( unsigned long long )MiConstructAddress( MiIndexLevel4( Level4 ), 169 | MiIndexLevel3( Level4 ), 170 | MiIndexLevel2( Level4 ), 171 | 0 ); 172 | 173 | // 174 | // We can now use recursive mappings to get the physical address 175 | // of our 2MB page, we store this in LoaderBase. 176 | // 177 | 178 | LoaderBase = MiReferenceLevel3Entry( 179 | MiIndexLevel4( LargeOffset ), 180 | MiIndexLevel3( LargeOffset ) )[ MiIndexLevel2( LargeOffset ) ].Entry.PageFrame << 12; 181 | 182 | // 183 | // Map the index 509 to our Level4 table. 184 | // 185 | 186 | Pxe[ 509 ].Table.Present = 1; 187 | Pxe[ 509 ].Table.Write = 1; 188 | Pxe[ 509 ].Table.PageFrame = ( ( unsigned long long )Level4 - LargeOffset + LoaderBase ) >> 12; 189 | 190 | // 191 | // Use recursive mappings to map the rest, we use large pages 192 | // and map 4MB of the frame buffer 193 | // 194 | 195 | MiReferenceLevel4Entry( 509 )[ 0 ].Table.Present = 1; 196 | MiReferenceLevel4Entry( 509 )[ 0 ].Table.Write = 1; 197 | MiReferenceLevel4Entry( 509 )[ 0 ].Table.PageFrame = ( ( unsigned long long )Level3 - LargeOffset + LoaderBase ) >> 12; 198 | 199 | MiReferenceLevel3Entry( 509, 0 )[ 0 ].Table.Present = 1; 200 | MiReferenceLevel3Entry( 509, 0 )[ 0 ].Table.Write = 1; 201 | MiReferenceLevel3Entry( 509, 0 )[ 0 ].Table.Large = 1; 202 | MiReferenceLevel3Entry( 509, 0 )[ 0 ].Table.PageFrame = ( unsigned long long )Loader->Graphics.Frame >> 12; 203 | 204 | MiReferenceLevel3Entry( 509, 0 )[ 1 ].Table.Present = 1; 205 | MiReferenceLevel3Entry( 509, 0 )[ 1 ].Table.Write = 1; 206 | MiReferenceLevel3Entry( 509, 0 )[ 1 ].Table.Large = 1; 207 | MiReferenceLevel3Entry( 509, 0 )[ 1 ].Table.PageFrame = ( ( unsigned long long )Loader->Graphics.Frame + 0x200000 ) >> 12; 208 | 209 | KiDisplayFrame = MiConstructAddress( 509, 0, 0, 0 ); 210 | 211 | KiDisplayWidth = Loader->Graphics.Width; 212 | KiDisplayHeight = Loader->Graphics.Height; 213 | KiDisplayPitch = Loader->Graphics.Pitch; 214 | KiDisplayBits = Loader->Graphics.Bpp; 215 | 216 | char LoaderName[ 5 ] = { 0 }; 217 | 218 | *( unsigned int* )LoaderName = Loader->LoaderSig; 219 | 220 | KiDisplayString( "Hello World!\n\n" ); 221 | KiDisplayString( "Loaded by " ); 222 | KiDisplayString( LoaderName ); 223 | KiDisplayString( "!\n" ); 224 | 225 | // 226 | // Call into hal.sys. 227 | // 228 | 229 | HalExtExample( ); 230 | 231 | __halt( ); 232 | } 233 | 234 | unsigned char KiDisplayFont[ 4096 ] = { 235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 237 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 238 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 241 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 242 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 243 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 244 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 245 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 246 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 247 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 248 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 249 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 250 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 252 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 254 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 255 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 258 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 259 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 260 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 261 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 262 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 263 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 264 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 265 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 266 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 267 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 268 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 269 | 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 270 | 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x12, 0x7e, 0x24, 0x24, 0x7e, 0x48, 0x48, 0x48, 0x00, 0x00, 271 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x3e, 0x49, 0x48, 0x38, 0x0e, 0x09, 0x49, 0x3e, 0x08, 0x00, 0x00, 272 | 0x00, 0x00, 0x00, 0x00, 0x31, 0x4a, 0x4a, 0x34, 0x08, 0x08, 0x16, 0x29, 0x29, 0x46, 0x00, 0x00, 273 | 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x14, 0x18, 0x29, 0x45, 0x42, 0x46, 0x39, 0x00, 0x00, 274 | 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 275 | 0x00, 0x00, 0x00, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 276 | 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 277 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x2a, 0x1c, 0x2a, 0x49, 0x08, 0x00, 0x00, 0x00, 278 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 279 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x10, 280 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 281 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 282 | 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x40, 0x00, 0x00, 283 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x46, 0x4a, 0x52, 0x62, 0x42, 0x24, 0x18, 0x00, 0x00, 284 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 285 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x0c, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, 286 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x1c, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, 287 | 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x14, 0x24, 0x44, 0x44, 0x7e, 0x04, 0x04, 0x04, 0x00, 0x00, 288 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 289 | 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 290 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 291 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 292 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, 0x04, 0x38, 0x00, 0x00, 293 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 294 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x10, 0x00, 295 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 296 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 297 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 298 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x04, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 299 | 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x4a, 0x56, 0x52, 0x52, 0x52, 0x4e, 0x20, 0x1e, 0x00, 0x00, 300 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 301 | 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 302 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x00, 0x00, 303 | 0x00, 0x00, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 304 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 305 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 306 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x4e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 307 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 308 | 0x00, 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 309 | 0x00, 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x00, 310 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 311 | 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 312 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x66, 0x66, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 313 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x46, 0x42, 0x00, 0x00, 314 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 315 | 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 316 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x66, 0x3c, 0x03, 0x00, 317 | 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x48, 0x44, 0x44, 0x42, 0x42, 0x00, 0x00, 318 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, 319 | 0x00, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 320 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 321 | 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 322 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x5a, 0x66, 0x66, 0x42, 0x42, 0x00, 0x00, 323 | 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x00, 0x00, 324 | 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 325 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, 326 | 0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, 327 | 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x02, 0x00, 0x00, 328 | 0x00, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00, 329 | 0x00, 0x00, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 330 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 331 | 0x00, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 332 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 333 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x00, 0x00, 334 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 335 | 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 336 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 337 | 0x00, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 338 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3a, 0x44, 0x44, 0x44, 0x38, 0x20, 0x3c, 0x42, 0x42, 0x3c, 339 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 340 | 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 341 | 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x48, 0x30, 342 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 343 | 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 344 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x00, 0x00, 345 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 346 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 347 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 348 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 349 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 350 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x3c, 0x00, 0x00, 351 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0c, 0x00, 0x00, 352 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 353 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 354 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 355 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x42, 0x00, 0x00, 356 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x3c, 357 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x00, 358 | 0x00, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x08, 0x08, 0x10, 0x20, 0x10, 0x08, 0x08, 0x10, 0x10, 0x0c, 359 | 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 360 | 0x00, 0x00, 0x00, 0x30, 0x08, 0x08, 0x10, 0x10, 0x08, 0x04, 0x08, 0x10, 0x10, 0x08, 0x08, 0x30, 361 | 0x00, 0x00, 0x00, 0x31, 0x49, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 362 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x73, 0xca, 0x4b, 0xca, 0x73, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 363 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x71, 0xca, 0x73, 0xc2, 0x42, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 364 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x49, 0xca, 0x7a, 0xca, 0x49, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 365 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x73, 0xca, 0x73, 0xca, 0x72, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 366 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x4b, 0xea, 0x5b, 0xca, 0x4b, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 367 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x74, 0xa6, 0x25, 0xa4, 0x74, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 368 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x4b, 0xea, 0x5b, 0xca, 0x4b, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 369 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x31, 0x88, 0x73, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 370 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x79, 0xc2, 0x79, 0xc0, 0x7b, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 371 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x4b, 0xc9, 0x79, 0xc9, 0x49, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 372 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x25, 0xa4, 0x3c, 0xa4, 0x24, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 373 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x45, 0xc4, 0x44, 0xa8, 0x10, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 374 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x72, 0xca, 0x72, 0xc2, 0x43, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 375 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x72, 0xca, 0x72, 0xc2, 0x43, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 376 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x0e, 0x89, 0x0e, 0x8a, 0x09, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 377 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x31, 0x88, 0x73, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 378 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x31, 0x88, 0x73, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 379 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x71, 0xca, 0x4a, 0xca, 0x71, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 380 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x72, 0xca, 0x72, 0xc2, 0x41, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 381 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x72, 0xca, 0x72, 0xc2, 0x41, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 382 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x3b, 0xc1, 0x31, 0x89, 0x71, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 383 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x42, 0xc2, 0x39, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 384 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x22, 0xb6, 0x2a, 0xa2, 0x22, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 385 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x3b, 0xc2, 0x33, 0x8a, 0x72, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 386 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x7b, 0xc2, 0x7b, 0xc2, 0x7a, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 387 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x32, 0x8a, 0x71, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 388 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x33, 0xc4, 0x25, 0x94, 0x63, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 389 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x32, 0x8a, 0x71, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 390 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x39, 0xc2, 0x41, 0xc0, 0x3b, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 391 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x0e, 0x90, 0x0c, 0x82, 0x1c, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 392 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x31, 0xca, 0x49, 0xc8, 0x33, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 393 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x1c, 0x92, 0x1c, 0x90, 0x10, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 394 | 0xaa, 0x00, 0x80, 0x00, 0x80, 0x33, 0xca, 0x7b, 0xca, 0x4a, 0x80, 0x00, 0x80, 0x00, 0x80, 0x55, 395 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 396 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 397 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x49, 0x48, 0x48, 0x49, 0x3e, 0x08, 0x08, 0x00, 0x00, 398 | 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x3e, 0x61, 0x00, 0x00, 399 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x3c, 0x24, 0x42, 0x42, 0x24, 0x3c, 0x42, 0x00, 0x00, 0x00, 400 | 0x00, 0x00, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x7f, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 401 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 402 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x3c, 0x42, 0x42, 0x3c, 0x02, 0x42, 0x3c, 0x00, 0x00, 403 | 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 404 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x99, 0xa5, 0xa1, 0xa1, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 405 | 0x00, 0x00, 0x1c, 0x02, 0x1e, 0x22, 0x1e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 406 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x24, 0x24, 0x48, 0x24, 0x24, 0x12, 0x12, 0x00, 0x00, 407 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x00, 0x00, 408 | 0xaa, 0x00, 0x80, 0x3a, 0xc2, 0x33, 0x8a, 0x72, 0x80, 0x00, 0x80, 0x03, 0x80, 0x00, 0x80, 0x55, 409 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0xb9, 0xa5, 0xa5, 0xb9, 0xa9, 0xa5, 0x42, 0x3c, 0x00, 0x00, 410 | 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 411 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 412 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 413 | 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x18, 0x20, 0x40, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 414 | 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x38, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 415 | 0x00, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 416 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x66, 0x59, 0x40, 0x80, 417 | 0x00, 0x00, 0x00, 0x00, 0x3f, 0x7a, 0x7a, 0x7a, 0x3a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 418 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 419 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, 420 | 0x00, 0x00, 0x00, 0x10, 0x30, 0x50, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 421 | 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 422 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x48, 0x24, 0x24, 0x12, 0x24, 0x24, 0x48, 0x48, 0x00, 0x00, 423 | 0x00, 0x00, 0x00, 0x00, 0x22, 0x62, 0x24, 0x28, 0x28, 0x12, 0x16, 0x2a, 0x4e, 0x42, 0x00, 0x00, 424 | 0x00, 0x00, 0x00, 0x00, 0x22, 0x62, 0x24, 0x28, 0x28, 0x14, 0x1a, 0x22, 0x44, 0x4e, 0x00, 0x00, 425 | 0x00, 0x00, 0x00, 0x00, 0x62, 0x12, 0x24, 0x18, 0x68, 0x12, 0x16, 0x2a, 0x4e, 0x42, 0x00, 0x00, 426 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x20, 0x40, 0x42, 0x42, 0x3c, 0x00, 0x00, 427 | 0x30, 0x0c, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 428 | 0x0c, 0x30, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 429 | 0x18, 0x24, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 430 | 0x32, 0x4c, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 431 | 0x24, 0x24, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 432 | 0x18, 0x24, 0x18, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 433 | 0x00, 0x00, 0x00, 0x00, 0x1f, 0x28, 0x48, 0x48, 0x7f, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x00, 0x00, 434 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x08, 0x30, 435 | 0x30, 0x0c, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 436 | 0x0c, 0x30, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 437 | 0x18, 0x24, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 438 | 0x24, 0x24, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 439 | 0x18, 0x06, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 440 | 0x0c, 0x30, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 441 | 0x18, 0x24, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 442 | 0x24, 0x24, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 443 | 0x00, 0x00, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0xf2, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 444 | 0x32, 0x4c, 0x00, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x46, 0x42, 0x00, 0x00, 445 | 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 446 | 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 447 | 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 448 | 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 449 | 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 450 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x24, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x00, 451 | 0x00, 0x00, 0x00, 0x02, 0x3a, 0x44, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62, 0x22, 0x5c, 0x40, 0x00, 452 | 0x30, 0x0c, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 453 | 0x0c, 0x30, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 454 | 0x18, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 455 | 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 456 | 0x0c, 0x30, 0x00, 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 457 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x78, 0x44, 0x42, 0x42, 0x44, 0x78, 0x40, 0x40, 0x40, 0x00, 0x00, 458 | 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x48, 0x58, 0x44, 0x42, 0x42, 0x52, 0x4c, 0x00, 0x00, 459 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 460 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 461 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 462 | 0x00, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 463 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 464 | 0x00, 0x18, 0x24, 0x18, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 465 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x49, 0x09, 0x3f, 0x48, 0x48, 0x49, 0x3e, 0x00, 0x00, 466 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x08, 0x30, 467 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 468 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 469 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 470 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 471 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 472 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 473 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 474 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 475 | 0x00, 0x00, 0x32, 0x0c, 0x14, 0x22, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 476 | 0x00, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 477 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 478 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 479 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 480 | 0x00, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 481 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 482 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 483 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3c, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62, 0x3c, 0x40, 0x00, 484 | 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 485 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 486 | 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 487 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 488 | 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x3c, 489 | 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 490 | 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x26, 0x1a, 0x02, 0x02, 0x3c, 491 | }; 492 | --------------------------------------------------------------------------------