> 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:
tracer-ics2023
2024-09-24 12:26:53 +08:00
committed by zzy
parent 2c2b54f1f6
commit ffcd9fbbab
11 changed files with 167 additions and 31 deletions

View File

@ -1,4 +1,4 @@
#HAS_NAVY = 1
HAS_NAVY = 1
RAMDISK_FILE = build/ramdisk.img
NAME = nanos-lite

View File

@ -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

View 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

View 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

View File

@ -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
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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]);

View File

@ -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

View File

@ -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

View File

@ -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) {