├── 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 | 
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 |
--------------------------------------------------------------------------------