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

kinit to 64-bit.

上级 54e63cc8
...@@ -28,7 +28,7 @@ LD = $(TOOLPREFIX)ld ...@@ -28,7 +28,7 @@ LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump OBJDUMP = $(TOOLPREFIX)objdump
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m64 \ 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) CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
ASFLAGS = -m64 -gdwarf-2 ASFLAGS = -m64 -gdwarf-2
LDFLAGS += -m elf_x86_64 LDFLAGS += -m elf_x86_64
......
...@@ -8,8 +8,7 @@ ...@@ -8,8 +8,7 @@
#include "kernel.h" #include "kernel.h"
#include "spinlock.h" #include "spinlock.h"
#include "kalloc.h" #include "kalloc.h"
#include "xv6-mtrace.h"
void kminit(void);
struct kmem kmems[NCPU]; struct kmem kmems[NCPU];
...@@ -17,6 +16,8 @@ extern char end[]; // first address after kernel loaded from ELF file ...@@ -17,6 +16,8 @@ extern char end[]; // first address after kernel loaded from ELF file
char *newend; char *newend;
enum { kalloc_memset = 0 }; enum { kalloc_memset = 0 };
static int kinited __mpalign__;
// simple page allocator to get off the ground during boot // simple page allocator to get off the ground during boot
char * char *
pgalloc(void) pgalloc(void)
...@@ -30,6 +31,86 @@ pgalloc(void) ...@@ -30,6 +31,86 @@ pgalloc(void)
return p; 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 #if 0
static void __attribute__((unused)) static void __attribute__((unused))
kmemprint(void) kmemprint(void)
......
...@@ -10,6 +10,7 @@ extern void initmp(void); ...@@ -10,6 +10,7 @@ extern void initmp(void);
extern void initlapic(void); extern void initlapic(void);
extern void initseg(void); extern void initseg(void);
extern void inittrap(void); extern void inittrap(void);
extern void initkalloc(void);
void void
cmain(void) cmain(void)
...@@ -24,6 +25,8 @@ cmain(void) ...@@ -24,6 +25,8 @@ cmain(void)
initlapic(); initlapic();
initseg(); initseg();
initkalloc();
cprintf("ncpu %d\n", ncpu); cprintf("ncpu %d\n", ncpu);
panic("end"); panic("end");
} }
...@@ -51,7 +51,7 @@ struct segdesc { ...@@ -51,7 +51,7 @@ struct segdesc {
// SEGDESC constructs a segment descriptor literal // SEGDESC constructs a segment descriptor literal
// with the given, base, limit, and type bits. // with the given, base, limit, and type bits.
#define SEGDESC(base, limit, bits) (struct segdesc){ \ #define SEGDESC(base, limit, bits) { \
(limit)&0xffff, (base)&0xffff, \ (limit)&0xffff, (base)&0xffff, \
((base)>>16)&0xff, \ ((base)>>16)&0xff, \
(bits)&0xff, \ (bits)&0xff, \
...@@ -61,7 +61,7 @@ struct segdesc { ...@@ -61,7 +61,7 @@ struct segdesc {
// SEGDESCHI constructs an extension segment descriptor // SEGDESCHI constructs an extension segment descriptor
// literal that records the high bits of base. // literal that records the high bits of base.
#define SEGDESCHI(base) (struct segdesc){ \ #define SEGDESCHI(base) { \
((base)>>32)&0xffff, ((base)>>48)&0xffff, \ ((base)>>32)&0xffff, ((base)>>48)&0xffff, \
} }
......
...@@ -13,3 +13,4 @@ ...@@ -13,3 +13,4 @@
#define INF (~0UL) #define INF (~0UL)
#define CACHELINE 64 // cache line size #define CACHELINE 64 // cache line size
#define MTRACE 0 #define MTRACE 0
#define PHYSTOP 0xE000000 // use phys mem up to here as free pool
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论