提交 2e5da953 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

kinit to 64-bit.

上级 54e63cc8
......@@ -28,7 +28,7 @@ LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m64 \
-Werror -fms-extensions -mno-sse -mcmodel=kernel
-Werror -std=c99 -fms-extensions -mno-sse -mcmodel=kernel
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
ASFLAGS = -m64 -gdwarf-2
LDFLAGS += -m elf_x86_64
......
......@@ -8,8 +8,7 @@
#include "kernel.h"
#include "spinlock.h"
#include "kalloc.h"
void kminit(void);
#include "xv6-mtrace.h"
struct kmem kmems[NCPU];
......@@ -17,6 +16,8 @@ extern char end[]; // first address after kernel loaded from ELF file
char *newend;
enum { kalloc_memset = 0 };
static int kinited __mpalign__;
// simple page allocator to get off the ground during boot
char *
pgalloc(void)
......@@ -30,6 +31,86 @@ pgalloc(void)
return p;
}
// Free the page of physical memory pointed at by v,
// which normally should have been returned by a
// call to kalloc(). (The exception is when
// initializing the allocator; see kinit above.)
static void
kfree_pool(struct kmem *m, char *v)
{
struct run *r;
if((uptr)v % PGSIZE || v < end || v2p(v) >= PHYSTOP)
panic("kfree_pool");
// Fill with junk to catch dangling refs.
if (kinited && kalloc_memset)
memset(v, 1, PGSIZE);
acquire(&m->lock);
r = (struct run*)v;
r->next = m->freelist;
m->freelist = r;
m->nfree++;
if (kinited)
mtrace_label_register(mtrace_label_block,
r,
0,
0,
0,
RET_EIP());
release(&m->lock);
}
// Memory allocator by Kernighan and Ritchie,
// The C programming Language, 2nd ed. Section 8.7.
typedef struct header {
struct header *ptr;
u64 size; // in multiples of sizeof(Header)
} __mpalign__ Header;
static struct freelist {
Header base;
Header *freep; // last allocated block
struct spinlock lock;
char name[MAXNAME];
} freelists[NCPU];
static void
kminit(void)
{
for (int c = 0; c < NCPU; c++) {
freelists[c].name[0] = (char) c + '0';
safestrcpy(freelists[c].name+1, "freelist", MAXNAME-1);
initlock(&freelists[c].lock, freelists[c].name);
}
}
// Initialize free list of physical pages.
void
initkalloc(void)
{
char *p;
for (int c = 0; c < NCPU; c++) {
kmems[c].name[0] = (char) c + '0';
safestrcpy(kmems[c].name+1, "kmem", MAXNAME-1);
initlock(&kmems[c].lock, kmems[c].name);
}
p = (char*)PGROUNDUP((uptr)newend);
for(; p + PGSIZE <= (char*)KBASE + PHYSTOP; p += PGSIZE)
kfree_pool(&kmems[((uptr) v2p(p)) / (PHYSTOP/NCPU)], p);
kminit();
kinited = 1;
}
#if 0
static void __attribute__((unused))
kmemprint(void)
......
......@@ -10,6 +10,7 @@ extern void initmp(void);
extern void initlapic(void);
extern void initseg(void);
extern void inittrap(void);
extern void initkalloc(void);
void
cmain(void)
......@@ -24,6 +25,8 @@ cmain(void)
initlapic();
initseg();
initkalloc();
cprintf("ncpu %d\n", ncpu);
panic("end");
}
......@@ -51,7 +51,7 @@ struct segdesc {
// SEGDESC constructs a segment descriptor literal
// with the given, base, limit, and type bits.
#define SEGDESC(base, limit, bits) (struct segdesc){ \
#define SEGDESC(base, limit, bits) { \
(limit)&0xffff, (base)&0xffff, \
((base)>>16)&0xff, \
(bits)&0xff, \
......@@ -61,7 +61,7 @@ struct segdesc {
// SEGDESCHI constructs an extension segment descriptor
// literal that records the high bits of base.
#define SEGDESCHI(base) (struct segdesc){ \
#define SEGDESCHI(base) { \
((base)>>32)&0xffff, ((base)>>48)&0xffff, \
}
......
......@@ -13,3 +13,4 @@
#define INF (~0UL)
#define CACHELINE 64 // cache line size
#define MTRACE 0
#define PHYSTOP 0xE000000 // use phys mem up to here as free pool
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论