@@ 4,10 4,17 @@ global pread_sector
extern boot2_main
+%define BIOS_MEMDETECT_MAGIC 0x534d4150
+%define MMAP_BASE 0x1000
+
start:
mov si, hallo
call print
+ push dword MMAP_BASE
+ call near detect_memory
+ add esp, 4
+
; hide cursor
mov ah, 0x01
mov cx, 0x2607
@@ 15,9 22,80 @@ start:
jmp enter_protected
-idle:
- hlt
- jmp idle
+hallo: db 'xos boot loader stage 1 ...', 0xa, 0xd, 0
+
+print:
+ mov ah, 0x0e
+.repeat:
+ lodsb
+ cmp al, 0
+ je .done
+ int 0x10
+ jmp .repeat
+.done:
+ ret
+
+enter_protected:
+ cli
+ lgdt [gdt_desc]
+
+ mov eax, cr0
+ or al, 1
+ mov cr0, eax
+
+ jmp 0x08:protected_main
+
+detect_memory:
+ mov di, [esp + 2] ; mmap base
+ add di, 4 ; first dword reserved for count
+ xor ebp, ebp ; valid entries counter
+
+ xor ebx, ebx
+
+ call .e820
+ jc .failed
+
+ ; first call checks:
+ cmp eax, BIOS_MEMDETECT_MAGIC
+ jne .failed
+ test ebx, ebx
+ je .failed
+
+.item:
+ jcxz .next
+ cmp cl, 0x18 ; extended record?
+ jb .normal
+.extended:
+ test [di + 20], byte 1 ; ignored
+ je .next
+.normal:
+ mov ecx, [di + 8]
+ or ecx, [di + 12] ; zero length?
+ jz .next
+ inc bp
+ add di, 20
+
+.next:
+ test ebx, ebx
+ je .finish
+ call .e820
+ jc .finish
+ jmp .item
+
+.failed:
+ mov ebp, 0
+.finish:
+ mov di, [esp+2]
+ mov [di], ebp
+ ret
+
+.e820
+ mov eax, 0xe820
+ mov edx, BIOS_MEMDETECT_MAGIC
+ mov [di + 20], dword 1
+ mov ecx, 24
+ int 0x15
+ ret
bits 32
@@ 105,30 183,6 @@ pread_sector:
bits 16
-hallo: db 'xos boot loader stage 1 ...', 0xa, 0xd, 0
-
-print:
- mov ah, 0x0e
-.repeat:
- lodsb
- cmp al, 0
- je .done
- int 0x10
- jmp .repeat
-.done:
- ret
-
-enter_protected:
- cli
- lgdt [gdt_desc]
-
- mov eax, cr0
- or al, 1
- mov cr0, eax
-
- jmp 0x08:protected_main
-
-
gdt_desc:
dw 0x1f
dd gdt
@@ 47,13 47,13 @@ static struct proc *launch(const char *binary, uint32_t mem);
void kernel_main() {
kprint("kernel main entered\n");
+ console_init(&global_console);
+ setup_gdt();
kmem_init();
paging_init();
- setup_gdt();
- console_init(&global_console);
console_clear(&global_console);
console_print(&global_console, "xos kernel loaded\n");
@@ 1,10 1,23 @@
+#include <sys/console.h>
#include <sys/kernel.h>
#include <sys/memory.h>
#include <sys/paging.h>
+#define DEBUG
+#include <debug.h>
+
#define KMEM_ARENA_START 0x200000
#define KMEM_ARENA_END 0x400000
+struct detect_mmap_info {
+ uint32_t base_low;
+ uint32_t base_high;
+ uint32_t length_low;
+ uint32_t length_high;
+ uint16_t type;
+ uint16_t pad;
+} __attribute__ ((__packed__));
+
struct kmem {
void *free; // first free page
};
@@ 15,7 28,11 @@ struct free_info {
static struct kmem kmem_state;
+void kmem_detect(void);
+
void kmem_init(void) {
+ kmem_detect();
+
// begin with the last page
void *page = (void *)(KMEM_ARENA_END - PAGE_SIZE);
@@ 32,6 49,22 @@ void kmem_init(void) {
kmem_state.free = previous;
}
+void
+kmem_detect(void) {
+ uint32_t mmap_count = *(uint32_t *)0x1000;
+ struct detect_mmap_info *mmap = (struct detect_mmap_info *)(0x1000 + 4);
+ khexprint("mmap count", mmap_count);
+ khexprint("mmap size", sizeof(struct detect_mmap_info));
+ for (int i=0; i<mmap_count; ++i) {
+ khexprint("=========== mmap entry", i);
+ khexprint("base_low", mmap[i].base_low);
+ khexprint("base_high", mmap[i].base_high);
+ khexprint("length_low", mmap[i].length_low);
+ khexprint("length_high", mmap[i].length_high);
+ khexprint("type", mmap[i].type);
+ }
+}
+
void *kmem_alloc_pages(size_t pages) {
if (pages != 1) {
panic("can only alloc one page at a time");