mirror of https://gitlab.com/nakst/essence
boot: Implement multiboot2 loader
It's based on uefi loader and paves the road to loading on platforms that are not directly supported like coreboot. Right now it supports only 64-bit kernel but 32-bit can be added later.
This commit is contained in:
parent
0a70170952
commit
015fb75973
|
@ -0,0 +1,343 @@
|
|||
// This file is part of the Essence operating system.
|
||||
// It is released under the terms of the MIT license -- see LICENSE.md.
|
||||
// Written by: phcoder.
|
||||
|
||||
#include "multiboot2.h"
|
||||
|
||||
#define ENTRIES_PER_PAGE_TABLE (512)
|
||||
#define ENTRIES_PER_PAGE_TABLE_BITS (9)
|
||||
#define K_PAGE_SIZE (4096)
|
||||
#define K_PAGE_BITS (12)
|
||||
|
||||
typedef __UINT8_TYPE__ uint8_t;
|
||||
typedef __UINT16_TYPE__ uint16_t;
|
||||
typedef __UINT32_TYPE__ uint32_t;
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
typedef struct VideoModeInformation {
|
||||
uint8_t valid : 1, edidValid : 1;
|
||||
uint8_t bitsPerPixel;
|
||||
uint16_t widthPixels, heightPixels;
|
||||
uint16_t bytesPerScanlineLinear;
|
||||
uint64_t bufferPhysical;
|
||||
uint8_t edid[128];
|
||||
} VideoModeInformation;
|
||||
|
||||
typedef struct ElfHeader {
|
||||
uint32_t magicNumber; // 0x7F followed by 'ELF'
|
||||
uint8_t bits; // 1 = 32 bit, 2 = 64 bit
|
||||
uint8_t endianness; // 1 = LE, 2 = BE
|
||||
uint8_t version1;
|
||||
uint8_t abi; // 0 = System V
|
||||
uint8_t _unused0[8];
|
||||
uint16_t type; // 1 = relocatable, 2 = executable, 3 = shared
|
||||
uint16_t instructionSet; // 0x03 = x86, 0x28 = ARM, 0x3E = x86-64, 0xB7 = AArch64
|
||||
uint32_t version2;
|
||||
uint64_t entry;
|
||||
uint64_t programHeaderTable;
|
||||
uint64_t sectionHeaderTable;
|
||||
uint32_t flags;
|
||||
uint16_t headerSize;
|
||||
uint16_t programHeaderEntrySize;
|
||||
uint16_t programHeaderEntries;
|
||||
uint16_t sectionHeaderEntrySize;
|
||||
uint16_t sectionHeaderEntries;
|
||||
uint16_t sectionNameIndex;
|
||||
} ElfHeader;
|
||||
|
||||
typedef struct ElfSectionHeader {
|
||||
uint32_t name; // Offset into section header->sectionNameIndex.
|
||||
uint32_t type; // 4 = rela
|
||||
uint64_t flags;
|
||||
uint64_t address;
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
uint32_t link;
|
||||
uint32_t info;
|
||||
uint64_t align;
|
||||
uint64_t entrySize;
|
||||
} ElfSectionHeader;
|
||||
|
||||
typedef struct ElfProgramHeader {
|
||||
uint32_t type; // 0 = unused, 1 = load, 2 = dynamic, 3 = interp, 4 = note
|
||||
uint32_t flags; // 1 = executable, 2 = writable, 4 = readable
|
||||
uint64_t fileOffset;
|
||||
uint64_t virtualAddress;
|
||||
uint64_t _unused0;
|
||||
uint64_t dataInFile;
|
||||
uint64_t segmentSize;
|
||||
uint64_t alignment;
|
||||
} ElfProgramHeader;
|
||||
|
||||
typedef struct __attribute__((packed)) GDTData {
|
||||
uint16_t length;
|
||||
uint64_t address;
|
||||
} GDTData;
|
||||
|
||||
typedef struct MemoryRegion {
|
||||
uint64_t base, pages;
|
||||
} MemoryRegion;
|
||||
|
||||
#define MAX_MEMORY_REGIONS (1024)
|
||||
|
||||
struct {
|
||||
// 0x106000
|
||||
char rsdp_copy[4096];
|
||||
// 0x107000 Graphics info
|
||||
VideoModeInformation graphics_info;
|
||||
char filler[0xFE8 - sizeof(VideoModeInformation)];
|
||||
// 0x107FE8 RSDP address
|
||||
uint64_t rsdp_address;
|
||||
// 0x107FF0 Installation ID
|
||||
char iid[16];
|
||||
} kernel_params __attribute__((section(".kernel_params")));
|
||||
|
||||
// 0x140000-0x150000 Identity paging tables
|
||||
uint64_t paging_table[0x2000] __attribute__((section(".paging_table"), aligned(4096)));
|
||||
|
||||
// 0x160000-0x170000 Memory regions
|
||||
MemoryRegion memoryRegions[MAX_MEMORY_REGIONS] __attribute__((section(".memory_map")));
|
||||
int memoryRegionCount = 0;
|
||||
|
||||
// 0x1c0000-0x1e0000 Identity paging tables
|
||||
uint64_t kernel_paging_table[0x2000] __attribute__((section(".kernel_paging_table"), aligned(4096)));
|
||||
// 0x180000-0x1C0000 Loader (this)
|
||||
// 0x1F0000-0x200000 Stack
|
||||
uint8_t stack[0x10000] __attribute__((section(".stack"), aligned(4096)));
|
||||
|
||||
uint64_t kernel_start;
|
||||
|
||||
static void ZeroMemory(void *pointer, uint64_t size) {
|
||||
char *d = (char *) pointer;
|
||||
|
||||
for (uintptr_t i = 0; i < size; i++) {
|
||||
d[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void CopyMemory(void *dest, void *src, uint64_t size) {
|
||||
char *d = (char *) dest;
|
||||
char *s = (char *) src;
|
||||
|
||||
for (uintptr_t i = 0; i < size; i++) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t hex2val (char c) {
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
void mb2_main(void *mb2_info) {
|
||||
ElfHeader *header;
|
||||
struct multiboot_tag_old_acpi *old_acpi = 0;
|
||||
struct multiboot_tag_new_acpi *new_acpi = 0;
|
||||
struct multiboot_tag_module *kernel_module = 0, *iid_module = 0;
|
||||
const char *iid_string = 0;
|
||||
|
||||
ZeroMemory(&kernel_params, sizeof(kernel_params));
|
||||
|
||||
for (struct multiboot_tag *tag = (struct multiboot_tag *) ((uint8_t *)mb2_info + 8);
|
||||
tag->type != MULTIBOOT_TAG_TYPE_END;
|
||||
tag = (struct multiboot_tag *) ((uint8_t *) tag + ((tag->size + MULTIBOOT_TAG_ALIGN - 1) & ~(MULTIBOOT_TAG_ALIGN - 1))))
|
||||
switch(tag->type) {
|
||||
case MULTIBOOT_TAG_TYPE_ACPI_OLD:
|
||||
old_acpi = (struct multiboot_tag_old_acpi *) tag;
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
|
||||
new_acpi = (struct multiboot_tag_new_acpi *) tag;
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_MODULE: {
|
||||
struct multiboot_tag_module *module = (struct multiboot_tag_module *) tag;
|
||||
if (module->mod_end - module->mod_start == 16)
|
||||
iid_module = module;
|
||||
else
|
||||
kernel_module = module;
|
||||
break;
|
||||
}
|
||||
case MULTIBOOT_TAG_TYPE_MMAP: {
|
||||
struct multiboot_tag_mmap *mmap = (struct multiboot_tag_mmap *) tag;
|
||||
struct multiboot_mmap_entry *mmap_entry = mmap->entries;
|
||||
for (; (uint8_t *)mmap_entry < (uint8_t *)tag + tag->size && memoryRegionCount != MAX_MEMORY_REGIONS - 1;
|
||||
mmap_entry = (struct multiboot_mmap_entry *) ((uint8_t *) mmap_entry + mmap->entry_size)) {
|
||||
if (mmap_entry->type != MULTIBOOT_MEMORY_AVAILABLE)
|
||||
continue;
|
||||
uint64_t st = (mmap_entry->addr + 0xfff) & ~0xfffULL;
|
||||
uint64_t end = (mmap_entry->addr + mmap_entry->len) & ~0xfffULL;
|
||||
if (st < 0x300000)
|
||||
st = 0x300000;
|
||||
if (st >= end)
|
||||
continue;
|
||||
|
||||
memoryRegions[memoryRegionCount].base = st;
|
||||
memoryRegions[memoryRegionCount].pages = (end - st) >> 12;
|
||||
memoryRegionCount++;
|
||||
}
|
||||
memoryRegions[memoryRegionCount].base = 0;
|
||||
break;
|
||||
}
|
||||
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: {
|
||||
struct multiboot_tag_framebuffer *fb = (struct multiboot_tag_framebuffer *) tag;
|
||||
kernel_params.graphics_info.heightPixels = fb->common.framebuffer_height;
|
||||
kernel_params.graphics_info.widthPixels = fb->common.framebuffer_width;
|
||||
kernel_params.graphics_info.bytesPerScanlineLinear = fb->common.framebuffer_pitch;
|
||||
kernel_params.graphics_info.bufferPhysical = fb->common.framebuffer_addr;
|
||||
kernel_params.graphics_info.bitsPerPixel = fb->common.framebuffer_bpp;
|
||||
kernel_params.graphics_info.valid = 1;
|
||||
kernel_params.graphics_info.edidValid = 0;
|
||||
break;
|
||||
}
|
||||
case MULTIBOOT_TAG_TYPE_CMDLINE: {
|
||||
struct multiboot_tag_string *cmdline = (struct multiboot_tag_string *) tag;
|
||||
for (const char *ptr = cmdline->string; *ptr;) {
|
||||
if (ptr[0] == 'i' && ptr[1] == 'i' && ptr[2] == 'd' && ptr[3] == '=')
|
||||
iid_string = ptr + 4;
|
||||
while (*ptr && *ptr != ' ' && *ptr != '\t')
|
||||
ptr++;
|
||||
while (*ptr && (*ptr == ' ' || *ptr == '\t'))
|
||||
ptr++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_acpi) {
|
||||
CopyMemory (&kernel_params.rsdp_copy, new_acpi->rsdp, new_acpi->size - sizeof(struct multiboot_tag));
|
||||
kernel_params.rsdp_address = (uintptr_t) &kernel_params.rsdp_copy;
|
||||
} else if (old_acpi) {
|
||||
CopyMemory (&kernel_params.rsdp_copy, old_acpi->rsdp, old_acpi->size - sizeof(struct multiboot_tag));
|
||||
kernel_params.rsdp_address = (uintptr_t) &kernel_params.rsdp_copy;
|
||||
}
|
||||
|
||||
if (iid_string) {
|
||||
int j = 0;
|
||||
for (const char *ptr = iid_string; *ptr && *ptr != ' ' && *ptr != '\t' && j < 16; ) {
|
||||
while (*ptr == '-')
|
||||
ptr++;
|
||||
if (ptr[0] == '\0' || ptr[0] == ' ' || ptr[0] == '\t' ||
|
||||
ptr[1] == '\0' || ptr[1] == ' ' || ptr[1] == '\t')
|
||||
break;
|
||||
kernel_params.iid[j++] = (hex2val(ptr[0]) << 4) | hex2val(ptr[1]);
|
||||
ptr += 2;
|
||||
}
|
||||
} else if (iid_module) {
|
||||
CopyMemory (kernel_params.iid, (void *) iid_module->mod_start, sizeof(kernel_params.iid));
|
||||
}
|
||||
|
||||
// Identity map the first 3MB for the loader.
|
||||
{
|
||||
uint64_t *paging = paging_table;
|
||||
uint64_t base = (uintptr_t)paging;
|
||||
ZeroMemory(paging, 0x5000);
|
||||
|
||||
paging[0x1FE] = base | 3; // Recursive
|
||||
paging[0x000] = (base + 0x1000) | 3; // L4
|
||||
paging[0x200] = (base + 0x2000) | 3; // L3
|
||||
paging[0x400] = (base + 0x3000) | 3; // L2
|
||||
paging[0x401] = (base + 0x4000) | 3;
|
||||
|
||||
for (uintptr_t i = 0; i < 0x400; i++) {
|
||||
paging[0x600 + i] = (i * 0x1000) | 3; // L1
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate and map memory for the kernel.
|
||||
{
|
||||
uint64_t nextPageTable = (uintptr_t) &kernel_paging_table;
|
||||
uint32_t kernelBuffer = kernel_module->mod_start;
|
||||
uint32_t kernelBufferEnd = kernel_module->mod_end;
|
||||
|
||||
header = (ElfHeader *) kernelBuffer;
|
||||
kernel_start = header->entry;
|
||||
ElfProgramHeader *programHeaders = (ElfProgramHeader *) (kernelBuffer + header->programHeaderTable);
|
||||
uintptr_t programHeaderEntrySize = header->programHeaderEntrySize;
|
||||
|
||||
for (uintptr_t i = 0; i < header->programHeaderEntries; i++) {
|
||||
ElfProgramHeader *header = (ElfProgramHeader *) ((uint8_t *) programHeaders + programHeaderEntrySize * i);
|
||||
if (header->type != 1) continue;
|
||||
|
||||
uintptr_t pagesToAllocate = (header->segmentSize + 0xfff) >> 12;
|
||||
uintptr_t physicalAddress = 0;
|
||||
|
||||
for (uintptr_t j = 0; j < MAX_MEMORY_REGIONS; j++) {
|
||||
MemoryRegion *region = memoryRegions + j;
|
||||
if (!region->base) break;
|
||||
if (region->pages < pagesToAllocate) continue;
|
||||
// Prevent intersections with kernel buffer
|
||||
if (region->base <= kernelBufferEnd && region->base + (pagesToAllocate << 12) > kernelBuffer) {
|
||||
uint64_t new_base = (kernelBufferEnd + 0xfff) & ~0xfffULL;
|
||||
uint64_t new_pages = region->pages - (new_base - region->base);
|
||||
if (new_pages < pagesToAllocate) continue;
|
||||
// Sacrifice at most size of kernel buffer
|
||||
region->base = new_base;
|
||||
region->pages = new_pages;
|
||||
}
|
||||
physicalAddress = region->base;
|
||||
region->pages -= pagesToAllocate;
|
||||
region->base += pagesToAllocate << 12;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!physicalAddress) {
|
||||
// TODO Error handling.
|
||||
*((uint32_t *) kernel_params.graphics_info.bufferPhysical + 3) = 0xFFFF00FF;
|
||||
while (1);
|
||||
}
|
||||
|
||||
ZeroMemory((void *) physicalAddress, header->segmentSize);
|
||||
CopyMemory((void *) physicalAddress, (void *) (kernelBuffer + header->fileOffset), header->dataInFile);
|
||||
|
||||
for (uintptr_t j = 0; j < pagesToAllocate; j++, physicalAddress += 0x1000) {
|
||||
uint64_t virtualAddress = header->virtualAddress + j * K_PAGE_SIZE;
|
||||
physicalAddress &= 0xFFFFFFFFFFFFF000;
|
||||
virtualAddress &= 0x0000FFFFFFFFF000;
|
||||
|
||||
uintptr_t indexL4 = (virtualAddress >> (K_PAGE_BITS + ENTRIES_PER_PAGE_TABLE_BITS * 3)) & (ENTRIES_PER_PAGE_TABLE - 1);
|
||||
uintptr_t indexL3 = (virtualAddress >> (K_PAGE_BITS + ENTRIES_PER_PAGE_TABLE_BITS * 2)) & (ENTRIES_PER_PAGE_TABLE - 1);
|
||||
uintptr_t indexL2 = (virtualAddress >> (K_PAGE_BITS + ENTRIES_PER_PAGE_TABLE_BITS * 1)) & (ENTRIES_PER_PAGE_TABLE - 1);
|
||||
uintptr_t indexL1 = (virtualAddress >> (K_PAGE_BITS + ENTRIES_PER_PAGE_TABLE_BITS * 0)) & (ENTRIES_PER_PAGE_TABLE - 1);
|
||||
|
||||
uint64_t *tableL4 = paging_table;
|
||||
|
||||
if (!(tableL4[indexL4] & 1)) {
|
||||
tableL4[indexL4] = nextPageTable | 7;
|
||||
ZeroMemory((void *) nextPageTable, K_PAGE_SIZE);
|
||||
nextPageTable += K_PAGE_SIZE;
|
||||
}
|
||||
|
||||
uint64_t *tableL3 = (uint64_t *) (tableL4[indexL4] & ~(K_PAGE_SIZE - 1));
|
||||
|
||||
if (!(tableL3[indexL3] & 1)) {
|
||||
tableL3[indexL3] = nextPageTable | 7;
|
||||
ZeroMemory((void *) nextPageTable, K_PAGE_SIZE);
|
||||
nextPageTable += K_PAGE_SIZE;
|
||||
}
|
||||
|
||||
uint64_t *tableL2 = (uint64_t *) (tableL3[indexL3] & ~(K_PAGE_SIZE - 1));
|
||||
|
||||
if (!(tableL2[indexL2] & 1)) {
|
||||
tableL2[indexL2] = nextPageTable | 7;
|
||||
ZeroMemory((void *) nextPageTable, K_PAGE_SIZE);
|
||||
nextPageTable += K_PAGE_SIZE;
|
||||
}
|
||||
|
||||
uint64_t *tableL1 = (uint64_t *) (tableL2[indexL2] & ~(K_PAGE_SIZE - 1));
|
||||
uintptr_t value = physicalAddress | 3;
|
||||
tableL1[indexL1] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Back to asm.
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/* Linker script to create multiboo2 loader. */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x106000;
|
||||
|
||||
.kernel_params (NOLOAD) : { *(.kernel_params) }
|
||||
|
||||
. = 0x140000;
|
||||
|
||||
.paging_table (NOLOAD) : { *(.paging_table) }
|
||||
|
||||
. = 0x160000;
|
||||
|
||||
.memory_map (NOLOAD) : { *(.memory_map) }
|
||||
|
||||
. = 0x180000;
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.rdata)
|
||||
*(.pdata)
|
||||
}
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
.edata :
|
||||
{
|
||||
*(.edata)
|
||||
}
|
||||
.stab :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
.stabstr :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
|
||||
. = 0x1c0000;
|
||||
|
||||
.kernel_paging_table (NOLOAD) : { *(.kernel_paging_table) }
|
||||
|
||||
. = 0x1f0000;
|
||||
|
||||
.stack (NOLOAD) : { *(.stack) }
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.dynamic)
|
||||
*(.comment)
|
||||
*(.note.gnu.build-id)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
// This file is part of the Essence operating system.
|
||||
// It is released under the terms of the MIT license -- see LICENSE.md.
|
||||
// Written by: phcoder.
|
||||
|
||||
#define ASM_FILE
|
||||
#include "multiboot2.h"
|
||||
.text
|
||||
.code32
|
||||
|
||||
#define REL32(x) ((x) - _start + 0x180000)
|
||||
|
||||
.globl _start
|
||||
.globl stack
|
||||
_start:
|
||||
// Change GDT
|
||||
lgdt REL32(.gdt)
|
||||
ljmpl $0x8, $REL32(.start_32_bit_mode)
|
||||
|
||||
.start_32_bit_mode:
|
||||
|
||||
mov $0x10, %eax
|
||||
mov %eax, %ds
|
||||
mov %eax, %es
|
||||
mov %eax, %ss
|
||||
|
||||
mov $REL32(stack + 0x10000 - 8), %esp
|
||||
push %ebx
|
||||
call mb2_main
|
||||
|
||||
mov %cr4, %eax
|
||||
or $0x30, %eax
|
||||
mov %eax, %cr4
|
||||
|
||||
mov $0x140000, %eax
|
||||
mov %eax, %cr3
|
||||
|
||||
// Enable long mode
|
||||
mov $0xC0000080, %ecx
|
||||
rdmsr
|
||||
or $0x100, %eax
|
||||
wrmsr
|
||||
mov %cr0, %eax
|
||||
or $0x80000000, %eax
|
||||
mov %eax, %cr0
|
||||
|
||||
lgdt REL32(.gdt)
|
||||
|
||||
// Go to 64-bit mode
|
||||
ljmpl $0x48, $REL32(.start_64_bit_mode)
|
||||
|
||||
.code64
|
||||
|
||||
.align 16
|
||||
|
||||
.start_64_bit_mode:
|
||||
|
||||
mov $0x50, %rax
|
||||
mov %rax, %ds
|
||||
mov %rax, %es
|
||||
mov %rax, %ss
|
||||
|
||||
// Get the start address of the kernel
|
||||
mov kernel_start(%rip), %rcx
|
||||
|
||||
// Map the first MB at 0xFFFFFE0000000000 --> 0xFFFFFE0000100000
|
||||
mov $0xFFFFFF7FBFDFE000, %rdi
|
||||
mov (%rdi), %rax
|
||||
mov $0xFFFFFF7FBFDFEFE0, %rdi
|
||||
mov %rax, (%rdi)
|
||||
mov %cr3, %rax
|
||||
mov %rax, %cr3
|
||||
|
||||
// Use the new linear address of the GDT
|
||||
mov $0xFFFFFE0000000000, %rax
|
||||
add %rax, .gdt2(%rip)
|
||||
lgdt .gdt(%rip)
|
||||
|
||||
call .set_cs
|
||||
|
||||
// Execute the kernel's _start function
|
||||
mov $0x100000, %rdi
|
||||
mov $2, %rsi
|
||||
jmp *%rcx
|
||||
|
||||
.set_cs:
|
||||
pop %rax
|
||||
push $0x48
|
||||
push %rax
|
||||
.byte 0x48, 0xCB
|
||||
|
||||
.align MULTIBOOT_HEADER_ALIGN
|
||||
|
||||
.multiboot2_header:
|
||||
.long MULTIBOOT2_HEADER_MAGIC
|
||||
.long MULTIBOOT2_ARCHITECTURE_I386
|
||||
.long .multiboot2_header_end - .multiboot2_header
|
||||
.long -(.multiboot2_header_end - .multiboot2_header + MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386)
|
||||
|
||||
.word MULTIBOOT_HEADER_TAG_FRAMEBUFFER
|
||||
.word 0
|
||||
.long 20
|
||||
.long 0 // width: any
|
||||
.long 0 // height: any
|
||||
.long 0 // depth: any
|
||||
|
||||
.long 0 // padding
|
||||
|
||||
.word MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST
|
||||
.word 0
|
||||
.long 20
|
||||
.long MULTIBOOT_TAG_TYPE_ACPI_NEW
|
||||
.long MULTIBOOT_TAG_TYPE_FRAMEBUFFER
|
||||
.long MULTIBOOT_TAG_TYPE_MODULE
|
||||
|
||||
.long 0 // padding
|
||||
|
||||
.word MULTIBOOT_HEADER_TAG_MODULE_ALIGN
|
||||
.word 0
|
||||
.long 8
|
||||
|
||||
.word MULTIBOOT_HEADER_TAG_END
|
||||
.word 0
|
||||
.long 8
|
||||
.multiboot2_header_end:
|
||||
|
||||
.align 16
|
||||
.gdt_data:
|
||||
.null_entry: .quad 0
|
||||
.code_entry: .long 0xFFFF // 0x08
|
||||
.byte 0
|
||||
.word 0xCF9A
|
||||
.byte 0
|
||||
.data_entry: .long 0xFFFF // 0x10
|
||||
.byte 0
|
||||
.word 0xCF92
|
||||
.byte 0
|
||||
.code_entry_16: .long 0xFFFF // 0x18
|
||||
.byte 0
|
||||
.word 0x0F9A
|
||||
.byte 0
|
||||
.data_entry_16: .long 0xFFFF // 0x20
|
||||
.byte 0
|
||||
.word 0x0F92
|
||||
.byte 0
|
||||
.user_code: .long 0xFFFF // 0x28
|
||||
.byte 0
|
||||
.word 0xCFFA
|
||||
.byte 0
|
||||
.user_data: .long 0xFFFF // 0x30
|
||||
.byte 0
|
||||
.word 0xCFF2
|
||||
.byte 0
|
||||
.tss: .long 0x68 // 0x38
|
||||
.byte 0
|
||||
.word 0xE9
|
||||
.byte 0
|
||||
.quad 0
|
||||
.code_entry64: .long 0xFFFF // 0x48
|
||||
.byte 0
|
||||
.word 0xAF9A
|
||||
.byte 0
|
||||
.data_entry64: .long 0xFFFF // 0x50
|
||||
.byte 0
|
||||
.word 0xAF92
|
||||
.byte 0
|
||||
.user_code64: .long 0xFFFF // 0x58
|
||||
.byte 0
|
||||
.word 0xAFFA
|
||||
.byte 0
|
||||
.user_data64: .long 0xFFFF // 0x60
|
||||
.byte 0
|
||||
.word 0xAFF2
|
||||
.byte 0
|
||||
.user_code64c: .long 0xFFFF // 0x68
|
||||
.byte 0
|
||||
.word 0xAFFA
|
||||
.byte 0
|
||||
.gdt: .word (.gdt - .gdt_data - 1)
|
||||
.gdt2: .quad REL32(.gdt_data)
|
|
@ -0,0 +1,416 @@
|
|||
/* multiboot2.h - Multiboot 2 header file. */
|
||||
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
|
||||
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MULTIBOOT_HEADER
|
||||
#define MULTIBOOT_HEADER 1
|
||||
|
||||
/* How many bytes from the start of the file we search for the header. */
|
||||
#define MULTIBOOT_SEARCH 32768
|
||||
#define MULTIBOOT_HEADER_ALIGN 8
|
||||
|
||||
/* The magic field should contain this. */
|
||||
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
|
||||
|
||||
/* This should be in %eax. */
|
||||
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
|
||||
|
||||
/* Alignment of multiboot modules. */
|
||||
#define MULTIBOOT_MOD_ALIGN 0x00001000
|
||||
|
||||
/* Alignment of the multiboot info structure. */
|
||||
#define MULTIBOOT_INFO_ALIGN 0x00000008
|
||||
|
||||
/* Flags set in the 'flags' member of the multiboot header. */
|
||||
|
||||
#define MULTIBOOT_TAG_ALIGN 8
|
||||
#define MULTIBOOT_TAG_TYPE_END 0
|
||||
#define MULTIBOOT_TAG_TYPE_CMDLINE 1
|
||||
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
|
||||
#define MULTIBOOT_TAG_TYPE_MODULE 3
|
||||
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
|
||||
#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
|
||||
#define MULTIBOOT_TAG_TYPE_MMAP 6
|
||||
#define MULTIBOOT_TAG_TYPE_VBE 7
|
||||
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
|
||||
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
|
||||
#define MULTIBOOT_TAG_TYPE_APM 10
|
||||
#define MULTIBOOT_TAG_TYPE_EFI32 11
|
||||
#define MULTIBOOT_TAG_TYPE_EFI64 12
|
||||
#define MULTIBOOT_TAG_TYPE_SMBIOS 13
|
||||
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
|
||||
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
|
||||
#define MULTIBOOT_TAG_TYPE_NETWORK 16
|
||||
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
|
||||
#define MULTIBOOT_TAG_TYPE_EFI_BS 18
|
||||
#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
|
||||
#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
|
||||
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
|
||||
|
||||
#define MULTIBOOT_HEADER_TAG_END 0
|
||||
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
|
||||
#define MULTIBOOT_HEADER_TAG_ADDRESS 2
|
||||
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
|
||||
#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
|
||||
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
|
||||
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
|
||||
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
|
||||
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
|
||||
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
|
||||
|
||||
#define MULTIBOOT2_ARCHITECTURE_I386 0
|
||||
#define MULTIBOOT2_ARCHITECTURE_MIPS32 4
|
||||
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
|
||||
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
|
||||
|
||||
#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
|
||||
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
typedef unsigned char multiboot_uint8_t;
|
||||
typedef unsigned short multiboot_uint16_t;
|
||||
typedef unsigned int multiboot_uint32_t;
|
||||
typedef unsigned long long multiboot_uint64_t;
|
||||
|
||||
struct multiboot_header
|
||||
{
|
||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||
multiboot_uint32_t magic;
|
||||
|
||||
/* ISA */
|
||||
multiboot_uint32_t architecture;
|
||||
|
||||
/* Total header length. */
|
||||
multiboot_uint32_t header_length;
|
||||
|
||||
/* The above fields plus this one must equal 0 mod 2^32. */
|
||||
multiboot_uint32_t checksum;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_information_request
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t requests[0];
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_address
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t header_addr;
|
||||
multiboot_uint32_t load_addr;
|
||||
multiboot_uint32_t load_end_addr;
|
||||
multiboot_uint32_t bss_end_addr;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_entry_address
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t entry_addr;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_console_flags
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t console_flags;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_framebuffer
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t width;
|
||||
multiboot_uint32_t height;
|
||||
multiboot_uint32_t depth;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_module_align
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_relocatable
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t min_addr;
|
||||
multiboot_uint32_t max_addr;
|
||||
multiboot_uint32_t align;
|
||||
multiboot_uint32_t preference;
|
||||
};
|
||||
|
||||
struct multiboot_color
|
||||
{
|
||||
multiboot_uint8_t red;
|
||||
multiboot_uint8_t green;
|
||||
multiboot_uint8_t blue;
|
||||
};
|
||||
|
||||
struct multiboot_mmap_entry
|
||||
{
|
||||
multiboot_uint64_t addr;
|
||||
multiboot_uint64_t len;
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||
#define MULTIBOOT_MEMORY_NVS 4
|
||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t zero;
|
||||
};
|
||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||
|
||||
struct multiboot_tag
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_tag_string
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
char string[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_module
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t mod_start;
|
||||
multiboot_uint32_t mod_end;
|
||||
char cmdline[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_basic_meminfo
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t mem_lower;
|
||||
multiboot_uint32_t mem_upper;
|
||||
};
|
||||
|
||||
struct multiboot_tag_bootdev
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t biosdev;
|
||||
multiboot_uint32_t slice;
|
||||
multiboot_uint32_t part;
|
||||
};
|
||||
|
||||
struct multiboot_tag_mmap
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t entry_size;
|
||||
multiboot_uint32_t entry_version;
|
||||
struct multiboot_mmap_entry entries[0];
|
||||
};
|
||||
|
||||
struct multiboot_vbe_info_block
|
||||
{
|
||||
multiboot_uint8_t external_specification[512];
|
||||
};
|
||||
|
||||
struct multiboot_vbe_mode_info_block
|
||||
{
|
||||
multiboot_uint8_t external_specification[256];
|
||||
};
|
||||
|
||||
struct multiboot_tag_vbe
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
|
||||
multiboot_uint16_t vbe_mode;
|
||||
multiboot_uint16_t vbe_interface_seg;
|
||||
multiboot_uint16_t vbe_interface_off;
|
||||
multiboot_uint16_t vbe_interface_len;
|
||||
|
||||
struct multiboot_vbe_info_block vbe_control_info;
|
||||
struct multiboot_vbe_mode_info_block vbe_mode_info;
|
||||
};
|
||||
|
||||
struct multiboot_tag_framebuffer_common
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
|
||||
multiboot_uint64_t framebuffer_addr;
|
||||
multiboot_uint32_t framebuffer_pitch;
|
||||
multiboot_uint32_t framebuffer_width;
|
||||
multiboot_uint32_t framebuffer_height;
|
||||
multiboot_uint8_t framebuffer_bpp;
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||
multiboot_uint8_t framebuffer_type;
|
||||
multiboot_uint16_t reserved;
|
||||
};
|
||||
|
||||
struct multiboot_tag_framebuffer
|
||||
{
|
||||
struct multiboot_tag_framebuffer_common common;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
multiboot_uint16_t framebuffer_palette_num_colors;
|
||||
struct multiboot_color framebuffer_palette[0];
|
||||
};
|
||||
struct
|
||||
{
|
||||
multiboot_uint8_t framebuffer_red_field_position;
|
||||
multiboot_uint8_t framebuffer_red_mask_size;
|
||||
multiboot_uint8_t framebuffer_green_field_position;
|
||||
multiboot_uint8_t framebuffer_green_mask_size;
|
||||
multiboot_uint8_t framebuffer_blue_field_position;
|
||||
multiboot_uint8_t framebuffer_blue_mask_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct multiboot_tag_elf_sections
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t num;
|
||||
multiboot_uint32_t entsize;
|
||||
multiboot_uint32_t shndx;
|
||||
char sections[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_apm
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint16_t version;
|
||||
multiboot_uint16_t cseg;
|
||||
multiboot_uint32_t offset;
|
||||
multiboot_uint16_t cseg_16;
|
||||
multiboot_uint16_t dseg;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint16_t cseg_len;
|
||||
multiboot_uint16_t cseg_16_len;
|
||||
multiboot_uint16_t dseg_len;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi32
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi64
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_smbios
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t major;
|
||||
multiboot_uint8_t minor;
|
||||
multiboot_uint8_t reserved[6];
|
||||
multiboot_uint8_t tables[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_old_acpi
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t rsdp[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_new_acpi
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t rsdp[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_network
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t dhcpack[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi_mmap
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t descr_size;
|
||||
multiboot_uint32_t descr_vers;
|
||||
multiboot_uint8_t efi_mmap[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi32_ih
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi64_ih
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_load_base_addr
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t load_base_addr;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
|
@ -171,11 +171,13 @@ char commonCompileFlagsWithCStdLib[4096];
|
|||
char cCompileFlags[4096] = "";
|
||||
char cppCompileFlags[4096] = " -std=c++14 -Wno-pmf-conversions -Wno-invalid-offsetof -fno-rtti ";
|
||||
char kernelCompileFlags[4096] = " -fno-omit-frame-pointer ";
|
||||
char multiboot2LoaderCompileFlags[4096] = " -m32 -fno-common -g -mno-mmx -mno-sse -mno-sse2 -mno-ssse3 -mno-sse4 ";
|
||||
char applicationLinkFlags[4096] = " -ffreestanding -nostdlib -lgcc -g -z max-page-size=0x1000 ";
|
||||
char apiLinkFlags1[4096] = " -T util/linker/api64.ld -ffreestanding -nostdlib -g -z max-page-size=0x1000 -Wl,--start-group "; // TODO Don't hardcode the target.
|
||||
char apiLinkFlags2[4096] = " -lgcc ";
|
||||
char apiLinkFlags3[4096] = " -Wl,--end-group -Lroot/Applications/POSIX/lib ";
|
||||
char kernelLinkFlags[4096] = " -ffreestanding -nostdlib -lgcc -g -z max-page-size=0x1000 ";
|
||||
char multiboot2LoaderLinkFlags[4096] = " -nostdlib -melf_i386 --no-dynamic-linker -Tboot/x86/mb2_link.sc -g ";
|
||||
char commonAssemblyFlags[4096] = " -Fdwarf ";
|
||||
const char *desktopProfilingFlags = "";
|
||||
|
||||
|
@ -1096,6 +1098,15 @@ void ParseKernelConfiguration() {
|
|||
DeleteFile("bin/dependency_files/system_config.d");
|
||||
}
|
||||
|
||||
void LinkMultiboot2Loader() {
|
||||
if (Execute(toolchainLD, "bin/Object Files/mb2_loader.o", "bin/Object Files/mb2.o", ArgString(multiboot2LoaderLinkFlags), "-o" "bin/Multiboot2Loader")) {
|
||||
return;
|
||||
}
|
||||
|
||||
Execute(toolchainStrip, "-o", "bin/Stripped Executables/Multiboot2Loader", "--strip-all", "bin/Multiboot2Loader");
|
||||
CopyFile("bin/Stripped Executables/Multiboot2Loader", "root/" SYSTEM_FOLDER_NAME "/Multiboot2Loader.elf", false);
|
||||
}
|
||||
|
||||
void LinkKernel() {
|
||||
if (encounteredErrorsInKernelModules) {
|
||||
return;
|
||||
|
@ -1157,6 +1168,13 @@ void BuildKernel(Application *application) {
|
|||
if (application->error) __sync_fetch_and_or(&encounteredErrorsInKernelModules, 1);
|
||||
}
|
||||
|
||||
void BuildMultiboot2Loader(Application *application) {
|
||||
ExecuteForApp(application, toolchainCXX, "-MD", "-MF", "bin/dependency_files/mb2.d", "-c", "boot/x86/mb2.c", "-o", "bin/Object Files/mb2.o",
|
||||
ArgString(multiboot2LoaderCompileFlags), ArgString(cppCompileFlags), ArgString(commonCompileFlags), buffer);
|
||||
ExecuteForApp(application, toolchainCXX, "-MD", "-MF", "bin/dependency_files/mb2.d", "-c", "boot/x86/mb2_loader.S", "-o", "bin/Object Files/mb2_loader.o",
|
||||
ArgString(multiboot2LoaderCompileFlags), ArgString(cppCompileFlags), ArgString(commonCompileFlags), buffer);
|
||||
}
|
||||
|
||||
void BuildBootloader(Application *application) {
|
||||
ExecuteForApp(application, toolchainNasm, "-MD", "bin/dependency_files/boot1.d", "-fbin",
|
||||
forEmulator ? "boot/x86/mbr.s" : "boot/x86/mbr-emu.s" , "-obin/mbr");
|
||||
|
@ -1620,6 +1638,15 @@ int main(int argc, char **argv) {
|
|||
arrput(applications, application);
|
||||
}
|
||||
|
||||
if (systemBuild) {
|
||||
Application application = {};
|
||||
application.name = "Multiboot2Loader";
|
||||
application.buildCallback = BuildMultiboot2Loader;
|
||||
ADD_DEPENDENCY_FILE(application, "bin/dependency_files/mb2.d", "Multiboot2Loader1");
|
||||
ADD_DEPENDENCY_FILE(application, "bin/dependency_files/mb2_loader.d", "Multiboot2Loader2");
|
||||
arrput(applications, application);
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < arrlenu(applicationManifests); i++) {
|
||||
ParseApplicationManifest(applicationManifests[i]);
|
||||
}
|
||||
|
@ -1746,6 +1773,8 @@ int main(int argc, char **argv) {
|
|||
LinkKernel();
|
||||
}
|
||||
|
||||
LinkMultiboot2Loader();
|
||||
|
||||
OutputSystemConfiguration();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue