> compile NEMU
221220000 张三 Linux zzy 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux 12:26:49 up 6 days, 21:24, 1 user, load average: 0.72, 0.73, 0.62
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
#HAS_NAVY = 1
|
||||
HAS_NAVY = 1
|
||||
RAMDISK_FILE = build/ramdisk.img
|
||||
|
||||
NAME = nanos-lite
|
||||
|
@ -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
|
||||
|
15
nanos-lite/include/ramdisk.h
Normal file
15
nanos-lite/include/ramdisk.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef __RAMDISK_H__
|
||||
#define __RAMDISK_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
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
|
41
nanos-lite/include/syscall.h
Normal file
41
nanos-lite/include/syscall.h
Normal file
@ -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
|
@ -1,4 +1,5 @@
|
||||
#include <fs.h>
|
||||
#include <ramdisk.h>
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <proc.h>
|
||||
#include <elf.h>
|
||||
#include <fs.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
@ -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");
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,6 @@
|
||||
#include <common.h>
|
||||
#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 <syscall.h>
|
||||
#include <fs.h>
|
||||
|
||||
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]);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user