From c9c820840fd33b6722f00469d23dad740b981d9b Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Sun, 8 Dec 2024 23:14:32 +0900 Subject: [PATCH] add memprobe NOTE: print "%llx" "%lld" not working now --- boot/Makefile | 2 +- boot/boot.c | 5 +++- boot/dat.h | 7 +++++ boot/fn.h | 8 ++++- boot/gdt.S | 2 +- boot/mem.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 boot/mem.c diff --git a/boot/Makefile b/boot/Makefile index 77041f0..fc930db 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -5,7 +5,7 @@ PROG = boot SRCS = srt0.S gdt.S boot.c OBJS = srt0.o gdt.o boot.o -ESRCS = pccon.c sricon.c print.c a20.c time.c +ESRCS = pccon.c sricon.c print.c a20.c time.c mem.c OBJS += $(ESRCS:.c=.o) include $(SDIR)/Makefile.inc diff --git a/boot/boot.c b/boot/boot.c index 1ea7e52..4a90533 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -6,7 +6,7 @@ static void coninit(void); static void machdep(void); void (*probe1[])(void) = { - a20up, coninit, + a20up, coninit, memprobe, }; void (*probe2[])(void) = { }; @@ -31,7 +31,10 @@ ConDev contab[CON_END] = { .init = cominit, }, }; + ConDev *con = &contab[0]; +BIOSmmap biosmmap[64]; +uint cnvmem, extmem; static void coninit(void) diff --git a/boot/dat.h b/boot/dat.h index 1166b5a..d71c07e 100644 --- a/boot/dat.h +++ b/boot/dat.h @@ -36,6 +36,11 @@ struct ConDev{ uint dev; uchar pri; // the higher the better }; +typedef struct{ + u64 addr; /* Beginning of block */ + u64 size; /* Size of block */ + u32 type; /* Type of block */ +} __attribute__((packed)) BIOSmmap; // gdt.S extern volatile struct BIOSreg BIOSreg; @@ -44,5 +49,7 @@ extern volatile struct BIOSreg BIOSreg; extern void (*probe1[])(void); extern void (*probe2[])(void); extern BootProbe probes[]; +extern BIOSmmap biosmmap[64]; extern ConDev contab[CON_END]; extern ConDev *con; +extern uint cnvmem, extmem; diff --git a/boot/fn.h b/boot/fn.h index 4d1bb47..1231d2a 100644 --- a/boot/fn.h +++ b/boot/fn.h @@ -1,3 +1,6 @@ +#define MAX(x, y) ((x)>(y)?(x):(y)) +#define MIN(x, y) ((x)<(y)?(x):(y)) + // console.c void cominit(ConDev *d); void pcinit(ConDev *d); @@ -16,7 +19,10 @@ void print(const char *fmt, ...); // a20.c void a20up(void); -// long.c +// mem.c +void memprobe(void); + +// time.c long getsecs(void); static __inline int diff --git a/boot/gdt.S b/boot/gdt.S index 955f82c..f270930 100644 --- a/boot/gdt.S +++ b/boot/gdt.S @@ -78,7 +78,7 @@ .globl pmode_init .globl BIOSreg BIOSreg: - .space 64 + .space 36, 0 // Table // IDTR offset + 0 : entry 0 diff --git a/boot/mem.c b/boot/mem.c new file mode 100644 index 0000000..e0a23fe --- /dev/null +++ b/boot/mem.c @@ -0,0 +1,82 @@ +#include +#include "dat.h" +#include "fn.h" + +#define IOMEM_BEGIN 0x0A0000 +#define IOMEM_END 0x100000 + +enum{ + MAP_END = 0x00, + MAP_FREE = 0x01, + MAP_RES = 0x02, + MAP_ACPI_RECLAM = 0x03, + MAP_ACPI_NVS = 0x04, +}; + +static BIOSmmap* +int15_E820(BIOSmmap *m) +{ + int rc, sig, off = 0; + do{ + BIOSreg.es = ((uint)(m) >> 4); + __asm volatile("int $0x35; setc %b1" + : "=a" (sig), "=d" (rc), "=b" (off) + : "0" (0xE820), "1" (0x534d4150), "b" (off), + "c" (sizeof(*m)), "D" (((uint)m) & 0xf) + : "cc", "memory"); + + off = BIOSreg.bx; + if(rc &0xff || sig !=0x534d4150){ + break; + if(m->type == 0) + m->type = MAP_RES; + } + m++; + }while(off); + return m; +} + +static void +dumpmem(BIOSmmap *m) +{ + ulong tot = 0; + + for(BIOSmmap *p=m; p->type != MAP_END; ++p){ + print("MEM %u type %u size %lldKB at 0x%llx\n", + p-m, p->type, p->size/1024, p->addr); + if(p->type == MAP_FREE) + tot += p->size/1024; + } + print("RAM low:%dKB high:%dKB\n", cnvmem, extmem); + print("Total free memory: %dKB\n", tot); +} + +static int +isa20done(void) +{ + register char *a = (char *)0x100000; + register char *b = (char *)0x000000; + + return *a != *b; +} + +void +memprobe(void) +{ + BIOSmmap *m; + + cnvmem = extmem = 0; + m = int15_E820(biosmmap); + m->type = MAP_END; + for(m = biosmmap; m->type != MAP_END; ++m){ + if(m->type != MAP_FREE || m->size <= 0) + continue; + if(m->addr < IOMEM_BEGIN) + cnvmem = MAX(cnvmem, m->addr + m->size)/1024; + if(m->addr >= IOMEM_END) + extmem += m->size/1024; + } + dumpmem(biosmmap); + print("A20:%d", isa20done()); +} +