> 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
|
RAMDISK_FILE = build/ramdisk.img
|
||||||
|
|
||||||
NAME = nanos-lite
|
NAME = nanos-lite
|
||||||
|
@ -7,4 +7,10 @@
|
|||||||
enum {SEEK_SET, SEEK_CUR, SEEK_END};
|
enum {SEEK_SET, SEEK_CUR, SEEK_END};
|
||||||
#endif
|
#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
|
#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 <fs.h>
|
||||||
|
#include <ramdisk.h>
|
||||||
|
|
||||||
typedef size_t (*ReadFn) (void *buf, size_t offset, size_t len);
|
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);
|
typedef size_t (*WriteFn) (const void *buf, size_t offset, size_t len);
|
||||||
@ -9,6 +10,7 @@ typedef struct {
|
|||||||
size_t disk_offset;
|
size_t disk_offset;
|
||||||
ReadFn read;
|
ReadFn read;
|
||||||
WriteFn write;
|
WriteFn write;
|
||||||
|
size_t open_offset;
|
||||||
} Finfo;
|
} Finfo;
|
||||||
|
|
||||||
enum {FD_STDIN, FD_STDOUT, FD_STDERR, FD_FB};
|
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;
|
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. */
|
/* This is the information about all files in disk. */
|
||||||
static Finfo file_table[] __attribute__((used)) = {
|
static Finfo file_table[] __attribute__((used)) = {
|
||||||
[FD_STDIN] = {"stdin", 0, 0, invalid_read, invalid_write},
|
[FD_STDIN] = {"stdin", 0, 0, invalid_read, invalid_write},
|
||||||
[FD_STDOUT] = {"stdout", 0, 0, invalid_read, invalid_write},
|
[FD_STDOUT] = {"stdout", 0, 0, invalid_read, _write},
|
||||||
[FD_STDERR] = {"stderr", 0, 0, invalid_read, invalid_write},
|
[FD_STDERR] = {"stderr", 0, 0, invalid_read, _write},
|
||||||
#include "files.h"
|
#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() {
|
void init_fs() {
|
||||||
// TODO: initialize the size of /dev/fb
|
// TODO: initialize the size of /dev/fb
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <proc.h>
|
#include <proc.h>
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
|
#include <fs.h>
|
||||||
|
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
# define Elf_Ehdr Elf64_Ehdr
|
# define Elf_Ehdr Elf64_Ehdr
|
||||||
@ -14,22 +15,25 @@ static uintptr_t loader(PCB *pcb, const char *filename) {
|
|||||||
Elf_Ehdr ehdr;
|
Elf_Ehdr ehdr;
|
||||||
size_t ret;
|
size_t ret;
|
||||||
|
|
||||||
size_t ramdisk_read(void *buf, size_t offset, size_t len);
|
int fd = _fs_open(filename, 0, 0);
|
||||||
ret = ramdisk_read(&ehdr, 0, sizeof(ehdr));
|
assert(fd != -1);
|
||||||
|
ret = _fs_read(fd, &ehdr, sizeof(ehdr));
|
||||||
assert(ret == 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(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(memcpy(ehdr.e_ident, ELFMAG, SELFMAG) == 0);
|
||||||
// assert(*(uint32_t *)ehdr.e_ident == 0x7f454746);
|
// assert(*(uint32_t *)ehdr.e_ident == 0x7f454746);
|
||||||
|
|
||||||
Elf_Phdr phdr[ehdr.e_phnum];
|
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);
|
assert(ret == ehdr.e_phentsize * ehdr.e_phnum);
|
||||||
|
|
||||||
for (int i = 0; i < ehdr.e_phnum; i ++) {
|
for (int i = 0; i < ehdr.e_phnum; i ++) {
|
||||||
if (phdr[i].p_type != PT_LOAD) {
|
if (phdr[i].p_type != PT_LOAD) {
|
||||||
continue;
|
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);
|
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);
|
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
|
// load program here
|
||||||
void naive_uload(PCB *pcb, const char *filename);
|
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 <common.h>
|
||||||
#include "syscall.h"
|
#include <syscall.h>
|
||||||
|
#include <fs.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _brk(void* addr) {
|
int _brk(void* addr) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -26,7 +17,13 @@ void do_syscall(Context *c) {
|
|||||||
TRACE("syscall %d: %s", a[0], __syscall_names[a[0]]);
|
TRACE("syscall %d: %s", a[0], __syscall_names[a[0]]);
|
||||||
switch (a[0]) {
|
switch (a[0]) {
|
||||||
CASE(yield, yield())
|
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(brk, c->GPRx = _brk((void*)a[1]))
|
||||||
CASE(exit, halt(0))
|
CASE(exit, halt(0))
|
||||||
default: panic("Unhandled syscall ID = %d", a[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
|
### Pull newlib from github if it does not exist
|
||||||
ifeq ($(wildcard $(NAVY_HOME)/libs/libc/Makefile),)
|
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
|
endif
|
||||||
|
|
||||||
### Build order control
|
### Build order control
|
||||||
@ -167,7 +167,7 @@ $(CLEAN_ALL):
|
|||||||
|
|
||||||
### Build fsimg and ramdisk for Nanos-lite
|
### Build fsimg and ramdisk for Nanos-lite
|
||||||
APPS =
|
APPS =
|
||||||
TESTS = dummy hello
|
TESTS = dummy hello file-test
|
||||||
|
|
||||||
fsimg: $(addprefix apps/, $(APPS)) $(addprefix tests/, $(TESTS))
|
fsimg: $(addprefix apps/, $(APPS)) $(addprefix tests/, $(TESTS))
|
||||||
-for t in $^; do $(MAKE) -s -C $(NAVY_HOME)/$$t install; done
|
-for t in $^; do $(MAKE) -s -C $(NAVY_HOME)/$$t install; done
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
REPO_PATH = repo
|
REPO_PATH = repo
|
||||||
ifeq ($(wildcard repo/LICENSE.TXT),)
|
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
|
endif
|
||||||
|
|
||||||
NAME = compiler-rt
|
NAME = compiler-rt
|
||||||
|
@ -62,8 +62,7 @@ void _exit(int status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int _open(const char *path, int flags, mode_t mode) {
|
int _open(const char *path, int flags, mode_t mode) {
|
||||||
_exit(SYS_open);
|
return _syscall_(SYS_open, (intptr_t)path, flags, mode);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _write(int fd, void *buf, size_t count) {
|
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) {
|
int _read(int fd, void *buf, size_t count) {
|
||||||
_exit(SYS_read);
|
return _syscall_(SYS_read, fd, (intptr_t)buf, count);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _close(int fd) {
|
int _close(int fd) {
|
||||||
_exit(SYS_close);
|
return _syscall_(SYS_close, fd, 0, 0);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t _lseek(int fd, off_t offset, int whence) {
|
off_t _lseek(int fd, off_t offset, int whence) {
|
||||||
_exit(SYS_lseek);
|
return _syscall_(SYS_lseek, fd, offset, whence);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _gettimeofday(struct timeval *tv, struct timezone *tz) {
|
int _gettimeofday(struct timeval *tv, struct timezone *tz) {
|
||||||
|
Reference in New Issue
Block a user