-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 \
|
||||
trap.o \
|
||||
syscall.o \
|
||||
sysproc.o
|
||||
sysproc.o \
|
||||
bio.o \
|
||||
fs.o \
|
||||
log.o \
|
||||
sleeplock.o \
|
||||
file.o \
|
||||
pipe.o \
|
||||
ramdisk.o
|
||||
|
||||
XXXOBJS = \
|
||||
bio.o\
|
||||
|
@ -83,15 +90,15 @@ endif
|
|||
|
||||
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)
|
||||
$(OBJDUMP) -S kernel > kernel.asm
|
||||
$(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym
|
||||
|
||||
initcode: initcode.S
|
||||
$(CC) $(CFLAGS) -nostdinc -I. -c initcode.S
|
||||
#$(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o
|
||||
#$(OBJCOPY) -S -O binary initcode.out initcode
|
||||
$(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o
|
||||
$(OBJCOPY) -S -O binary initcode.out initcode
|
||||
$(OBJDUMP) -S initcode.o > initcode.asm
|
||||
|
||||
tags: $(OBJS) entryother.S _init
|
||||
|
@ -107,6 +114,9 @@ _%: %.o $(ULIB)
|
|||
$(OBJDUMP) -S $@ > $*.asm
|
||||
$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
|
||||
|
||||
usys.S : usys.pl
|
||||
perl ./usys.pl > usys.S
|
||||
|
||||
_forktest: forktest.o $(ULIB)
|
||||
# forktest has less library code linked in - needs to be small
|
||||
# in order to be able to max out the proc table.
|
||||
|
@ -171,7 +181,7 @@ ifndef CPUS
|
|||
CPUS := 1
|
||||
endif
|
||||
QEMUOPTS = -machine virt -kernel kernel -m 3G -smp $(CPUS) -nographic
|
||||
#QEMUOPTS += -initrd fs.img
|
||||
QEMUOPTS += -initrd fs.img
|
||||
|
||||
qemu: kernel
|
||||
$(QEMU) $(QEMUOPTS)
|
||||
|
|
7
bio.c
7
bio.c
|
@ -19,10 +19,11 @@
|
|||
// and needs to be written to disk.
|
||||
|
||||
#include "types.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "spinlock.h"
|
||||
#include "sleeplock.h"
|
||||
#include "riscv.h"
|
||||
#include "defs.h"
|
||||
#include "fs.h"
|
||||
#include "buf.h"
|
||||
|
||||
|
@ -100,7 +101,7 @@ bread(uint dev, uint blockno)
|
|||
|
||||
b = bget(dev, blockno);
|
||||
if((b->flags & B_VALID) == 0) {
|
||||
iderw(b);
|
||||
ramdiskrw(b);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
@ -112,7 +113,7 @@ bwrite(struct buf *b)
|
|||
if(!holdingsleep(&b->lock))
|
||||
panic("bwrite");
|
||||
b->flags |= B_DIRTY;
|
||||
iderw(b);
|
||||
ramdiskrw(b);
|
||||
}
|
||||
|
||||
// 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*);
|
||||
int writei(struct inode*, char*, uint, uint);
|
||||
|
||||
// ide.c
|
||||
void ideinit(void);
|
||||
void ideintr(void);
|
||||
void iderw(struct buf*);
|
||||
// ramdisk.c
|
||||
void ramdiskinit(void);
|
||||
void ramdiskintr(void);
|
||||
void ramdiskrw(struct buf*);
|
||||
|
||||
// ioapic.c
|
||||
void ioapicenable(int irq, int cpu);
|
||||
|
|
1
file.c
1
file.c
|
@ -3,6 +3,7 @@
|
|||
//
|
||||
|
||||
#include "types.h"
|
||||
#include "riscv.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "fs.h"
|
||||
|
|
4
fs.c
4
fs.c
|
@ -10,10 +10,10 @@
|
|||
// are in sysfile.c.
|
||||
|
||||
#include "types.h"
|
||||
#include "riscv.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "stat.h"
|
||||
#include "mmu.h"
|
||||
#include "proc.h"
|
||||
#include "spinlock.h"
|
||||
#include "sleeplock.h"
|
||||
|
@ -180,7 +180,7 @@ iinit(int dev)
|
|||
}
|
||||
|
||||
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,
|
||||
sb.ninodes, sb.nlog, sb.logstart, sb.inodestart,
|
||||
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()
|
||||
{
|
||||
initlock(&kmem.lock, "kmem");
|
||||
if(PHYSTOP > RAMDISK)
|
||||
panic("kinit");
|
||||
freerange(end, (void*)PHYSTOP);
|
||||
}
|
||||
|
||||
|
|
1
log.c
1
log.c
|
@ -1,4 +1,5 @@
|
|||
#include "types.h"
|
||||
#include "riscv.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "spinlock.h"
|
||||
|
|
4
main.c
4
main.c
|
@ -17,11 +17,9 @@ main()
|
|||
kvminit(); // kernel page table
|
||||
procinit(); // process table
|
||||
trapinit(); // trap vectors
|
||||
#if 0
|
||||
binit(); // buffer cache
|
||||
fileinit(); // file table
|
||||
ideinit(); // disk
|
||||
#endif
|
||||
ramdiskinit(); // disk
|
||||
userinit(); // first user process
|
||||
|
||||
scheduler();
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
// 00001000 -- boot ROM, provided by qemu
|
||||
// 10000000 -- uart0 registers
|
||||
// 80000000 -- boot ROM jumps here in machine mode
|
||||
// -kernel loads the kernel here
|
||||
// 88000000 -- -initrd fs.img ramdisk image.
|
||||
// unused RAM after 80000000.
|
||||
|
||||
// the kernel uses physical memory thus:
|
||||
|
@ -14,6 +16,8 @@
|
|||
// registers start here in physical memory.
|
||||
#define UART0 0x10000000L
|
||||
|
||||
#define RAMDISK 0x88000000
|
||||
|
||||
// the kernel expects there to be RAM
|
||||
// for use by the kernel and user pages
|
||||
// from physical address 0x80000000 to PHYSTOP.
|
||||
|
|
2
pipe.c
2
pipe.c
|
@ -1,7 +1,7 @@
|
|||
#include "types.h"
|
||||
#include "riscv.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "mmu.h"
|
||||
#include "proc.h"
|
||||
#include "fs.h"
|
||||
#include "spinlock.h"
|
||||
|
|
27
proc.c
27
proc.c
|
@ -116,16 +116,13 @@ found:
|
|||
return p;
|
||||
}
|
||||
|
||||
// XXX hack because I don't know how to incorporate initcode
|
||||
// into the kernel binary. just the exec system call, no arguments.
|
||||
// manually copied from initcode.asm.
|
||||
// a user program that calls exec("/init")
|
||||
// od -t xC initcode
|
||||
unsigned char initcode[] = {
|
||||
0x85, 0x48, // li a7, 1 -- SYS_fork
|
||||
0x73, 0x00, 0x00, 0x00, // ecall
|
||||
0x8d, 0x48, // li a7, 3 -- SYS_wait
|
||||
0x73, 0x00, 0x00, 0x00, // ecall
|
||||
0x89, 0x48, // li a7, 2 -- SYS_exit
|
||||
0x73, 0x00, 0x00, 0x00, // ecall
|
||||
0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x05, 0x02, 0x97, 0x05, 0x00, 0x00, 0x93, 0x85, 0x05, 0x02,
|
||||
0x9d, 0x48, 0x73, 0x00, 0x00, 0x00, 0x89, 0x48, 0x73, 0x00, 0x00, 0x00, 0xef, 0xf0, 0xbf, 0xff,
|
||||
0x2f, 0x69, 0x6e, 0x69, 0x74, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
//PAGEBREAK: 32
|
||||
|
@ -146,8 +143,7 @@ userinit(void)
|
|||
p->tf->sp = PGSIZE;
|
||||
|
||||
safestrcpy(p->name, "initcode", sizeof(p->name));
|
||||
// XXX riscv
|
||||
//p->cwd = namei("/");
|
||||
p->cwd = namei("/");
|
||||
|
||||
// this assignment to p->state lets other cores
|
||||
// run this process. the acquire forces the above
|
||||
|
@ -210,13 +206,11 @@ fork(void)
|
|||
// Cause fork to return 0 in the child.
|
||||
np->tf->a0 = 0;
|
||||
|
||||
#if 0 // XXX riscv
|
||||
// increment reference counts on open file descriptors.
|
||||
for(i = 0; i < NOFILE; i++)
|
||||
if(p->ofile[i])
|
||||
np->ofile[i] = filedup(p->ofile[i]);
|
||||
np->cwd = idup(p->cwd);
|
||||
#endif
|
||||
|
||||
safestrcpy(np->name, p->name, sizeof(p->name));
|
||||
|
||||
|
@ -244,7 +238,6 @@ exit(void)
|
|||
if(p == initproc)
|
||||
panic("init exiting");
|
||||
|
||||
#if 0 // XXX riscv
|
||||
// Close all open files.
|
||||
for(fd = 0; fd < NOFILE; fd++){
|
||||
if(p->ofile[fd]){
|
||||
|
@ -256,7 +249,6 @@ exit(void)
|
|||
begin_op();
|
||||
iput(p->cwd);
|
||||
end_op();
|
||||
#endif
|
||||
p->cwd = 0;
|
||||
|
||||
acquire(&ptable.lock);
|
||||
|
@ -423,9 +415,8 @@ forkret(void)
|
|||
// of a regular process (e.g., they call sleep), and thus cannot
|
||||
// be run from main().
|
||||
first = 0;
|
||||
// XXX riscv
|
||||
//iinit(ROOTDEV);
|
||||
//initlog(ROOTDEV);
|
||||
iinit(ROOTDEV);
|
||||
initlog(ROOTDEV);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#include "types.h"
|
||||
#include "riscv.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "x86.h"
|
||||
#include "memlayout.h"
|
||||
#include "mmu.h"
|
||||
#include "proc.h"
|
||||
#include "spinlock.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 "fcntl.h"
|
||||
#include "user.h"
|
||||
#include "x86.h"
|
||||
|
||||
char*
|
||||
strcpy(char *s, const char *t)
|
||||
|
@ -36,7 +35,11 @@ strlen(const char *s)
|
|||
void*
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
32
usertests.c
32
usertests.c
|
@ -5,7 +5,6 @@
|
|||
#include "fs.h"
|
||||
#include "fcntl.h"
|
||||
#include "syscall.h"
|
||||
#include "traps.h"
|
||||
#include "memlayout.h"
|
||||
|
||||
char buf[8192];
|
||||
|
@ -1713,35 +1712,6 @@ fsfull()
|
|||
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()
|
||||
{
|
||||
int fd;
|
||||
|
@ -1813,8 +1783,6 @@ main(int argc, char *argv[])
|
|||
forktest();
|
||||
bigdir(); // slow
|
||||
|
||||
uio();
|
||||
|
||||
exectest();
|
||||
|
||||
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 "riscv.h"
|
||||
#include "defs.h"
|
||||
#include "fs.h"
|
||||
|
||||
/*
|
||||
* the kernel's page table.
|
||||
|
@ -37,6 +38,10 @@ kvminit()
|
|||
mappages(kernel_pagetable, (uint64)etext, PHYSTOP-(uint64)etext,
|
||||
(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
|
||||
// the highest virtual address in the kernel.
|
||||
mappages(kernel_pagetable, TRAMPOLINE, PGSIZE,
|
||||
|
|
Loading…
Reference in a new issue