-initrd fs.img, ramdisk.c, file system
This commit is contained in:
parent
2ec1959fd1
commit
5d34fa2a48
20
Makefile
20
Makefile
|
@ -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
7
bio.c
|
@ -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
8
defs.h
|
@ -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
1
file.c
|
@ -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
4
fs.c
|
@ -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
168
ide.c
|
@ -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);
|
|
||||||
}
|
|
2
kalloc.c
2
kalloc.c
|
@ -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
1
log.c
|
@ -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
4
main.c
|
@ -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();
|
||||||
|
|
|
@ -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
2
pipe.c
|
@ -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
27
proc.c
|
@ -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
45
ramdisk.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
132
trapasm.S
|
@ -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
7
ulib.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
usertests.c
32
usertests.c
|
@ -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
31
usys.S
|
@ -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
38
usys.pl
Executable 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
5
vm.c
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue