-initrd fs.img, ramdisk.c, file system

This commit is contained in:
Robert Morris 2019-05-31 11:45:42 -04:00
parent 2ec1959fd1
commit 5d34fa2a48
20 changed files with 138 additions and 403 deletions

View file

@ -12,7 +12,14 @@ OBJS = \
trampoline.o \ trampoline.o \
trap.o \ trap.o \
syscall.o \ syscall.o \
sysproc.o sysproc.o \
bio.o \
fs.o \
log.o \
sleeplock.o \
file.o \
pipe.o \
ramdisk.o
XXXOBJS = \ XXXOBJS = \
bio.o\ bio.o\
@ -83,15 +90,15 @@ endif
LDFLAGS = -z max-page-size=4096 LDFLAGS = -z max-page-size=4096
kernel: $(OBJS) entry.o kernel.ld kernel: $(OBJS) entry.o kernel.ld initcode
$(LD) $(LDFLAGS) -T kernel.ld -o kernel entry.o $(OBJS) $(LD) $(LDFLAGS) -T kernel.ld -o kernel entry.o $(OBJS)
$(OBJDUMP) -S kernel > kernel.asm $(OBJDUMP) -S kernel > kernel.asm
$(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym $(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym
initcode: initcode.S initcode: initcode.S
$(CC) $(CFLAGS) -nostdinc -I. -c initcode.S $(CC) $(CFLAGS) -nostdinc -I. -c initcode.S
#$(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o $(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o
#$(OBJCOPY) -S -O binary initcode.out initcode $(OBJCOPY) -S -O binary initcode.out initcode
$(OBJDUMP) -S initcode.o > initcode.asm $(OBJDUMP) -S initcode.o > initcode.asm
tags: $(OBJS) entryother.S _init tags: $(OBJS) entryother.S _init
@ -107,6 +114,9 @@ _%: %.o $(ULIB)
$(OBJDUMP) -S $@ > $*.asm $(OBJDUMP) -S $@ > $*.asm
$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym $(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
usys.S : usys.pl
perl ./usys.pl > usys.S
_forktest: forktest.o $(ULIB) _forktest: forktest.o $(ULIB)
# forktest has less library code linked in - needs to be small # forktest has less library code linked in - needs to be small
# in order to be able to max out the proc table. # in order to be able to max out the proc table.
@ -171,7 +181,7 @@ ifndef CPUS
CPUS := 1 CPUS := 1
endif endif
QEMUOPTS = -machine virt -kernel kernel -m 3G -smp $(CPUS) -nographic QEMUOPTS = -machine virt -kernel kernel -m 3G -smp $(CPUS) -nographic
#QEMUOPTS += -initrd fs.img QEMUOPTS += -initrd fs.img
qemu: kernel qemu: kernel
$(QEMU) $(QEMUOPTS) $(QEMU) $(QEMUOPTS)

7
bio.c
View file

@ -19,10 +19,11 @@
// and needs to be written to disk. // and needs to be written to disk.
#include "types.h" #include "types.h"
#include "defs.h"
#include "param.h" #include "param.h"
#include "spinlock.h" #include "spinlock.h"
#include "sleeplock.h" #include "sleeplock.h"
#include "riscv.h"
#include "defs.h"
#include "fs.h" #include "fs.h"
#include "buf.h" #include "buf.h"
@ -100,7 +101,7 @@ bread(uint dev, uint blockno)
b = bget(dev, blockno); b = bget(dev, blockno);
if((b->flags & B_VALID) == 0) { if((b->flags & B_VALID) == 0) {
iderw(b); ramdiskrw(b);
} }
return b; return b;
} }
@ -112,7 +113,7 @@ bwrite(struct buf *b)
if(!holdingsleep(&b->lock)) if(!holdingsleep(&b->lock))
panic("bwrite"); panic("bwrite");
b->flags |= B_DIRTY; b->flags |= B_DIRTY;
iderw(b); ramdiskrw(b);
} }
// Release a locked buffer. // Release a locked buffer.

8
defs.h
View file

@ -54,10 +54,10 @@ int readi(struct inode*, char*, uint, uint);
void stati(struct inode*, struct stat*); void stati(struct inode*, struct stat*);
int writei(struct inode*, char*, uint, uint); int writei(struct inode*, char*, uint, uint);
// ide.c // ramdisk.c
void ideinit(void); void ramdiskinit(void);
void ideintr(void); void ramdiskintr(void);
void iderw(struct buf*); void ramdiskrw(struct buf*);
// ioapic.c // ioapic.c
void ioapicenable(int irq, int cpu); void ioapicenable(int irq, int cpu);

1
file.c
View file

@ -3,6 +3,7 @@
// //
#include "types.h" #include "types.h"
#include "riscv.h"
#include "defs.h" #include "defs.h"
#include "param.h" #include "param.h"
#include "fs.h" #include "fs.h"

4
fs.c
View file

@ -10,10 +10,10 @@
// are in sysfile.c. // are in sysfile.c.
#include "types.h" #include "types.h"
#include "riscv.h"
#include "defs.h" #include "defs.h"
#include "param.h" #include "param.h"
#include "stat.h" #include "stat.h"
#include "mmu.h"
#include "proc.h" #include "proc.h"
#include "spinlock.h" #include "spinlock.h"
#include "sleeplock.h" #include "sleeplock.h"
@ -180,7 +180,7 @@ iinit(int dev)
} }
readsb(dev, &sb); readsb(dev, &sb);
cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d\ printf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d\
inodestart %d bmap start %d\n", sb.size, sb.nblocks, inodestart %d bmap start %d\n", sb.size, sb.nblocks,
sb.ninodes, sb.nlog, sb.logstart, sb.inodestart, sb.ninodes, sb.nlog, sb.logstart, sb.inodestart,
sb.bmapstart); sb.bmapstart);

168
ide.c
View file

@ -1,168 +0,0 @@
// Simple PIO-based (non-DMA) IDE driver code.
#include "types.h"
#include "defs.h"
#include "param.h"
#include "memlayout.h"
#include "mmu.h"
#include "proc.h"
#include "x86.h"
#include "traps.h"
#include "spinlock.h"
#include "sleeplock.h"
#include "fs.h"
#include "buf.h"
#define SECTOR_SIZE 512
#define IDE_BSY 0x80
#define IDE_DRDY 0x40
#define IDE_DF 0x20
#define IDE_ERR 0x01
#define IDE_CMD_READ 0x20
#define IDE_CMD_WRITE 0x30
#define IDE_CMD_RDMUL 0xc4
#define IDE_CMD_WRMUL 0xc5
// idequeue points to the buf now being read/written to the disk.
// idequeue->qnext points to the next buf to be processed.
// You must hold idelock while manipulating queue.
static struct spinlock idelock;
static struct buf *idequeue;
static int havedisk1;
static void idestart(struct buf*);
// Wait for IDE disk to become ready.
static int
idewait(int checkerr)
{
int r;
while(((r = inb(0x1f7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
;
if(checkerr && (r & (IDE_DF|IDE_ERR)) != 0)
return -1;
return 0;
}
void
ideinit(void)
{
int i;
initlock(&idelock, "ide");
ioapicenable(IRQ_IDE, ncpu - 1);
idewait(0);
// Check if disk 1 is present
outb(0x1f6, 0xe0 | (1<<4));
for(i=0; i<1000; i++){
if(inb(0x1f7) != 0){
havedisk1 = 1;
break;
}
}
// Switch back to disk 0.
outb(0x1f6, 0xe0 | (0<<4));
}
// Start the request for b. Caller must hold idelock.
static void
idestart(struct buf *b)
{
if(b == 0)
panic("idestart");
if(b->blockno >= FSSIZE)
panic("incorrect blockno");
int sector_per_block = BSIZE/SECTOR_SIZE;
int sector = b->blockno * sector_per_block;
int read_cmd = (sector_per_block == 1) ? IDE_CMD_READ : IDE_CMD_RDMUL;
int write_cmd = (sector_per_block == 1) ? IDE_CMD_WRITE : IDE_CMD_WRMUL;
if (sector_per_block > 7) panic("idestart");
idewait(0);
outb(0x3f6, 0); // generate interrupt
outb(0x1f2, sector_per_block); // number of sectors
outb(0x1f3, sector & 0xff);
outb(0x1f4, (sector >> 8) & 0xff);
outb(0x1f5, (sector >> 16) & 0xff);
outb(0x1f6, 0xe0 | ((b->dev&1)<<4) | ((sector>>24)&0x0f));
if(b->flags & B_DIRTY){
outb(0x1f7, write_cmd);
outsl(0x1f0, b->data, BSIZE/4);
} else {
outb(0x1f7, read_cmd);
}
}
// Interrupt handler.
void
ideintr(void)
{
struct buf *b;
// First queued buffer is the active request.
acquire(&idelock);
if((b = idequeue) == 0){
release(&idelock);
return;
}
idequeue = b->qnext;
// Read data if needed.
if(!(b->flags & B_DIRTY) && idewait(1) >= 0)
insl(0x1f0, b->data, BSIZE/4);
// Wake process waiting for this buf.
b->flags |= B_VALID;
b->flags &= ~B_DIRTY;
wakeup(b);
// Start disk on next buf in queue.
if(idequeue != 0)
idestart(idequeue);
release(&idelock);
}
//PAGEBREAK!
// Sync buf with disk.
// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID.
// Else if B_VALID is not set, read buf from disk, set B_VALID.
void
iderw(struct buf *b)
{
struct buf **pp;
if(!holdingsleep(&b->lock))
panic("iderw: buf not locked");
if((b->flags & (B_VALID|B_DIRTY)) == B_VALID)
panic("iderw: nothing to do");
if(b->dev != 0 && !havedisk1)
panic("iderw: ide disk 1 not present");
acquire(&idelock); //DOC:acquire-lock
// Append b to idequeue.
b->qnext = 0;
for(pp=&idequeue; *pp; pp=&(*pp)->qnext) //DOC:insert-queue
;
*pp = b;
// Start disk if necessary.
if(idequeue == b)
idestart(b);
// Wait for request to finish.
while((b->flags & (B_VALID|B_DIRTY)) != B_VALID){
sleep(b, &idelock);
}
release(&idelock);
}

View file

@ -27,6 +27,8 @@ void
kinit() kinit()
{ {
initlock(&kmem.lock, "kmem"); initlock(&kmem.lock, "kmem");
if(PHYSTOP > RAMDISK)
panic("kinit");
freerange(end, (void*)PHYSTOP); freerange(end, (void*)PHYSTOP);
} }

1
log.c
View file

@ -1,4 +1,5 @@
#include "types.h" #include "types.h"
#include "riscv.h"
#include "defs.h" #include "defs.h"
#include "param.h" #include "param.h"
#include "spinlock.h" #include "spinlock.h"

4
main.c
View file

@ -17,11 +17,9 @@ main()
kvminit(); // kernel page table kvminit(); // kernel page table
procinit(); // process table procinit(); // process table
trapinit(); // trap vectors trapinit(); // trap vectors
#if 0
binit(); // buffer cache binit(); // buffer cache
fileinit(); // file table fileinit(); // file table
ideinit(); // disk ramdiskinit(); // disk
#endif
userinit(); // first user process userinit(); // first user process
scheduler(); scheduler();

View file

@ -4,6 +4,8 @@
// 00001000 -- boot ROM, provided by qemu // 00001000 -- boot ROM, provided by qemu
// 10000000 -- uart0 registers // 10000000 -- uart0 registers
// 80000000 -- boot ROM jumps here in machine mode // 80000000 -- boot ROM jumps here in machine mode
// -kernel loads the kernel here
// 88000000 -- -initrd fs.img ramdisk image.
// unused RAM after 80000000. // unused RAM after 80000000.
// the kernel uses physical memory thus: // the kernel uses physical memory thus:
@ -14,6 +16,8 @@
// registers start here in physical memory. // registers start here in physical memory.
#define UART0 0x10000000L #define UART0 0x10000000L
#define RAMDISK 0x88000000
// the kernel expects there to be RAM // the kernel expects there to be RAM
// for use by the kernel and user pages // for use by the kernel and user pages
// from physical address 0x80000000 to PHYSTOP. // from physical address 0x80000000 to PHYSTOP.

2
pipe.c
View file

@ -1,7 +1,7 @@
#include "types.h" #include "types.h"
#include "riscv.h"
#include "defs.h" #include "defs.h"
#include "param.h" #include "param.h"
#include "mmu.h"
#include "proc.h" #include "proc.h"
#include "fs.h" #include "fs.h"
#include "spinlock.h" #include "spinlock.h"

27
proc.c
View file

@ -116,16 +116,13 @@ found:
return p; return p;
} }
// XXX hack because I don't know how to incorporate initcode // a user program that calls exec("/init")
// into the kernel binary. just the exec system call, no arguments. // od -t xC initcode
// manually copied from initcode.asm.
unsigned char initcode[] = { unsigned char initcode[] = {
0x85, 0x48, // li a7, 1 -- SYS_fork 0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x05, 0x02, 0x97, 0x05, 0x00, 0x00, 0x93, 0x85, 0x05, 0x02,
0x73, 0x00, 0x00, 0x00, // ecall 0x9d, 0x48, 0x73, 0x00, 0x00, 0x00, 0x89, 0x48, 0x73, 0x00, 0x00, 0x00, 0xef, 0xf0, 0xbf, 0xff,
0x8d, 0x48, // li a7, 3 -- SYS_wait 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x73, 0x00, 0x00, 0x00, // ecall 0x00, 0x00, 0x00
0x89, 0x48, // li a7, 2 -- SYS_exit
0x73, 0x00, 0x00, 0x00, // ecall
}; };
//PAGEBREAK: 32 //PAGEBREAK: 32
@ -146,8 +143,7 @@ userinit(void)
p->tf->sp = PGSIZE; p->tf->sp = PGSIZE;
safestrcpy(p->name, "initcode", sizeof(p->name)); safestrcpy(p->name, "initcode", sizeof(p->name));
// XXX riscv p->cwd = namei("/");
//p->cwd = namei("/");
// this assignment to p->state lets other cores // this assignment to p->state lets other cores
// run this process. the acquire forces the above // run this process. the acquire forces the above
@ -210,13 +206,11 @@ fork(void)
// Cause fork to return 0 in the child. // Cause fork to return 0 in the child.
np->tf->a0 = 0; np->tf->a0 = 0;
#if 0 // XXX riscv
// increment reference counts on open file descriptors. // increment reference counts on open file descriptors.
for(i = 0; i < NOFILE; i++) for(i = 0; i < NOFILE; i++)
if(p->ofile[i]) if(p->ofile[i])
np->ofile[i] = filedup(p->ofile[i]); np->ofile[i] = filedup(p->ofile[i]);
np->cwd = idup(p->cwd); np->cwd = idup(p->cwd);
#endif
safestrcpy(np->name, p->name, sizeof(p->name)); safestrcpy(np->name, p->name, sizeof(p->name));
@ -244,7 +238,6 @@ exit(void)
if(p == initproc) if(p == initproc)
panic("init exiting"); panic("init exiting");
#if 0 // XXX riscv
// Close all open files. // Close all open files.
for(fd = 0; fd < NOFILE; fd++){ for(fd = 0; fd < NOFILE; fd++){
if(p->ofile[fd]){ if(p->ofile[fd]){
@ -256,7 +249,6 @@ exit(void)
begin_op(); begin_op();
iput(p->cwd); iput(p->cwd);
end_op(); end_op();
#endif
p->cwd = 0; p->cwd = 0;
acquire(&ptable.lock); acquire(&ptable.lock);
@ -423,9 +415,8 @@ forkret(void)
// of a regular process (e.g., they call sleep), and thus cannot // of a regular process (e.g., they call sleep), and thus cannot
// be run from main(). // be run from main().
first = 0; first = 0;
// XXX riscv iinit(ROOTDEV);
//iinit(ROOTDEV); initlog(ROOTDEV);
//initlog(ROOTDEV);
} }
usertrapret(); usertrapret();

45
ramdisk.c Normal file
View file

@ -0,0 +1,45 @@
//
// ramdisk that uses the disk image loaded by qemu -rdinit fs.img
//
#include "types.h"
#include "riscv.h"
#include "defs.h"
#include "param.h"
#include "memlayout.h"
#include "spinlock.h"
#include "sleeplock.h"
#include "fs.h"
#include "buf.h"
void
ramdiskinit(void)
{
}
// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID.
// Else if B_VALID is not set, read buf from disk, set B_VALID.
void
ramdiskrw(struct buf *b)
{
if(!holdingsleep(&b->lock))
panic("ramdiskrw: buf not locked");
if((b->flags & (B_VALID|B_DIRTY)) == B_VALID)
panic("ramdiskrw: nothing to do");
if(b->blockno >= FSSIZE)
panic("ramdiskrw: blockno too big");
uint64 diskaddr = b->blockno * BSIZE;
char *addr = (char *)RAMDISK + diskaddr;
if(b->flags & B_DIRTY){
// write
memmove(addr, b->data, BSIZE);
b->flags &= ~B_DIRTY;
} else {
// read
memmove(b->data, addr, BSIZE);
b->flags |= B_VALID;
}
}

View file

@ -1,11 +1,10 @@
// Sleeping locks // Sleeping locks
#include "types.h" #include "types.h"
#include "riscv.h"
#include "defs.h" #include "defs.h"
#include "param.h" #include "param.h"
#include "x86.h"
#include "memlayout.h" #include "memlayout.h"
#include "mmu.h"
#include "proc.h" #include "proc.h"
#include "spinlock.h" #include "spinlock.h"
#include "sleeplock.h" #include "sleeplock.h"

132
trapasm.S
View file

@ -1,132 +0,0 @@
#include "param.h"
#include "x86.h"
#include "mmu.h"
# the offset of cs in trapframe (i.e., tf->cs - tf)
#define CSOFF 144
# vectors.S sends all traps here.
.globl alltraps
alltraps:
# Build trap frame.
push %r15
push %r14
push %r13
push %r12
push %r11
push %r10
push %r9
push %r8
push %rdi
push %rsi
push %rbp
push %rdx
push %rcx
push %rbx
push %rax
cmpw $SEG_KCODE, CSOFF(%rsp) # compare to saved cs
jz 1f
swapgs
1:mov %rsp, %rdi # frame in arg1
call trap
# Return falls through to trapret...
.globl trapret
trapret:
cli
cmpw $SEG_KCODE, CSOFF(%rsp) # compare to saved cs
jz 1f
swapgs
1:pop %rax
pop %rbx
pop %rcx
pop %rdx
pop %rbp
pop %rsi
pop %rdi
pop %r8
pop %r9
pop %r10
pop %r11
pop %r12
pop %r13
pop %r14
pop %r15
add $16, %rsp # discard trapnum and errorcode
iretq
#PAGEBREAK!
# syscall jumps here after syscall instruction
.globl sysentry
sysentry: # Build syscall frame.
// load kernel stack address
swapgs
movq %rax, %gs:0 // save %rax in syscallno of cpu entry
movq %rsp, %gs:8 // user sp
movq %gs:16, %rax // proc entry
movq %ss:0(%rax), %rax // load kstack from proc
addq $(KSTACKSIZE), %rax
movq %rax, %rsp
movq %gs:0, %rax // restore rax
push %gs:8
push %rcx
push %r11
push %rax
push %rbp
push %rbx
push %r12
push %r13
push %r14
push %r15
push %r9
push %r8
push %r10
push %rdx
push %rsi
push %rdi
mov %rsp, %rdi # frame in arg1
call syscall
# fall through to sysexit
.globl sysexit
sysexit:
# to make sure we don't get any interrupts on the user stack while in
# supervisor mode. insufficient? (see vunerability reports for sysret)
cli
pop %rdi
pop %rsi
pop %rdx
pop %r10
pop %r8
pop %r9
pop %r15
pop %r14
pop %r13
pop %r12
pop %rbx
pop %rbp
pop %rax
pop %r11
pop %rcx
mov (%rsp),%rsp # switch to the user stack
# there are two more values on the stack, but we don't care about them
swapgs
sysretq

7
ulib.c
View file

@ -2,7 +2,6 @@
#include "stat.h" #include "stat.h"
#include "fcntl.h" #include "fcntl.h"
#include "user.h" #include "user.h"
#include "x86.h"
char* char*
strcpy(char *s, const char *t) strcpy(char *s, const char *t)
@ -36,7 +35,11 @@ strlen(const char *s)
void* void*
memset(void *dst, int c, uint n) memset(void *dst, int c, uint n)
{ {
stosb(dst, c, n); char *cdst = (char *) dst;
int i;
for(i = 0; i < n; i++){
cdst[i] = c;
}
return dst; return dst;
} }

View file

@ -5,7 +5,6 @@
#include "fs.h" #include "fs.h"
#include "fcntl.h" #include "fcntl.h"
#include "syscall.h" #include "syscall.h"
#include "traps.h"
#include "memlayout.h" #include "memlayout.h"
char buf[8192]; char buf[8192];
@ -1713,35 +1712,6 @@ fsfull()
printf(1, "fsfull test finished\n"); printf(1, "fsfull test finished\n");
} }
void
uio()
{
#define RTC_ADDR 0x70
#define RTC_DATA 0x71
ushort port = 0;
uchar val = 0;
int pid;
printf(1, "uio test\n");
pid = fork();
if(pid == 0){
port = RTC_ADDR;
val = 0x09; /* year */
/* http://wiki.osdev.org/Inline_Assembly/Examples */
asm volatile("outb %0,%1"::"a"(val), "d" (port));
port = RTC_DATA;
asm volatile("inb %1,%0" : "=a" (val) : "d" (port));
printf(1, "uio: uio succeeded; test FAILED\n");
exit();
} else if(pid < 0){
printf (1, "fork failed\n");
exit();
}
wait();
printf(1, "uio test done\n");
}
void argptest() void argptest()
{ {
int fd; int fd;
@ -1813,8 +1783,6 @@ main(int argc, char *argv[])
forktest(); forktest();
bigdir(); // slow bigdir(); // slow
uio();
exectest(); exectest();
exit(); exit();

31
usys.S
View file

@ -1,31 +0,0 @@
#include "syscall.h"
#include "traps.h"
#define SYSCALL(name) \
.globl name; \
name: \
mov $SYS_ ## name, %rax; \
syscall; \
ret
SYSCALL(fork)
SYSCALL(exit)
SYSCALL(wait)
SYSCALL(pipe)
SYSCALL(read)
SYSCALL(write)
SYSCALL(close)
SYSCALL(kill)
SYSCALL(exec)
SYSCALL(open)
SYSCALL(mknod)
SYSCALL(unlink)
SYSCALL(fstat)
SYSCALL(link)
SYSCALL(mkdir)
SYSCALL(chdir)
SYSCALL(dup)
SYSCALL(getpid)
SYSCALL(sbrk)
SYSCALL(sleep)
SYSCALL(uptime)

38
usys.pl Executable file
View file

@ -0,0 +1,38 @@
#!/usr/bin/perl -w
# Generate usys.S, the stubs for syscalls.
print "# generated by usys.pl - do not edit\n";
print "#include \"syscall.h\"\n";
sub entry {
my $name = shift;
print ".global $name\n";
print "${name}:\n";
print " li a7, SYS_${name}\n";
print " ecall\n";
print " ret\n";
}
entry("fork");
entry("exit");
entry("wait");
entry("pipe");
entry("read");
entry("write");
entry("close");
entry("kill");
entry("exec");
entry("open");
entry("mknod");
entry("unlink");
entry("fstat");
entry("link");
entry("mkdir");
entry("chdir");
entry("dup");
entry("getpid");
entry("sbrk");
entry("sleep");
entry("uptime");

5
vm.c
View file

@ -4,6 +4,7 @@
#include "elf.h" #include "elf.h"
#include "riscv.h" #include "riscv.h"
#include "defs.h" #include "defs.h"
#include "fs.h"
/* /*
* the kernel's page table. * the kernel's page table.
@ -37,6 +38,10 @@ kvminit()
mappages(kernel_pagetable, (uint64)etext, PHYSTOP-(uint64)etext, mappages(kernel_pagetable, (uint64)etext, PHYSTOP-(uint64)etext,
(uint64)etext, PTE_R | PTE_W); (uint64)etext, PTE_R | PTE_W);
// map the qemu -initrd fs.img ramdisk
mappages(kernel_pagetable, RAMDISK, FSSIZE * BSIZE,
RAMDISK, PTE_R | PTE_W);
// map the trampoline for trap entry/exit to // map the trampoline for trap entry/exit to
// the highest virtual address in the kernel. // the highest virtual address in the kernel.
mappages(kernel_pagetable, TRAMPOLINE, PGSIZE, mappages(kernel_pagetable, TRAMPOLINE, PGSIZE,