os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

commit a778d9116e59ca832d2d6d3b8bef32ee651e2513
parent f4a0d8c56a8575971c7ef12fa790c497f770495b
Author: erai <erai@omiltem.net>
Date:   Mon, 25 Mar 2024 13:35:58 -0400

add multiboot header

Diffstat:
Mas.c | 97++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mcc0.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Mcc1.c | 15++++++++++++---
3 files changed, 170 insertions(+), 20 deletions(-)

diff --git a/as.c b/as.c @@ -39,16 +39,24 @@ enum { enum { OP_NOP = 0x90, + OP_RET = 0xc3, OP_CALL = 0xe8, OP_JMP = 0xe9, OP_JCC = 0x0f80, OP_SETCC = 0x0f90, - OP_ICALLM = 0x02ff, + OP_PUSHF = 0x9c, + OP_IRET = 0xcf, + OP_IRETQ = 0x48cf, + OP_WRMSR = 0x0f30, + OP_WRCRM = 0x0f20, + OP_LGDTM = 0x020f01, + + OP_ICALLM = 0x0200ff, - OP_NOTM = 0x02f7, - OP_NEGM = 0x03f7, + OP_NOTM = 0x0200f7, + OP_NEGM = 0x0300f7, OP_ANDRM = 0x23, OP_ORRM = 0x0b, @@ -60,10 +68,10 @@ enum { OP_ADDI = 0x0081, - OP_IMULM = 0x04f7, - OP_IDIVM = 0x07f7, - OP_SHLM = 0x04d3, - OP_SHRM = 0x05d3, + OP_IMULM = 0x0400f7, + OP_IDIVM = 0x0700f7, + OP_SHLM = 0x0400d3, + OP_SHRM = 0x0500d3, OP_PUSHR = 0x50, @@ -536,12 +544,18 @@ emit_syscall(c: *assembler) { as_opr(c, OP_PUSHR, R_RAX); } -writeout(c: *assembler, start: *label) { +writeout(c: *assembler, start: *label, kstart: *label) { var b: *chunk; var i: int; var text_size: int; + var text_end: int; var load_addr: int; var entry: int; + var kentry: int; + var mb_magic: int; + var mb_flags: int; + var mb_checksum: int; + var mb_addr: int; if (!c.out) { open_output(c, "a.out"); @@ -554,8 +568,21 @@ writeout(c: *assembler, start: *label) { die("_start is not defined"); } - entry = load_addr + start.at + 128; - text_size = text_size + 128; + entry = load_addr + start.at + 128 + 32; + text_size = text_size + 128 + 32; + text_end = load_addr + text_size; + + mb_magic = 0x1badb002; + mb_flags = 0x00010003; + mb_checksum = -(mb_magic + mb_flags); + mb_addr = load_addr + 120; + + if (kstart && kstart.fixed) { + kentry = load_addr + kstart.at + 128 + 32; + } else { + mb_magic = 0; + kentry = 0; + } // magic putchar(c, 0x7f); @@ -733,6 +760,54 @@ writeout(c: *assembler, start: *label) { putchar(c, 0); putchar(c, 0); + // multiboot magic + putchar(c, mb_magic); + putchar(c, mb_magic >> 8); + putchar(c, mb_magic >> 16); + putchar(c, mb_magic >> 24); + + // multiboot flags + putchar(c, mb_flags); + putchar(c, mb_flags >> 8); + putchar(c, mb_flags >> 16); + putchar(c, mb_flags >> 24); + + // multboot checksum + putchar(c, mb_checksum); + putchar(c, mb_checksum >> 8); + putchar(c, mb_checksum >> 16); + putchar(c, mb_checksum >> 24); + + // multiboot header_addr + putchar(c, mb_addr); + putchar(c, mb_addr >> 8); + putchar(c, mb_addr >> 16); + putchar(c, mb_addr >> 24); + + // multiboot load_addr + putchar(c, load_addr); + putchar(c, load_addr >> 8); + putchar(c, load_addr >> 16); + putchar(c, load_addr >> 24); + + // multiboot load_end_addr + putchar(c, text_end); + putchar(c, text_end >> 8); + putchar(c, text_end >> 16); + putchar(c, text_end >> 24); + + // multiboot bss_end_addr + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + + // entry_addr + putchar(c, kentry); + putchar(c, kentry >> 8); + putchar(c, kentry >> 16); + putchar(c, kentry >> 24); + // nop sled putchar(c, OP_NOP); putchar(c, OP_NOP); @@ -822,7 +897,7 @@ as_modrr(a: *assembler, op: int, r: int, b: int) { // modrm /op as_modr(a: *assembler, op: int, b: int) { - as_modrr(a, op & 0xff, op >> 8, b); + as_modrr(a, op & 0xffff, op >> 16, b); } // modrm + sib + disp diff --git a/cc0.c b/cc0.c @@ -4137,14 +4137,36 @@ writeout(void) int entry; struct decl *d; struct buf *b; - - load_addr = 0x100000; + int kentry; + int magic; + int flags; + int checksum; + int addr; + int end; d = find((unsigned char *)"_start"); if (!d->defined || !d->label->fixed) { die("no _start function"); } + load_addr = 0x100000; + entry = load_addr + d->label->at + 128 + 32; + at = at + 128 + 32; + end = load_addr + at; + + magic = 0x1badb002; + flags = 0x00010003; + checksum = -(magic + flags); + addr = load_addr + 120; + + d = find((unsigned char *)"_kstart"); + if (d->defined && d->label->fixed) { + kentry = load_addr + d->label->at +128 + 32; + } else { + magic = 0; + kentry = 0; + } + // magic fputc(0x7f, fout); fputc('E', fout); @@ -4189,8 +4211,6 @@ writeout(void) fputc(0, fout); fputc(0, fout); - entry = load_addr + d->label->at + 128; - // entry point fputc(entry, fout); fputc(entry >> 8, fout); @@ -4293,8 +4313,6 @@ writeout(void) fputc(0, fout); fputc(0, fout); - at = at + 128; - // phdr[0].filesize fputc(at, fout); fputc(at >> 8, fout); @@ -4325,6 +4343,54 @@ writeout(void) fputc(0, fout); fputc(0, fout); + // mb.magic + fputc(magic, fout); + fputc(magic >> 8, fout); + fputc(magic >> 16, fout); + fputc(magic >> 24, fout); + + // mb.flags + fputc(flags, fout); + fputc(flags >> 8, fout); + fputc(flags >> 16, fout); + fputc(flags >> 24, fout); + + // mb.checksum + fputc(checksum, fout); + fputc(checksum >> 8, fout); + fputc(checksum >> 16, fout); + fputc(checksum >> 24, fout); + + // mb.header + fputc(addr, fout); + fputc(addr >> 8, fout); + fputc(addr >> 16, fout); + fputc(addr >> 24, fout); + + // mb.load + fputc(load_addr, fout); + fputc(load_addr >> 8, fout); + fputc(load_addr >> 16, fout); + fputc(load_addr >> 24, fout); + + // mb.load_end + fputc(end, fout); + fputc(end >> 8, fout); + fputc(end >> 16, fout); + fputc(end >> 24, fout); + + // mb.bss_end + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + + // mb.entry + fputc(kentry, fout); + fputc(kentry >> 8, fout); + fputc(kentry >> 16, fout); + fputc(kentry >> 24, fout); + // nop sled fputc(0x90, fout); fputc(0x90, fout); diff --git a/cc1.c b/cc1.c @@ -1274,6 +1274,8 @@ main(argc: int, argv: **byte, envp: **byte) { var c: *compiler; var p: *node; var d: *decl; + var start: *label; + var kstart: *label; var i: int; setup_alloc(&a); @@ -1327,10 +1329,17 @@ main(argc: int, argv: **byte, envp: **byte) { emit_ret(c.as); } + start = 0: *label; d = find(c, "_start", 0:*byte, 0); - if (!d || !d.func_defined) { - die("no _start"); + if (d && d.func_defined) { + start = d.func_label; } - writeout(c.as, d.func_label); + kstart = 0: *label; + d = find(c, "_kstart", 0:*byte, 0); + if (d && d.func_defined) { + kstart = d.func_label; + } + + writeout(c.as, start, kstart); }