[Update] xv6-la init
This commit is contained in:
7
Makefile
7
Makefile
@@ -1,5 +1,6 @@
|
|||||||
default:
|
default:
|
||||||
@echo "Hello World!"
|
@echo "Hello World!"
|
||||||
|
@echo $(CURDIR)
|
||||||
|
|
||||||
submodue-update-init:
|
submodue-update-init:
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
@@ -27,3 +28,9 @@ $(LA_TOOLS): unpk-gcc
|
|||||||
|
|
||||||
# prepare loongarch source code
|
# prepare loongarch source code
|
||||||
|
|
||||||
|
xv6:
|
||||||
|
TOOLPREFIX=$(CURDIR)/$(LA) $(MAKE) -C lasoft/xv6-la build
|
||||||
|
|
||||||
|
xv6-clean:
|
||||||
|
$(MAKE) -C lasoft/xv6-la clean
|
||||||
|
|
||||||
|
|||||||
1
lasoft/xv6-la/.gitignore
vendored
1
lasoft/xv6-la/.gitignore
vendored
@@ -11,7 +11,6 @@ entryother
|
|||||||
initcode
|
initcode
|
||||||
initcode.out
|
initcode.out
|
||||||
kernelmemfs
|
kernelmemfs
|
||||||
mkfs
|
|
||||||
kernel/kernel
|
kernel/kernel
|
||||||
user/usys.S
|
user/usys.S
|
||||||
.gdbinit
|
.gdbinit
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ QEMUOPTS += -global virtio-mmio.force-legacy=false
|
|||||||
QEMUOPTS += -drive file=fs.img,if=none,format=raw,id=x0
|
QEMUOPTS += -drive file=fs.img,if=none,format=raw,id=x0
|
||||||
QEMUOPTS += -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
|
QEMUOPTS += -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
|
||||||
|
|
||||||
|
build: $K/kernel fs.img
|
||||||
|
|
||||||
qemu: $K/kernel fs.img
|
qemu: $K/kernel fs.img
|
||||||
$(QEMU) $(QEMUOPTS)
|
$(QEMU) $(QEMUOPTS)
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +1,21 @@
|
|||||||
xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix
|
# vscode config
|
||||||
Version 6 (v6). xv6 loosely follows the structure and style of v6,
|
|
||||||
but is implemented for a modern RISC-V multiprocessor using ANSI C.
|
|
||||||
|
|
||||||
ACKNOWLEDGMENTS
|
``` json
|
||||||
|
// c_cpp_properties
|
||||||
xv6 is inspired by John Lions's Commentary on UNIX 6th Edition (Peer
|
{
|
||||||
to Peer Communications; ISBN: 1-57398-013-7; 1st edition (June 14,
|
"configurations": [
|
||||||
2000)). See also https://pdos.csail.mit.edu/6.1810/, which provides
|
{
|
||||||
pointers to on-line resources for v6.
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
The following people have made contributions: Russ Cox (context switching,
|
"${workspaceFolder}/**",
|
||||||
locking), Cliff Frey (MP), Xiao Yu (MP), Nickolai Zeldovich, and Austin
|
"${workspaceFolder}/../../ext/toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18/lib/gcc/loongarch64-linux-gnu/8.3.0/include"
|
||||||
Clements.
|
],
|
||||||
|
"defines": [],
|
||||||
We are also grateful for the bug reports and patches contributed by
|
"compilerPath": "${workspaceFolder}/../../ext/toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18/bin/loongarch64-linux-gnu-gcc",
|
||||||
Takahiro Aoyagi, Silas Boyd-Wickizer, Anton Burtsev, carlclone, Ian
|
"cStandard": "c99",
|
||||||
Chen, Dan Cross, Cody Cutler, Mike CAT, Tej Chajed, Asami Doi,
|
"intelliSenseMode": "linux-gcc-x64"
|
||||||
eyalz800, Nelson Elhage, Saar Ettinger, Alice Ferrazzi, Nathaniel
|
}
|
||||||
Filardo, flespark, Peter Froehlich, Yakir Goaron, Shivam Handa, Matt
|
],
|
||||||
Harvey, Bryan Henry, jaichenhengjie, Jim Huang, Matúš Jókay, John
|
"version": 4
|
||||||
Jolly, Alexander Kapshuk, Anders Kaseorg, kehao95, Wolfgang Keller,
|
}
|
||||||
Jungwoo Kim, Jonathan Kimmitt, Eddie Kohler, Vadim Kolontsov, Austin
|
```
|
||||||
Liew, l0stman, Pavan Maddamsetti, Imbar Marinescu, Yandong Mao, Matan
|
|
||||||
Shabtay, Hitoshi Mitake, Carmi Merimovich, Mark Morrissey, mtasm, Joel
|
|
||||||
Nider, Hayato Ohhashi, OptimisticSide, Harry Porter, Greg Price, Jude
|
|
||||||
Rich, segfault, Ayan Shafqat, Eldar Sehayek, Yongming Shen, Fumiya
|
|
||||||
Shigemitsu, Cam Tenny, tyfkda, Warren Toomey, Stephen Tu, Rafael Ubal,
|
|
||||||
Amane Uehara, Pablo Ventura, Xi Wang, WaheedHafez, Keiichi Watanabe,
|
|
||||||
Nicolas Wolovick, wxdao, Grant Wu, Jindong Zhang, Icenowy Zheng,
|
|
||||||
ZhUyU1997, and Zou Chang Wei.
|
|
||||||
|
|
||||||
|
|
||||||
The code in the files that constitute xv6 is
|
|
||||||
Copyright 2006-2022 Frans Kaashoek, Robert Morris, and Russ Cox.
|
|
||||||
|
|
||||||
ERROR REPORTS
|
|
||||||
|
|
||||||
Please send errors and suggestions to Frans Kaashoek and Robert Morris
|
|
||||||
(kaashoek,rtm@mit.edu). The main purpose of xv6 is as a teaching
|
|
||||||
operating system for MIT's 6.1810, so we are more interested in
|
|
||||||
simplifications and clarifications than new features.
|
|
||||||
|
|
||||||
BUILDING AND RUNNING XV6
|
|
||||||
|
|
||||||
You will need a RISC-V "newlib" tool chain from
|
|
||||||
https://github.com/riscv/riscv-gnu-toolchain, and qemu compiled for
|
|
||||||
riscv64-softmmu. Once they are installed, and in your shell
|
|
||||||
search path, you can run "make qemu".
|
|
||||||
|
|||||||
301
lasoft/xv6-la/mkfs/mkfs.c
Normal file
301
lasoft/xv6-la/mkfs/mkfs.c
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define stat xv6_stat // avoid clash with host struct stat
|
||||||
|
#include "kernel/types.h"
|
||||||
|
#include "kernel/fs.h"
|
||||||
|
#include "kernel/stat.h"
|
||||||
|
#include "kernel/param.h"
|
||||||
|
|
||||||
|
#ifndef static_assert
|
||||||
|
#define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NINODES 200
|
||||||
|
|
||||||
|
// Disk layout:
|
||||||
|
// [ boot block | sb block | log | inode blocks | free bit map | data blocks ]
|
||||||
|
|
||||||
|
int nbitmap = FSSIZE/(BSIZE*8) + 1;
|
||||||
|
int ninodeblocks = NINODES / IPB + 1;
|
||||||
|
int nlog = LOGSIZE;
|
||||||
|
int nmeta; // Number of meta blocks (boot, sb, nlog, inode, bitmap)
|
||||||
|
int nblocks; // Number of data blocks
|
||||||
|
|
||||||
|
int fsfd;
|
||||||
|
struct superblock sb;
|
||||||
|
char zeroes[BSIZE];
|
||||||
|
uint freeinode = 1;
|
||||||
|
uint freeblock;
|
||||||
|
|
||||||
|
|
||||||
|
void balloc(int);
|
||||||
|
void wsect(uint, void*);
|
||||||
|
void winode(uint, struct dinode*);
|
||||||
|
void rinode(uint inum, struct dinode *ip);
|
||||||
|
void rsect(uint sec, void *buf);
|
||||||
|
uint ialloc(ushort type);
|
||||||
|
void iappend(uint inum, void *p, int n);
|
||||||
|
void die(const char *);
|
||||||
|
|
||||||
|
// convert to riscv byte order
|
||||||
|
ushort
|
||||||
|
xshort(ushort x)
|
||||||
|
{
|
||||||
|
ushort y;
|
||||||
|
uchar *a = (uchar*)&y;
|
||||||
|
a[0] = x;
|
||||||
|
a[1] = x >> 8;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
xint(uint x)
|
||||||
|
{
|
||||||
|
uint y;
|
||||||
|
uchar *a = (uchar*)&y;
|
||||||
|
a[0] = x;
|
||||||
|
a[1] = x >> 8;
|
||||||
|
a[2] = x >> 16;
|
||||||
|
a[3] = x >> 24;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i, cc, fd;
|
||||||
|
uint rootino, inum, off;
|
||||||
|
struct dirent de;
|
||||||
|
char buf[BSIZE];
|
||||||
|
struct dinode din;
|
||||||
|
|
||||||
|
|
||||||
|
static_assert(sizeof(int) == 4, "Integers must be 4 bytes!");
|
||||||
|
|
||||||
|
if(argc < 2){
|
||||||
|
fprintf(stderr, "Usage: mkfs fs.img files...\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert((BSIZE % sizeof(struct dinode)) == 0);
|
||||||
|
assert((BSIZE % sizeof(struct dirent)) == 0);
|
||||||
|
|
||||||
|
fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);
|
||||||
|
if(fsfd < 0)
|
||||||
|
die(argv[1]);
|
||||||
|
|
||||||
|
// 1 fs block = 1 disk sector
|
||||||
|
nmeta = 2 + nlog + ninodeblocks + nbitmap;
|
||||||
|
nblocks = FSSIZE - nmeta;
|
||||||
|
|
||||||
|
sb.magic = FSMAGIC;
|
||||||
|
sb.size = xint(FSSIZE);
|
||||||
|
sb.nblocks = xint(nblocks);
|
||||||
|
sb.ninodes = xint(NINODES);
|
||||||
|
sb.nlog = xint(nlog);
|
||||||
|
sb.logstart = xint(2);
|
||||||
|
sb.inodestart = xint(2+nlog);
|
||||||
|
sb.bmapstart = xint(2+nlog+ninodeblocks);
|
||||||
|
|
||||||
|
printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n",
|
||||||
|
nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE);
|
||||||
|
|
||||||
|
freeblock = nmeta; // the first free block that we can allocate
|
||||||
|
|
||||||
|
for(i = 0; i < FSSIZE; i++)
|
||||||
|
wsect(i, zeroes);
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
memmove(buf, &sb, sizeof(sb));
|
||||||
|
wsect(1, buf);
|
||||||
|
|
||||||
|
rootino = ialloc(T_DIR);
|
||||||
|
assert(rootino == ROOTINO);
|
||||||
|
|
||||||
|
bzero(&de, sizeof(de));
|
||||||
|
de.inum = xshort(rootino);
|
||||||
|
strcpy(de.name, ".");
|
||||||
|
iappend(rootino, &de, sizeof(de));
|
||||||
|
|
||||||
|
bzero(&de, sizeof(de));
|
||||||
|
de.inum = xshort(rootino);
|
||||||
|
strcpy(de.name, "..");
|
||||||
|
iappend(rootino, &de, sizeof(de));
|
||||||
|
|
||||||
|
for(i = 2; i < argc; i++){
|
||||||
|
// get rid of "user/"
|
||||||
|
char *shortname;
|
||||||
|
if(strncmp(argv[i], "user/", 5) == 0)
|
||||||
|
shortname = argv[i] + 5;
|
||||||
|
else
|
||||||
|
shortname = argv[i];
|
||||||
|
|
||||||
|
assert(index(shortname, '/') == 0);
|
||||||
|
|
||||||
|
if((fd = open(argv[i], 0)) < 0)
|
||||||
|
die(argv[i]);
|
||||||
|
|
||||||
|
// Skip leading _ in name when writing to file system.
|
||||||
|
// The binaries are named _rm, _cat, etc. to keep the
|
||||||
|
// build operating system from trying to execute them
|
||||||
|
// in place of system binaries like rm and cat.
|
||||||
|
if(shortname[0] == '_')
|
||||||
|
shortname += 1;
|
||||||
|
|
||||||
|
inum = ialloc(T_FILE);
|
||||||
|
|
||||||
|
bzero(&de, sizeof(de));
|
||||||
|
de.inum = xshort(inum);
|
||||||
|
strncpy(de.name, shortname, DIRSIZ);
|
||||||
|
iappend(rootino, &de, sizeof(de));
|
||||||
|
|
||||||
|
while((cc = read(fd, buf, sizeof(buf))) > 0)
|
||||||
|
iappend(inum, buf, cc);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix size of root inode dir
|
||||||
|
rinode(rootino, &din);
|
||||||
|
off = xint(din.size);
|
||||||
|
off = ((off/BSIZE) + 1) * BSIZE;
|
||||||
|
din.size = xint(off);
|
||||||
|
winode(rootino, &din);
|
||||||
|
|
||||||
|
balloc(freeblock);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wsect(uint sec, void *buf)
|
||||||
|
{
|
||||||
|
if(lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE)
|
||||||
|
die("lseek");
|
||||||
|
if(write(fsfd, buf, BSIZE) != BSIZE)
|
||||||
|
die("write");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
winode(uint inum, struct dinode *ip)
|
||||||
|
{
|
||||||
|
char buf[BSIZE];
|
||||||
|
uint bn;
|
||||||
|
struct dinode *dip;
|
||||||
|
|
||||||
|
bn = IBLOCK(inum, sb);
|
||||||
|
rsect(bn, buf);
|
||||||
|
dip = ((struct dinode*)buf) + (inum % IPB);
|
||||||
|
*dip = *ip;
|
||||||
|
wsect(bn, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rinode(uint inum, struct dinode *ip)
|
||||||
|
{
|
||||||
|
char buf[BSIZE];
|
||||||
|
uint bn;
|
||||||
|
struct dinode *dip;
|
||||||
|
|
||||||
|
bn = IBLOCK(inum, sb);
|
||||||
|
rsect(bn, buf);
|
||||||
|
dip = ((struct dinode*)buf) + (inum % IPB);
|
||||||
|
*ip = *dip;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rsect(uint sec, void *buf)
|
||||||
|
{
|
||||||
|
if(lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE)
|
||||||
|
die("lseek");
|
||||||
|
if(read(fsfd, buf, BSIZE) != BSIZE)
|
||||||
|
die("read");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
ialloc(ushort type)
|
||||||
|
{
|
||||||
|
uint inum = freeinode++;
|
||||||
|
struct dinode din;
|
||||||
|
|
||||||
|
bzero(&din, sizeof(din));
|
||||||
|
din.type = xshort(type);
|
||||||
|
din.nlink = xshort(1);
|
||||||
|
din.size = xint(0);
|
||||||
|
winode(inum, &din);
|
||||||
|
return inum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
balloc(int used)
|
||||||
|
{
|
||||||
|
uchar buf[BSIZE];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("balloc: first %d blocks have been allocated\n", used);
|
||||||
|
assert(used < BSIZE*8);
|
||||||
|
bzero(buf, BSIZE);
|
||||||
|
for(i = 0; i < used; i++){
|
||||||
|
buf[i/8] = buf[i/8] | (0x1 << (i%8));
|
||||||
|
}
|
||||||
|
printf("balloc: write bitmap block at sector %d\n", sb.bmapstart);
|
||||||
|
wsect(sb.bmapstart, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
void
|
||||||
|
iappend(uint inum, void *xp, int n)
|
||||||
|
{
|
||||||
|
char *p = (char*)xp;
|
||||||
|
uint fbn, off, n1;
|
||||||
|
struct dinode din;
|
||||||
|
char buf[BSIZE];
|
||||||
|
uint indirect[NINDIRECT];
|
||||||
|
uint x;
|
||||||
|
|
||||||
|
rinode(inum, &din);
|
||||||
|
off = xint(din.size);
|
||||||
|
// printf("append inum %d at off %d sz %d\n", inum, off, n);
|
||||||
|
while(n > 0){
|
||||||
|
fbn = off / BSIZE;
|
||||||
|
assert(fbn < MAXFILE);
|
||||||
|
if(fbn < NDIRECT){
|
||||||
|
if(xint(din.addrs[fbn]) == 0){
|
||||||
|
din.addrs[fbn] = xint(freeblock++);
|
||||||
|
}
|
||||||
|
x = xint(din.addrs[fbn]);
|
||||||
|
} else {
|
||||||
|
if(xint(din.addrs[NDIRECT]) == 0){
|
||||||
|
din.addrs[NDIRECT] = xint(freeblock++);
|
||||||
|
}
|
||||||
|
rsect(xint(din.addrs[NDIRECT]), (char*)indirect);
|
||||||
|
if(indirect[fbn - NDIRECT] == 0){
|
||||||
|
indirect[fbn - NDIRECT] = xint(freeblock++);
|
||||||
|
wsect(xint(din.addrs[NDIRECT]), (char*)indirect);
|
||||||
|
}
|
||||||
|
x = xint(indirect[fbn-NDIRECT]);
|
||||||
|
}
|
||||||
|
n1 = min(n, (fbn + 1) * BSIZE - off);
|
||||||
|
rsect(x, buf);
|
||||||
|
bcopy(p, buf + off - (fbn * BSIZE), n1);
|
||||||
|
wsect(x, buf);
|
||||||
|
n -= n1;
|
||||||
|
off += n1;
|
||||||
|
p += n1;
|
||||||
|
}
|
||||||
|
din.size = xint(off);
|
||||||
|
winode(inum, &din);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
die(const char *s)
|
||||||
|
{
|
||||||
|
perror(s);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user