提交 77f1be87 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

initkalloc -- handle an e820 map.

..There is not yet code to read the e820 map from the BIOS.
上级 266d673d
......@@ -32,6 +32,7 @@ OBJS = \
cga.o \
condvar.o \
console.o \
e820.o \
exec.o \
file.o \
fs.o \
......
#include "types.h"
#include "kernel.h"
#include "e820.h"
// Make is easier to copy from dmesg
#define E820_LINUX(start, end, t) \
{ .addr = start, .size = end - start, .type = t }
#if defined(HW_qemu)
// For qemu -m 512
struct e820entry e820[NE820] = {
E820_LINUX(0x0000000000000000ull, 0x000000000009f400ull, E820_RAM),
E820_LINUX(0x000000000009f400ull, 0x00000000000a0000ull, E820_RESERVED),
E820_LINUX(0x00000000000f0000ull, 0x0000000000100000ull, E820_RESERVED),
E820_LINUX(0x0000000000100000ull, 0x000000001fffd000ull, E820_RAM),
E820_LINUX(0x000000001fffd000ull, 0x0000000020000000ull, E820_RESERVED),
E820_LINUX(0x00000000fffc0000ull, 0x0000000100000000ull, E820_RESERVED)
};
#elif defined(HW_josmp)
#elif defined(HW_ud0)
#endif
static struct e820entry *
e820search(paddr pa)
{
struct e820entry *e;
struct e820entry *q;
q = &e820[NE820];
for (e = &e820[0]; e < q; e++) {
if (e->type == E820_RAM && (e->addr <= pa) && ((e->addr + e->size) > pa))
return e;
}
return NULL;
}
u64
e820bytes(void)
{
u64 tot = 0;
for (int i = 0; i < NE820; i++) {
if (e820[i].type == E820_RAM)
tot += e820[i].size;
}
return tot;
}
u64
e820size(void *va)
{
struct e820entry *e;
paddr pa = v2p(va);
e = e820search(pa);
if (e == NULL)
return -1;
return (e->addr + e->size) - pa;
}
void *
e820next(void *va, u64 inc)
{
struct e820entry *e;
paddr pa = v2p(va);
e = e820search(pa);
if (e == NULL)
return (void *)-1;
pa += inc;
if (pa < (e->addr + e->size))
return p2v(pa);
for (e = e + 1; e < &e820[NE820]; e++) {
if (e->type == E820_RAM)
return p2v(e->addr);
}
return (void *)-1;
}
#define E820_RAM 1
#define E820_RESERVED 2
#define E820_ACPI 3
#define E820_NVS 4
#define NE820 32
struct e820entry {
u64 addr; // start of memory segment
u64 size; // size of memory segment
u32 type; // type of memory segment
} __attribute__((packed));
extern struct e820entry e820[NE820];
u64 e820bytes(void);
u64 e820size(void *va);
void *e820next(void *va, u64 inc);
......@@ -9,6 +9,7 @@
#include "kalloc.h"
#include "mtrace.h"
#include "cpu.h"
#include "e820.h"
struct kmem kmems[NCPU];
struct kmem kstacks[NCPU];
......@@ -41,7 +42,7 @@ kfree_pool(struct kmem *m, char *v)
{
struct run *r;
if((uptr)v % PGSIZE || v < end || v2p(v) >= PHYSTOP)
if((uptr)v % PGSIZE || v < end || e820size(v) == -1ull)
panic("kfree_pool");
// Fill with junk to catch dangling refs.
......@@ -150,7 +151,8 @@ void
initkalloc(void)
{
char *p;
char *e;
u64 n;
u64 k;
for (int c = 0; c < NCPU; c++) {
kmems[c].name[0] = (char) c + '0';
......@@ -166,18 +168,35 @@ initkalloc(void)
kstacks[c].size = KSTACKSIZE;
}
cprintf("%lu MBytes\n", e820bytes() / (1 << 20));
n = e820bytes() / NCPU;
if (n & (PGSIZE - 1)) {
cprintf("Oops: bytes/CPU isn't aligned\n");
n = PGROUNDDOWN(n);
}
p = (char*)PGROUNDUP((uptr)newend);
e = (char*)KBASE;
k = (((uptr)p) - KBASE);
for (int c = 0; c < NCPU; c++) {
char *sp = p + CPUKSTACKS*KSTACKSIZE;
char *ep = e + (PHYSTOP/NCPU);
if (sp >= ep)
panic("Too many stacks");
for (; p < sp; p += KSTACKSIZE)
// Fill the stack allocator
for (int i = 0; i < CPUKSTACKS; i++, k += KSTACKSIZE) {
if (p == (void *)-1)
panic("initkalloc: e820next");
// XXX(sbw) handle this condition
if (e820size(p) < KSTACKSIZE)
panic("initkalloc: e820size");
kfree_pool(&kstacks[c], p);
for (; p < ep; p += PGSIZE)
p = e820next(p, KSTACKSIZE);
}
// The rest goes to the page allocator
for (; k != n; k += PGSIZE, p = e820next(p, PGSIZE)) {
if (p == (void *)-1)
panic("initkalloc: e820next");
kfree_pool(&kmems[c], p);
e = p;
}
k = 0;
}
kminit();
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论