From ffcd9fbbabf6b5166169c544237779f645bce84e Mon Sep 17 00:00:00 2001 From: tracer-ics2023 Date: Tue, 24 Sep 2024 12:26:53 +0800 Subject: [PATCH] =?UTF-8?q?>=20=20compile=20NEMU=20221220000=20=E5=BC=A0?= =?UTF-8?q?=E4=B8=89=20Linux=20zzy=205.15.146.1-microsoft-standard-WSL2=20?= =?UTF-8?q?#1=20SMP=20Thu=20Jan=2011=2004:09:03=20UTC=202024=20x86=5F64=20?= =?UTF-8?q?x86=5F64=20x86=5F64=20GNU/Linux=20=2012:26:49=20up=206=20days,?= =?UTF-8?q?=2021:24,=20=201=20user,=20=20load=20average:=200.72,=200.73,?= =?UTF-8?q?=200.62?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nanos-lite/Makefile | 2 +- nanos-lite/include/fs.h | 6 +++ nanos-lite/include/ramdisk.h | 15 ++++++ nanos-lite/include/syscall.h | 41 +++++++++++++++ nanos-lite/src/fs.c | 81 ++++++++++++++++++++++++++++- nanos-lite/src/loader.c | 12 +++-- nanos-lite/src/proc.c | 2 +- nanos-lite/src/syscall.c | 21 ++++---- navy-apps/Makefile | 4 +- navy-apps/libs/compiler-rt/Makefile | 2 +- navy-apps/libs/libos/src/syscall.c | 12 ++--- 11 files changed, 167 insertions(+), 31 deletions(-) create mode 100644 nanos-lite/include/ramdisk.h create mode 100644 nanos-lite/include/syscall.h diff --git a/nanos-lite/Makefile b/nanos-lite/Makefile index 64e02b0..f15fb30 100644 --- a/nanos-lite/Makefile +++ b/nanos-lite/Makefile @@ -1,4 +1,4 @@ -#HAS_NAVY = 1 +HAS_NAVY = 1 RAMDISK_FILE = build/ramdisk.img NAME = nanos-lite diff --git a/nanos-lite/include/fs.h b/nanos-lite/include/fs.h index 8fc94a2..9084aa8 100644 --- a/nanos-lite/include/fs.h +++ b/nanos-lite/include/fs.h @@ -7,4 +7,10 @@ enum {SEEK_SET, SEEK_CUR, SEEK_END}; #endif +int _fs_open(const char *pathname, int flags, int mode); +size_t _fs_read(int fd, void *buf, size_t len); +size_t _fs_write(int fd, const void *buf, size_t len); +size_t _fs_lseek(int fd, size_t offset, int whence); +int _fs_close(int fd); + #endif diff --git a/nanos-lite/include/ramdisk.h b/nanos-lite/include/ramdisk.h new file mode 100644 index 0000000..07ba40d --- /dev/null +++ b/nanos-lite/include/ramdisk.h @@ -0,0 +1,15 @@ +#ifndef __RAMDISK_H__ +#define __RAMDISK_H__ + +#include + +size_t ramdisk_read(void *buf, size_t offset, size_t len); + +/* write `len` bytes starting from `buf` into the `offset` of ramdisk */ +size_t ramdisk_write(const void *buf, size_t offset, size_t len); + +void init_ramdisk(); + +size_t get_ramdisk_size(); + +#endif diff --git a/nanos-lite/include/syscall.h b/nanos-lite/include/syscall.h new file mode 100644 index 0000000..22de6ab --- /dev/null +++ b/nanos-lite/include/syscall.h @@ -0,0 +1,41 @@ +#ifndef __NANOS_SYSCALL_H__ +#define __NANOS_SYSCALL_H__ + +#define SYSCALLS(_) \ + _(exit) \ + _(yield) \ + _(open) \ + _(read) \ + _(write) \ + _(kill) \ + _(getpid) \ + _(close) \ + _(lseek) \ + _(brk) \ + _(fstat) \ + _(time) \ + _(signal) \ + _(execve) \ + _(fork) \ + _(link) \ + _(unlink) \ + _(wait) \ + _(times) \ + _(gettimeofday) + +#define _SYSCALL_NAME(name) SYS_##name +#define SYSCALL_NAME(name) _SYSCALL_NAME(name), +#define SYSCALL_NAME_STR(name) #name, + +#ifndef __SYSCALL_H__ +#define __SYSCALL_H__ +enum { + SYSCALLS(SYSCALL_NAME) +}; +#endif + +const char __syscall_names[][32] = { + SYSCALLS(SYSCALL_NAME_STR) +}; + +#endif \ No newline at end of file diff --git a/nanos-lite/src/fs.c b/nanos-lite/src/fs.c index a9d2670..55967d2 100644 --- a/nanos-lite/src/fs.c +++ b/nanos-lite/src/fs.c @@ -1,4 +1,5 @@ #include +#include typedef size_t (*ReadFn) (void *buf, size_t offset, size_t len); typedef size_t (*WriteFn) (const void *buf, size_t offset, size_t len); @@ -9,6 +10,7 @@ typedef struct { size_t disk_offset; ReadFn read; WriteFn write; + size_t open_offset; } Finfo; enum {FD_STDIN, FD_STDOUT, FD_STDERR, FD_FB}; @@ -23,14 +25,89 @@ size_t invalid_write(const void *buf, size_t offset, size_t len) { return 0; } +size_t _write(const void *buf, size_t offset, size_t count) { + for (size_t i = 0; i < count; i++) { + putch(((const char*)buf)[i]); + } + return count; +} + /* This is the information about all files in disk. */ static Finfo file_table[] __attribute__((used)) = { [FD_STDIN] = {"stdin", 0, 0, invalid_read, invalid_write}, - [FD_STDOUT] = {"stdout", 0, 0, invalid_read, invalid_write}, - [FD_STDERR] = {"stderr", 0, 0, invalid_read, invalid_write}, + [FD_STDOUT] = {"stdout", 0, 0, invalid_read, _write}, + [FD_STDERR] = {"stderr", 0, 0, invalid_read, _write}, #include "files.h" }; +int _fs_open(const char *pathname, int flags, int mode) { + int fd; + for (fd = 0; fd < LENGTH(file_table); fd ++) { + if (strcmp(file_table[fd].name, pathname) == 0) { + file_table[fd].open_offset = 0; + return fd; + } + } + panic_all_on(0, "No such file or directory"); + return -1; +} + +size_t _fs_read(int fd, void *buf, size_t len) { + assert(fd >= 0 && fd < LENGTH(file_table)); + if (file_table[fd].read != NULL) { + return file_table[fd].read(buf, file_table[fd].open_offset, len); + } + + if (file_table[fd].size < file_table[fd].open_offset + len) { + return -1; + } + size_t ret = ramdisk_read(buf, file_table[fd].disk_offset + file_table[fd].open_offset, len); + file_table[fd].open_offset += ret; + return ret; +} + +size_t _fs_write(int fd, const void *buf, size_t len) { + assert(fd >= 0 && fd < LENGTH(file_table)); + if (file_table[fd].write != NULL) { + return file_table[fd].write(buf, file_table[fd].open_offset, len); + } + + if (file_table[fd].size < file_table[fd].open_offset + len) { + return -1; + } + size_t ret = ramdisk_write(buf, file_table[fd].disk_offset + file_table[fd].open_offset, len); + file_table[fd].open_offset += ret; + return ret; +} + +size_t _fs_lseek(int fd, size_t offset, int whence) { + assert(fd >= 0 && fd < LENGTH(file_table)); + switch (whence) + { + case SEEK_CUR: + file_table[fd].open_offset += offset; + break; + case SEEK_END: + file_table[fd].open_offset = file_table[fd].size - offset; + break; + case SEEK_SET: + file_table[fd].open_offset = offset; + break; + default: + break; + } + if (file_table[fd].open_offset < file_table[fd].size) { + return -1; + } + return file_table[fd].open_offset; +} + +int _fs_close(int fd) { + assert(fd >= 0 && fd < LENGTH(file_table)); + return 0; +} + + void init_fs() { // TODO: initialize the size of /dev/fb } diff --git a/nanos-lite/src/loader.c b/nanos-lite/src/loader.c index 06f8064..3b2030f 100644 --- a/nanos-lite/src/loader.c +++ b/nanos-lite/src/loader.c @@ -1,5 +1,6 @@ #include #include +#include #ifdef __LP64__ # define Elf_Ehdr Elf64_Ehdr @@ -14,22 +15,25 @@ static uintptr_t loader(PCB *pcb, const char *filename) { Elf_Ehdr ehdr; size_t ret; - size_t ramdisk_read(void *buf, size_t offset, size_t len); - ret = ramdisk_read(&ehdr, 0, sizeof(ehdr)); + int fd = _fs_open(filename, 0, 0); + assert(fd != -1); + ret = _fs_read(fd, &ehdr, sizeof(ehdr)); assert(ret == sizeof(ehdr)); assert(ehdr.e_ident[0] == 0x7f && ehdr.e_ident[1] == 'E' && ehdr.e_ident[2] == 'L' && ehdr.e_ident[3] == 'F'); // assert(memcpy(ehdr.e_ident, ELFMAG, SELFMAG) == 0); // assert(*(uint32_t *)ehdr.e_ident == 0x7f454746); Elf_Phdr phdr[ehdr.e_phnum]; - ret = ramdisk_read(phdr, ehdr.e_phoff, sizeof(phdr)); + assert(_fs_lseek(fd, ehdr.e_phoff, SEEK_SET) != -1); + ret = _fs_read(fd, phdr, sizeof(phdr)); assert(ret == ehdr.e_phentsize * ehdr.e_phnum); for (int i = 0; i < ehdr.e_phnum; i ++) { if (phdr[i].p_type != PT_LOAD) { continue; } - ret = ramdisk_read((void*)phdr[i].p_vaddr, phdr[i].p_offset, phdr[i].p_filesz); + assert(_fs_lseek(fd, phdr[i].p_offset, SEEK_SET) != -1); + ret = _fs_read(fd, (void*)phdr[i].p_vaddr, phdr[i].p_filesz); assert(ret == phdr[i].p_filesz); memset((uint8_t*)phdr[i].p_vaddr + phdr[i].p_filesz, 0, phdr[i].p_memsz - phdr[i].p_filesz); } diff --git a/nanos-lite/src/proc.c b/nanos-lite/src/proc.c index abcf6bf..347b73f 100644 --- a/nanos-lite/src/proc.c +++ b/nanos-lite/src/proc.c @@ -26,7 +26,7 @@ void init_proc() { // load program here void naive_uload(PCB *pcb, const char *filename); - naive_uload(NULL, NULL); + naive_uload(NULL, "/bin/hello"); } diff --git a/nanos-lite/src/syscall.c b/nanos-lite/src/syscall.c index ae874fd..456136a 100644 --- a/nanos-lite/src/syscall.c +++ b/nanos-lite/src/syscall.c @@ -1,15 +1,6 @@ #include -#include "syscall.h" - -size_t _write(int fd, const void *buf, size_t count) { - if ((fd != 1 && fd != 2) || buf == NULL || count == 0) { - return -1; - } - for (size_t i = 0; i < count; i++) { - putch(((const char*)buf)[i]); - } - return count; -} +#include +#include int _brk(void* addr) { return 0; @@ -26,7 +17,13 @@ void do_syscall(Context *c) { TRACE("syscall %d: %s", a[0], __syscall_names[a[0]]); switch (a[0]) { CASE(yield, yield()) - CASE(write, c->GPRx = _write((int)a[1], (const char*)a[2], (size_t)a[3])) + + CASE(open, c->GPRx = _fs_open((const char*)a[1], (int)a[2], (int)a[3])) + CASE(read, c->GPRx = _fs_read((int)a[1], (void*)a[2], (size_t)a[3])) + CASE(write, c->GPRx = _fs_write((int)a[1], (const char*)a[2], (size_t)a[3])) + CASE(lseek, c->GPRx = _fs_lseek((int)a[1], (size_t)a[2], (int)a[3])) + CASE(close, c->GPRx = _fs_close((int)a[1])) + CASE(brk, c->GPRx = _brk((void*)a[1])) CASE(exit, halt(0)) default: panic("Unhandled syscall ID = %d", a[0]); diff --git a/navy-apps/Makefile b/navy-apps/Makefile index 6d2d944..f78425f 100644 --- a/navy-apps/Makefile +++ b/navy-apps/Makefile @@ -136,7 +136,7 @@ $(ARCHIVE): $(OBJS) libs ### Pull newlib from github if it does not exist ifeq ($(wildcard $(NAVY_HOME)/libs/libc/Makefile),) - $(shell cd $(NAVY_HOME)/libs && git clone https://github.com/NJU-ProjectN/newlib-navy.git libc) + $(shell cd $(NAVY_HOME)/libs && git clone https://www.github.com/NJU-ProjectN/newlib-navy.git libc) endif ### Build order control @@ -167,7 +167,7 @@ $(CLEAN_ALL): ### Build fsimg and ramdisk for Nanos-lite APPS = -TESTS = dummy hello +TESTS = dummy hello file-test fsimg: $(addprefix apps/, $(APPS)) $(addprefix tests/, $(TESTS)) -for t in $^; do $(MAKE) -s -C $(NAVY_HOME)/$$t install; done diff --git a/navy-apps/libs/compiler-rt/Makefile b/navy-apps/libs/compiler-rt/Makefile index fbcdb95..48b41cc 100644 --- a/navy-apps/libs/compiler-rt/Makefile +++ b/navy-apps/libs/compiler-rt/Makefile @@ -1,6 +1,6 @@ REPO_PATH = repo ifeq ($(wildcard repo/LICENSE.TXT),) - $(shell git clone --depth=1 git@github.com:NJU-ProjectN/compiler-rt.git $(REPO_PATH)) + $(shell git clone --depth=1 https://github.com/NJU-ProjectN/compiler-rt.git $(REPO_PATH)) endif NAME = compiler-rt diff --git a/navy-apps/libs/libos/src/syscall.c b/navy-apps/libs/libos/src/syscall.c index e4badfc..bc2dda1 100644 --- a/navy-apps/libs/libos/src/syscall.c +++ b/navy-apps/libs/libos/src/syscall.c @@ -62,8 +62,7 @@ void _exit(int status) { } int _open(const char *path, int flags, mode_t mode) { - _exit(SYS_open); - return 0; + return _syscall_(SYS_open, (intptr_t)path, flags, mode); } int _write(int fd, void *buf, size_t count) { @@ -83,18 +82,15 @@ void *_sbrk(intptr_t increment) { } int _read(int fd, void *buf, size_t count) { - _exit(SYS_read); - return 0; + return _syscall_(SYS_read, fd, (intptr_t)buf, count); } int _close(int fd) { - _exit(SYS_close); - return 0; + return _syscall_(SYS_close, fd, 0, 0); } off_t _lseek(int fd, off_t offset, int whence) { - _exit(SYS_lseek); - return 0; + return _syscall_(SYS_lseek, fd, offset, whence); } int _gettimeofday(struct timeval *tv, struct timezone *tz) {