summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--stage1/main.asm5
-rw-r--r--stage2/elf.asm9
-rw-r--r--stage2/main.asm27
-rw-r--r--stage2/mmap.asm24
-rw-r--r--stage2/vesa.asm47
-rw-r--r--stage3/bootinfo.h32
-rw-r--r--stage3/cheese3d.c4
-rw-r--r--stage3/font.c15
-rw-r--r--stage3/fs.c3
-rw-r--r--stage3/gfx.c15
-rw-r--r--stage3/gfx.h7
-rw-r--r--stage3/init.c8
-rw-r--r--stage3/main.c75
-rw-r--r--stage3/shell.c3
14 files changed, 158 insertions, 116 deletions
diff --git a/stage1/main.asm b/stage1/main.asm
index fcf7ed3..2f8c60c 100644
--- a/stage1/main.asm
+++ b/stage1/main.asm
@@ -19,9 +19,6 @@ boot:
mov ebx, .msg
call print_str
- ; save offset of the file system
- mov dword[0x1000-10-8], KSIZE+512
-
; print boot drive
pusha
movzx eax, dl
@@ -36,6 +33,8 @@ boot:
mov bp, KSTART
mov sp, bp
+ ; pass offset of the file system as argument
+ mov edi, KSIZE+512
; jump into stage2
jmp KSTART
diff --git a/stage2/elf.asm b/stage2/elf.asm
index 01759b3..d1d15e3 100644
--- a/stage2/elf.asm
+++ b/stage2/elf.asm
@@ -11,7 +11,7 @@ load_kernel_elf:
.header:
cmp rdx, 0
- je .start
+ je .done
mov edi, [r8] ; type
cmp edi, 0
@@ -48,14 +48,11 @@ load_kernel_elf:
dec rdx
jmp .header
-.start:
- ; more stack space
- mov rsp, 0x80000
- xor rbp, rbp
+.done:
; ELF entry point
mov rax, [kernel_elf+24]
- call rax
+ ret
.fail:
cli
diff --git a/stage2/main.asm b/stage2/main.asm
index fae8d5a..1964720 100644
--- a/stage2/main.asm
+++ b/stage2/main.asm
@@ -1,14 +1,12 @@
[org 0x7E00]
%define PAGETABLE 0x1000
-%define VESAINFO 0x0500
-%define VESAMODE VESAINFO+512
-%define OWNMODE VESAMODE+256
-%define GFXINFO PAGETABLE-10
-;%define MEMMAPCNT GFXINFO-2
+%define VESAMODES 0x500
%define MEMMAP 0x500
setup:
+ mov [bootinfo.ksize], edi
+
; print message
mov ebx, .msg
call print_str
@@ -28,6 +26,15 @@ setup:
.msg:
db 10, 13, "cuddles stage2", 10, 13, 0
+bootinfo:
+ .ksize: dq 0
+ .gfx_pitch: dw 0
+ .gfx_width: dw 0
+ .gfx_height: dw 0
+ .gfx_framebuffer: dq 0
+ .mmap_len: dq 0
+ .mmap_ptr: dq 0
+
%include "stage2/vesa.asm"
%include "stage2/mmap.asm"
%include "stage2/paging.asm"
@@ -46,6 +53,14 @@ long_mode:
mov gs, ax
mov ss, ax
- call load_kernel_elf
+ call load_kernel_elf ; returns entry point in rax
+
+ ; more stack space
+ mov rsp, 0x80000
+ xor rbp, rbp
+
+ ; pass bootinfo as arg
+ mov rdi, bootinfo
+ call rax
kernel_elf:
diff --git a/stage2/mmap.asm b/stage2/mmap.asm
index 72f188a..b719f84 100644
--- a/stage2/mmap.asm
+++ b/stage2/mmap.asm
@@ -6,6 +6,7 @@ mmap:
xor ebx, ebx ; counter for interrupt
mov di, MEMMAP
+ xor esi, esi ; number of regions
.loop:
; issue an INT 0x15, EAX = 0xE820 interrupt
@@ -17,32 +18,19 @@ mmap:
cmp eax, MAPMAGIC ; detect failure
jne .fail
- cmp dword[di+16], 1
- ; jne .next
-
- cmp dword[di+4], 0
- jne .keep
-
- cmp dword[di+0], 0x100000
- jb .next
-
-.keep:
- mov dword[di+20], 0
+ inc esi
add di, 24
-.next:
cmp ebx, 0
jne .loop
mov dword[di+0], 0
mov dword[di+4], 0
- ;mov ax, di
- ;sub ax, MEMMAP
- ;xor dx, dx
- ;mov bx, 24
- ;div bx
- ;mov [MEMMAPCNT], ax
+ mov dword[bootinfo.mmap_len+0], esi
+ mov dword[bootinfo.mmap_len+4], 0
+ mov dword[bootinfo.mmap_ptr+0], MEMMAP
+ mov dword[bootinfo.mmap_ptr+4], 0
ret
diff --git a/stage2/vesa.asm b/stage2/vesa.asm
index da7eb81..8038ba4 100644
--- a/stage2/vesa.asm
+++ b/stage2/vesa.asm
@@ -1,3 +1,6 @@
+vesainfo: times 512 db 0
+vesamode: times 256 db 0
+
vesa:
; print message
mov ebx, .msg
@@ -5,16 +8,16 @@ vesa:
; get vesa bios info
mov eax, dword[.vbe2]
- mov dword[VESAINFO], eax ; move "VBE2" to start of vesainfo struct
+ mov dword[vesainfo], eax ; move "VBE2" to start of vesainfo struct
mov ax, 0x4F00 ; get VESA BIOS information
- mov di, VESAINFO ; struct buffer
+ mov di, vesainfo ; struct buffer
int 0x10
cmp ax, 0x004F ; check ax for correct magic number
jne .fail_getinfo
mov eax, dword[.vesa]
- cmp dword[VESAINFO], eax ; check if "VESA" is at start of stuct
+ cmp dword[vesainfo], eax ; check if "VESA" is at start of struct
jne .fail_getinfo
; print select message
@@ -22,8 +25,8 @@ vesa:
call print_str
; get segment:offset pointer to video modes into gs:ebx
- movzx ebx, word[VESAINFO+14]
- mov ax, word[VESAINFO+16]
+ movzx ebx, word[vesainfo+14]
+ mov ax, word[vesainfo+16]
mov gs, ax
; convert modes to own structure
@@ -36,17 +39,17 @@ vesa:
cmp cx, 0xFFFF ; 0xFFFF is terminator, no suitable mode has been found
je .mode_done
mov ax, 0x4F01 ; get VESA mode information
- mov di, VESAMODE ; vesa mode info struct buffer
+ mov di, vesamode ; vesa mode info struct buffer
int 0x10
cmp ax, 0x004F ; check ax for correct magic number
jne .fail_modeinfo
- mov al, byte[VESAMODE] ; get attributes
+ mov al, byte[vesamode] ; get attributes
and al, 0b10000000 ; extract bit 7, indicates linear framebuffer support
jz .mode_next
- mov al, byte[VESAMODE+25] ; get bpp (bits per pixel)
+ mov al, byte[vesamode+25] ; get bpp (bits per pixel)
cmp al, 32
jne .mode_next
@@ -56,7 +59,7 @@ vesa:
mov ebx, 12
mul ebx
mov edi, eax
- add edi, OWNMODE
+ add edi, VESAMODES
mov [edi+10], cx ; copy mode
@@ -74,22 +77,22 @@ vesa:
mov al, ' '
call print_chr
- mov ax, [VESAMODE+16] ; copy pitch
+ mov ax, [vesamode+16] ; copy pitch
mov [edi+0], ax
- movzx eax, word[VESAMODE+18] ; copy width
+ movzx eax, word[vesamode+18] ; copy width
mov [edi+2], ax
call print_dec
mov al, 'x'
call print_chr
- movzx eax, word[VESAMODE+20] ; copy height
+ movzx eax, word[vesamode+20] ; copy height
mov [edi+4], ax
call print_dec
call newline
- mov eax, [VESAMODE+40] ; copy framebuffer
+ mov eax, [vesamode+40] ; copy framebuffer
mov [edi+6], eax
pop ebx
@@ -132,17 +135,21 @@ vesa:
mov eax, edi
mov ebx, 12
mul ebx
- add eax, OWNMODE
+ add eax, VESAMODES
; copy to final gfx info location
- mov ebx, [eax+0]
- mov [GFXINFO+0], ebx
+ mov bx, [eax+0]
+ mov [bootinfo.gfx_pitch], bx
+
+ mov bx, [eax+2]
+ mov [bootinfo.gfx_width], bx
- mov ebx, [eax+4]
- mov [GFXINFO+4], ebx
+ mov bx, [eax+4]
+ mov [bootinfo.gfx_height], bx
- mov bx, [eax+8]
- mov [GFXINFO+8], bx
+ mov ebx, [eax+6]
+ mov dword[bootinfo.gfx_framebuffer+0], ebx
+ mov dword[bootinfo.gfx_framebuffer+4], 0
;mov edi, eax
;mov eax, [edi+6]
diff --git a/stage3/bootinfo.h b/stage3/bootinfo.h
new file mode 100644
index 0000000..825f513
--- /dev/null
+++ b/stage3/bootinfo.h
@@ -0,0 +1,32 @@
+#ifndef BOOTINFO_H
+#define BOOTINFO_H
+
+#include "def.h"
+
+typedef enum {
+ MEM_USABLE = 1,
+ MEM_RESERVED = 2,
+ MEM_ACPI_RECLAIMABLE = 3,
+ MEM_ACPI_NVS = 4,
+ MEM_BAD = 5,
+} mem_region_type;
+
+typedef struct __attribute__((packed)) {
+ void *start;
+ usize size;
+ u32 type;
+ u32 acpi_attrs;
+} mem_region;
+
+MKVEC(mem_region)
+
+extern struct __attribute__((packed)) bootinfo {
+ u64 ksize;
+ u16 gfx_pitch;
+ u16 gfx_width;
+ u16 gfx_height;
+ void *gfx_framebuffer;
+ slice_mem_region mmap;
+} *bootinfo;
+
+#endif
diff --git a/stage3/cheese3d.c b/stage3/cheese3d.c
index 4d58a35..0c73f90 100644
--- a/stage3/cheese3d.c
+++ b/stage3/cheese3d.c
@@ -1,7 +1,7 @@
#include "heap.h"
#include "math3d.h"
#include "cheese3d.h"
-#include "gfx.h"
+#include "bootinfo.h"
#include "memory.h"
cheese3d_ctx cheese3d_create(void *target, u32 width, u32 height, u32 pitch, u32 bgcolor)
@@ -19,7 +19,7 @@ cheese3d_ctx cheese3d_create(void *target, u32 width, u32 height, u32 pitch, u32
cheese3d_ctx cheese3d_create_default(u32 bgcolor)
{
- return cheese3d_create((void *) (u64) gfx_info->framebuffer, gfx_info->width, gfx_info->height, gfx_info->pitch, bgcolor);
+ return cheese3d_create(bootinfo->gfx_framebuffer, bootinfo->gfx_width, bootinfo->gfx_height, bootinfo->gfx_pitch, bgcolor);
}
void cheese3d_destroy(cheese3d_ctx ctx)
diff --git a/stage3/font.c b/stage3/font.c
index f0b8d93..4c99137 100644
--- a/stage3/font.c
+++ b/stage3/font.c
@@ -4,6 +4,7 @@
#include "heap.h"
#include "memory.h"
#include "math.h"
+#include "bootinfo.h"
#include "font_builtin.c"
@@ -34,8 +35,8 @@ void font_set_size(u16 size)
outer_width = CHAR_WIDTH * font_size;
outer_height = CHAR_HEIGHT * font_size;
- screen_width = gfx_info->width / outer_width;
- screen_height = gfx_info->height / outer_height;
+ screen_width = bootinfo->gfx_width / outer_width;
+ screen_height = bootinfo->gfx_height / outer_height;
}
void font_set_cursor(term_pos new_cursor)
@@ -95,7 +96,7 @@ void font_load_classic()
void font_clear_screen()
{
cursor_x = cursor_y = 0;
- gfx_set_area(0, 0, gfx_info->width, gfx_info->height, 0xFF000000);
+ gfx_set_area(0, 0, bootinfo->gfx_width, bootinfo->gfx_height, 0xFF000000);
}
static void render_char(u8 c)
@@ -127,11 +128,11 @@ static void update_cursor()
while (cursor_y >= screen_height) {
cursor_y--;
- lmemcpy((void *) (u64) gfx_info->framebuffer,
- (void *) (u64) gfx_info->framebuffer + gfx_info->pitch * outer_height,
- gfx_info->pitch * (gfx_info->height - outer_height));
+ lmemcpy(bootinfo->gfx_framebuffer,
+ bootinfo->gfx_framebuffer + bootinfo->gfx_pitch * outer_height,
+ bootinfo->gfx_pitch * (bootinfo->gfx_height - outer_height));
- gfx_set_area(0, gfx_info->height-outer_height, gfx_info->width, outer_height, 0xFF000000);
+ gfx_set_area(0, bootinfo->gfx_height-outer_height, bootinfo->gfx_width, outer_height, 0xFF000000);
}
gfx_set_area(cursor_x * outer_width, cursor_y * outer_height,
diff --git a/stage3/fs.c b/stage3/fs.c
index d96d014..341a478 100644
--- a/stage3/fs.c
+++ b/stage3/fs.c
@@ -3,12 +3,13 @@
#include "string.h"
#include "memory.h"
#include "heap.h"
+#include "bootinfo.h"
#define FS_WALKER(X) bool (X)(str filename, u64 lba, usize fsize, usize fsect, void *varg)
void fs_walk(FS_WALKER(*fun), void *arg)
{
- u64 lba = (*(u32 *) (0x1000-10-8))/512;
+ u64 lba = bootinfo->ksize/512;
for (;;) {
u8 *info = ata_read_full(lba, 1);
diff --git a/stage3/gfx.c b/stage3/gfx.c
index 7fe8df7..4c9fe4c 100644
--- a/stage3/gfx.c
+++ b/stage3/gfx.c
@@ -1,7 +1,6 @@
#include "gfx.h"
#include "memory.h"
-
-struct GfxInfo *gfx_info = (void *) (0x1000-10);
+#include "bootinfo.h"
// byteswap
u32 make_color(color col)
@@ -15,17 +14,17 @@ u32 make_color(color col)
void gfx_set_pixel(u16 x, u16 y, u32 col)
{
- u32 *out = (u32 *) (u64) (gfx_info->framebuffer + y * gfx_info->pitch + x * sizeof col);
+ u32 *out = bootinfo->gfx_framebuffer + y * bootinfo->gfx_pitch + x * sizeof col;
*out = col;
BARRIER_VAR(out);
}
void gfx_set_area(u16 x, u16 y, u16 w, u16 h, u32 col)
{
- void *cbeg = (void *) (u64) (gfx_info->framebuffer + y * gfx_info->pitch + x * sizeof col);
- void *cend = cbeg + h * gfx_info->pitch;
+ void *cbeg = bootinfo->gfx_framebuffer + y * bootinfo->gfx_pitch + x * sizeof col;
+ void *cend = cbeg + h * bootinfo->gfx_pitch;
- for (; cbeg < cend; cbeg += gfx_info->pitch) {
+ for (; cbeg < cend; cbeg += bootinfo->gfx_pitch) {
u32 *rbeg = cbeg;
u32 *rend = rbeg + w;
@@ -38,8 +37,8 @@ void gfx_set_area(u16 x, u16 y, u16 w, u16 h, u32 col)
void gfx_draw_img(u16 x, u16 y, u16 w, u16 h, u32 *img)
{
- void *cbeg = (void *) (u64) (gfx_info->framebuffer + y * gfx_info->pitch + x * sizeof(color));
- for (u16 yi = 0; yi < h; cbeg += gfx_info->pitch, yi++)
+ void *cbeg = bootinfo->gfx_framebuffer + y * bootinfo->gfx_pitch + x * sizeof(color);
+ for (u16 yi = 0; yi < h; cbeg += bootinfo->gfx_pitch, yi++)
lmemcpy(cbeg, img + yi * w, w * sizeof(color));
BARRIER_VAR(cbeg);
diff --git a/stage3/gfx.h b/stage3/gfx.h
index 5d9c8b3..d81f54b 100644
--- a/stage3/gfx.h
+++ b/stage3/gfx.h
@@ -3,13 +3,6 @@
#include "def.h"
-extern struct __attribute__((packed)) GfxInfo {
- u16 pitch;
- u16 width;
- u16 height;
- u32 framebuffer;
-} *gfx_info;
-
typedef struct __attribute__((packed)) {
u8 r, g, b, a;
} color;
diff --git a/stage3/init.c b/stage3/init.c
index c65f08b..b49ba94 100644
--- a/stage3/init.c
+++ b/stage3/init.c
@@ -1,7 +1,9 @@
#include "def.h"
-void kmain();
+#include "bootinfo.h"
-void _start()
+void kmain(struct bootinfo *info);
+
+void _start(struct bootinfo *info)
{
// enable SSE. long mode demands it is present
u64 cr0;
@@ -15,5 +17,5 @@ void _start()
u16 fpu_cw = 0x37a;
asm volatile("fldcw %0"::"m"(fpu_cw));
- kmain();
+ kmain(info);
}
diff --git a/stage3/main.c b/stage3/main.c
index e9b5717..b4ce692 100644
--- a/stage3/main.c
+++ b/stage3/main.c
@@ -1,5 +1,4 @@
#include "def.h"
-#include "gfx.h"
#include "halt.h"
#include "heap.h"
#include "font.h"
@@ -12,21 +11,13 @@
#include "thread.h"
#include "shell.h"
#include "fs.h"
-#include "gfx.h"
#include "clock.h"
#include "rng.h"
#include "debug.h"
+#include "bootinfo.h"
-typedef enum {
- MEM_USABLE = 1,
- MEM_RESERVED = 2,
-} mem_region_type;
-
-typedef struct __attribute__((packed)) {
- void *start;
- usize size;
- usize type;
-} mem_region;
+#define T mem_region
+#include "vec.h"
char keymap[256] = { '\0' };
@@ -68,8 +59,12 @@ void keyboard_handler()
}
}
-void kmain()
+struct bootinfo *bootinfo;
+
+void kmain(struct bootinfo *info)
{
+ bootinfo = info;
+
// PML3
for (u64 page = 0; page < 512*512; page++)
((u64 *) 0x200000)[page] = (page << 30) | 0b10000011; // bit 7 is for huge pages
@@ -78,25 +73,29 @@ void kmain()
for (u64 tbl = 0; tbl < 512; tbl++)
((u64 *) 0x1000)[tbl] = (0x200000 + tbl * 0x1000) | 0b11;
-#define MMAP for (mem_region *mreg = (void *) 0x500; mreg->start != nil; mreg++)
-
- // heap init
+ // heap init and fill
heap_init();
- MMAP {
+ ITER(bootinfo->mmap) {
+ mem_region *r = &bootinfo->mmap.data[i];
+ if (r->type != MEM_USABLE || r->size == 0)
+ continue;
+
// remove anything between 0x100000 and 0x400000. it is used for kernel and page tables
- usize start = (usize) mreg->start;
+ usize start = (usize) r->start;
+ usize size = r->size;
+
+ if (start < 0x100000)
+ continue;
+
if (start >= 0x100000 && start < 0x400000) {
- if (start + mreg->size <= 0x400000) {
- mreg->size = 0; // kill it
- } else {
- mreg->size = start + mreg->size - 0x400000;
- mreg->start = (void *) 0x400000;
- }
+ if (start + size <= 0x400000)
+ continue; // skip
+
+ size = start + size - 0x400000;
+ start = 0x400000;
}
- // add to heap
- if (mreg->type == MEM_USABLE) // usable
- heap_add(mreg->start, mreg->size);
+ heap_add((void *) start, size);
}
// font init
@@ -108,20 +107,28 @@ void kmain()
print(S("welcome to cuddles\n"));
// memory map
- print(S("heap memory:\n"));
- MMAP {
- print_num_pad((u64) mreg->start, 16, 16, ' ');
+ print(S("memory map:\n"));
+ ITER(bootinfo->mmap) {
+ mem_region *r = &bootinfo->mmap.data[i];
+ print_num_pad((u64) r->start, 16, 16, ' ');
print(S(" | "));
- print_num_pad((u64) mreg->start + mreg->size, 16, 16, ' ');
+ print_num_pad((u64) r->start + r->size, 16, 16, ' ');
print(S(" | "));
- print_dec(mreg->type);
+ switch (r->type) {
+ case MEM_USABLE: print(S("usable")); break;
+ case MEM_RESERVED: print(S("reserved")); break;
+ case MEM_ACPI_RECLAIMABLE: print(S("acpi reclaimable")); break;
+ case MEM_ACPI_NVS: print(S("acpi nvs")); break;
+ case MEM_BAD: print(S("bad")); break;
+ default: print_dec(r->type); break;
+ }
print(S("\n"));
}
print(S("gfx framebuffer at "));
- print_hex(gfx_info->framebuffer);
+ print_hex((u64) bootinfo->gfx_framebuffer);
print(S("-"));
- print_hex((u64) gfx_info->framebuffer + gfx_info->pitch * gfx_info->height);
+ print_hex((u64) bootinfo->gfx_framebuffer + bootinfo->gfx_pitch * bootinfo->gfx_height);
print(S("\n"));
u32 vendor[4];
diff --git a/stage3/shell.c b/stage3/shell.c
index cf628ab..9fd0f93 100644
--- a/stage3/shell.c
+++ b/stage3/shell.c
@@ -12,6 +12,7 @@
#include "thread.h"
#include "rng.h"
#include "cheese_demo.h"
+#include "bootinfo.h"
static void cmd_echo(str arg)
{
@@ -82,7 +83,7 @@ static void cmd_img(str arg)
if (f.len != 2 * sizeof(u32) + width * height * sizeof(color))
print(S("img: invalid file size\n"));
else
- gfx_draw_img(gfx_info->width-width, 0, width, height,
+ gfx_draw_img(bootinfo->gfx_width-width, 0, width, height,
(void *) (f.data + 2 * sizeof(u32)));
}