NJU-ProjectN/nanos-lite ics2021 initialized
NJU-ProjectN/nanos-lite 2a141760e31be246a7316942293a97873925bc2f Makefile: use header files in newlib-navy
This commit is contained in:
8
nanos-lite/.gitignore
vendored
Normal file
8
nanos-lite/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
*.*
|
||||
*
|
||||
!*/
|
||||
!Makefile*
|
||||
!*.[cSh]
|
||||
!.gitignore
|
||||
!README.md
|
||||
!resources/logo.txt
|
34
nanos-lite/Makefile
Normal file
34
nanos-lite/Makefile
Normal file
@ -0,0 +1,34 @@
|
||||
#HAS_NAVY = 1
|
||||
RAMDISK_FILE = build/ramdisk.img
|
||||
|
||||
NAME = nanos-lite
|
||||
SRCS = $(shell find -L ./src/ -name "*.c" -o -name "*.cpp" -o -name "*.S")
|
||||
include $(AM_HOME)/Makefile
|
||||
|
||||
ifeq ($(ARCH),native)
|
||||
ISA = am_native
|
||||
else
|
||||
INC_PATH += include $(NAVY_HOME)/libs/libc/include
|
||||
endif
|
||||
|
||||
./src/resources.S: $(RAMDISK_FILE)
|
||||
@touch $@
|
||||
|
||||
ifeq ($(HAS_NAVY),)
|
||||
files = $(RAMDISK_FILE) src/files.h src/syscall.h
|
||||
# create an empty file if it does not exist
|
||||
$(foreach f,$(files),$(if $(wildcard $f),, $(shell touch $f)))
|
||||
else
|
||||
|
||||
ifeq ($(wildcard $(NAVY_HOME)/libs/libos/src/syscall.h),)
|
||||
$(error $$NAVY_HOME must be a Navy-apps repo)
|
||||
endif
|
||||
|
||||
update:
|
||||
$(MAKE) -s -C $(NAVY_HOME) ISA=$(ISA) ramdisk
|
||||
@ln -sf $(NAVY_HOME)/build/ramdisk.img $(RAMDISK_FILE)
|
||||
@ln -sf $(NAVY_HOME)/build/ramdisk.h src/files.h
|
||||
@ln -sf $(NAVY_HOME)/libs/libos/src/syscall.h src/syscall.h
|
||||
|
||||
.PHONY: update
|
||||
endif
|
15
nanos-lite/README.md
Normal file
15
nanos-lite/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Nanos-lite
|
||||
|
||||
Nanos-lite is the simplified version of Nanos (http://cslab.nju.edu.cn/opsystem).
|
||||
It is ported to the [AM project](https://github.com/NJU-ProjectN/abstract-machine.git).
|
||||
It is a two-tasking operating system with the following features
|
||||
* ramdisk device drivers
|
||||
* ELF program loader
|
||||
* memory management with paging
|
||||
* a simple file system
|
||||
* with fix number and size of files
|
||||
* without directory
|
||||
* some device files
|
||||
* 9 system calls
|
||||
* open, read, write, lseek, close, gettimeofday, brk, exit, execve
|
||||
* scheduler with two tasks
|
15
nanos-lite/include/common.h
Normal file
15
nanos-lite/include/common.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef __COMMON_H__
|
||||
#define __COMMON_H__
|
||||
|
||||
/* Uncomment these macros to enable corresponding functionality. */
|
||||
//#define HAS_CTE
|
||||
//#define HAS_VME
|
||||
//#define MULTIPROGRAM
|
||||
//#define TIME_SHARING
|
||||
|
||||
#include <am.h>
|
||||
#include <klib.h>
|
||||
#include <klib-macros.h>
|
||||
#include <debug.h>
|
||||
|
||||
#endif
|
30
nanos-lite/include/debug.h
Normal file
30
nanos-lite/include/debug.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef __DEBUG_H__
|
||||
#define __DEBUG_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#define Log(format, ...) \
|
||||
printf("\33[1;35m[%s,%d,%s] " format "\33[0m\n", \
|
||||
__FILE__, __LINE__, __func__, ## __VA_ARGS__)
|
||||
|
||||
#undef panic
|
||||
#define panic(format, ...) \
|
||||
do { \
|
||||
Log("\33[1;31msystem panic: " format, ## __VA_ARGS__); \
|
||||
halt(1); \
|
||||
} while (0)
|
||||
|
||||
#ifdef assert
|
||||
# undef assert
|
||||
#endif
|
||||
|
||||
#define assert(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
panic("Assertion failed: %s", #cond); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TODO() panic("please implement me")
|
||||
|
||||
#endif
|
10
nanos-lite/include/fs.h
Normal file
10
nanos-lite/include/fs.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __FS_H__
|
||||
#define __FS_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#ifndef SEEK_SET
|
||||
enum {SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
#endif
|
||||
|
||||
#endif
|
14
nanos-lite/include/memory.h
Normal file
14
nanos-lite/include/memory.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __MEMORY_H__
|
||||
#define __MEMORY_H__
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#ifndef PGSIZE
|
||||
#define PGSIZE 4096
|
||||
#endif
|
||||
|
||||
#define PG_ALIGN __attribute((aligned(PGSIZE)))
|
||||
|
||||
void* new_page(size_t);
|
||||
|
||||
#endif
|
21
nanos-lite/include/proc.h
Normal file
21
nanos-lite/include/proc.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef __PROC_H__
|
||||
#define __PROC_H__
|
||||
|
||||
#include <common.h>
|
||||
#include <memory.h>
|
||||
|
||||
#define STACK_SIZE (8 * PGSIZE)
|
||||
|
||||
typedef union {
|
||||
uint8_t stack[STACK_SIZE] PG_ALIGN;
|
||||
struct {
|
||||
Context *cp;
|
||||
AddrSpace as;
|
||||
// we do not free memory, so use `max_brk' to determine when to call _map()
|
||||
uintptr_t max_brk;
|
||||
};
|
||||
} PCB;
|
||||
|
||||
extern PCB *current;
|
||||
|
||||
#endif
|
29
nanos-lite/resources/logo.txt
Normal file
29
nanos-lite/resources/logo.txt
Normal file
@ -0,0 +1,29 @@
|
||||
######################%'``|######################$
|
||||
###################$` ..`. '&###################$
|
||||
#################$` .`::::'` '&#################$
|
||||
###############$` .`::;!;::::`. '&###############$
|
||||
#############$` .`:::::|$%;::::` '&#############$
|
||||
###########$` .'::::::!%$$$%;::::`. '&###########$
|
||||
#########$` .'::::::!%$$$$$%;::::::` '&#########$
|
||||
#######$` .'::::::!%$%|$$$$%;::::::::`. '&#######$
|
||||
#####$` .'::::::!%$%;:|$$$$|;::::::::::` '&#####$
|
||||
###$` .';;;;;;!%$%;;;;|$$$$|;::::;|%!::::`. '&###$
|
||||
#&' .';;;%%!!%$%;;;;;;%$$$$|;;;;;;;|$%!;:::`. '@#$
|
||||
%. ';;;;;|$$%!;;;;;;!%$$$$!;;;;;!%$%%$%!;;:` '&$
|
||||
| `;;;;;;|$%!;;;;;!$$$$%!;;;!%$%!;;;;;;:` .%$
|
||||
@: ;!``;;;;;;;;;;;;;|$$$$%!;!%$%!;;;;;;:`'!' :@$
|
||||
; '%$!``;;;;;;;;;;;|$$$$%!%$%!;;;;;;:`'|$|` |$
|
||||
| .:%$!`';;;;;;;;!%$$$$$$%!;;;;;;:`'|$|' .%$
|
||||
#$` .:%$|`';;;;;;!%$$$$%!;;;;;;:`'|$|' ;##$
|
||||
###$` .:%$|`';;;;;!%$%|!;;;;;;`'%$|' ;####$
|
||||
#####$` .:%$|`';!!!!!!!!!!!;`'%$%' ;######$
|
||||
#######$` .:$$|`';!!!!!!!;`'%$%' ;########$
|
||||
#########$` .:$$|`';!!!;`'%$%' ;##########$
|
||||
###########$` .:$&|`.`.'%&%' ;@###########$
|
||||
#############$` .:$&$$&&%' ;##############$
|
||||
###############$` .:$&%' ;@###############$
|
||||
#################$` ;##################$
|
||||
|
||||
**Project-N**
|
||||
Nanjing University Computer System Project Series
|
||||
Build a computer system from scratch!
|
2
nanos-lite/src/.gitignore
vendored
Normal file
2
nanos-lite/src/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
files.h
|
||||
syscall.h
|
36
nanos-lite/src/device.c
Normal file
36
nanos-lite/src/device.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include <common.h>
|
||||
|
||||
#if defined(MULTIPROGRAM) && !defined(TIME_SHARING)
|
||||
# define MULTIPROGRAM_YIELD() yield()
|
||||
#else
|
||||
# define MULTIPROGRAM_YIELD()
|
||||
#endif
|
||||
|
||||
#define NAME(key) \
|
||||
[AM_KEY_##key] = #key,
|
||||
|
||||
static const char *keyname[256] __attribute__((used)) = {
|
||||
[AM_KEY_NONE] = "NONE",
|
||||
AM_KEYS(NAME)
|
||||
};
|
||||
|
||||
size_t serial_write(const void *buf, size_t offset, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t events_read(void *buf, size_t offset, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t dispinfo_read(void *buf, size_t offset, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t fb_write(const void *buf, size_t offset, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_device() {
|
||||
Log("Initializing devices...");
|
||||
ioe_init();
|
||||
}
|
36
nanos-lite/src/fs.c
Normal file
36
nanos-lite/src/fs.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include <fs.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);
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
size_t size;
|
||||
size_t disk_offset;
|
||||
ReadFn read;
|
||||
WriteFn write;
|
||||
} Finfo;
|
||||
|
||||
enum {FD_STDIN, FD_STDOUT, FD_STDERR, FD_FB};
|
||||
|
||||
size_t invalid_read(void *buf, size_t offset, size_t len) {
|
||||
panic("should not reach here");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t invalid_write(const void *buf, size_t offset, size_t len) {
|
||||
panic("should not reach here");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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},
|
||||
#include "files.h"
|
||||
};
|
||||
|
||||
void init_fs() {
|
||||
// TODO: initialize the size of /dev/fb
|
||||
}
|
14
nanos-lite/src/irq.c
Normal file
14
nanos-lite/src/irq.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include <common.h>
|
||||
|
||||
static Context* do_event(Event e, Context* c) {
|
||||
switch (e.event) {
|
||||
default: panic("Unhandled event ID = %d", e.event);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void init_irq(void) {
|
||||
Log("Initializing interrupt/exception handler...");
|
||||
cte_init(do_event);
|
||||
}
|
22
nanos-lite/src/loader.c
Normal file
22
nanos-lite/src/loader.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include <proc.h>
|
||||
#include <elf.h>
|
||||
|
||||
#ifdef __LP64__
|
||||
# define Elf_Ehdr Elf64_Ehdr
|
||||
# define Elf_Phdr Elf64_Phdr
|
||||
#else
|
||||
# define Elf_Ehdr Elf32_Ehdr
|
||||
# define Elf_Phdr Elf32_Phdr
|
||||
#endif
|
||||
|
||||
static uintptr_t loader(PCB *pcb, const char *filename) {
|
||||
TODO();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void naive_uload(PCB *pcb, const char *filename) {
|
||||
uintptr_t entry = loader(pcb, filename);
|
||||
Log("Jump to entry = %p", entry);
|
||||
((void(*)())entry) ();
|
||||
}
|
||||
|
37
nanos-lite/src/main.c
Normal file
37
nanos-lite/src/main.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include <common.h>
|
||||
|
||||
void init_mm(void);
|
||||
void init_device(void);
|
||||
void init_ramdisk(void);
|
||||
void init_irq(void);
|
||||
void init_fs(void);
|
||||
void init_proc(void);
|
||||
|
||||
int main() {
|
||||
extern const char logo[];
|
||||
printf("%s", logo);
|
||||
Log("'Hello World!' from Nanos-lite");
|
||||
Log("Build time: %s, %s", __TIME__, __DATE__);
|
||||
|
||||
init_mm();
|
||||
|
||||
init_device();
|
||||
|
||||
init_ramdisk();
|
||||
|
||||
#ifdef HAS_CTE
|
||||
init_irq();
|
||||
#endif
|
||||
|
||||
init_fs();
|
||||
|
||||
init_proc();
|
||||
|
||||
Log("Finish initialization");
|
||||
|
||||
#ifdef HAS_CTE
|
||||
yield();
|
||||
#endif
|
||||
|
||||
panic("Should not reach here");
|
||||
}
|
31
nanos-lite/src/mm.c
Normal file
31
nanos-lite/src/mm.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <memory.h>
|
||||
|
||||
static void *pf = NULL;
|
||||
|
||||
void* new_page(size_t nr_page) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAS_VME
|
||||
static void* pg_alloc(int n) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void free_page(void *p) {
|
||||
panic("not implement yet");
|
||||
}
|
||||
|
||||
/* The brk() system call handler. */
|
||||
int mm_brk(uintptr_t brk) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_mm() {
|
||||
pf = (void *)ROUNDUP(heap.start, PGSIZE);
|
||||
Log("free physical pages starting from %p", pf);
|
||||
|
||||
#ifdef HAS_VME
|
||||
vme_init(pg_alloc, free_page);
|
||||
#endif
|
||||
}
|
33
nanos-lite/src/proc.c
Normal file
33
nanos-lite/src/proc.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include <proc.h>
|
||||
|
||||
#define MAX_NR_PROC 4
|
||||
|
||||
static PCB pcb[MAX_NR_PROC] __attribute__((used)) = {};
|
||||
static PCB pcb_boot = {};
|
||||
PCB *current = NULL;
|
||||
|
||||
void switch_boot_pcb() {
|
||||
current = &pcb_boot;
|
||||
}
|
||||
|
||||
void hello_fun(void *arg) {
|
||||
int j = 1;
|
||||
while (1) {
|
||||
Log("Hello World from Nanos-lite with arg '%p' for the %dth time!", (uintptr_t)arg, j);
|
||||
j ++;
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
void init_proc() {
|
||||
switch_boot_pcb();
|
||||
|
||||
Log("Initializing processes...");
|
||||
|
||||
// load program here
|
||||
|
||||
}
|
||||
|
||||
Context* schedule(Context *prev) {
|
||||
return NULL;
|
||||
}
|
33
nanos-lite/src/ramdisk.c
Normal file
33
nanos-lite/src/ramdisk.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include <common.h>
|
||||
|
||||
extern uint8_t ramdisk_start;
|
||||
extern uint8_t ramdisk_end;
|
||||
#define RAMDISK_SIZE ((&ramdisk_end) - (&ramdisk_start))
|
||||
|
||||
/* The kernel is monolithic, therefore we do not need to
|
||||
* translate the address `buf' from the user process to
|
||||
* a physical one, which is necessary for a microkernel.
|
||||
*/
|
||||
|
||||
/* read `len' bytes starting from `offset' of ramdisk into `buf' */
|
||||
size_t ramdisk_read(void *buf, size_t offset, size_t len) {
|
||||
assert(offset + len <= RAMDISK_SIZE);
|
||||
memcpy(buf, &ramdisk_start + offset, len);
|
||||
return 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) {
|
||||
assert(offset + len <= RAMDISK_SIZE);
|
||||
memcpy(&ramdisk_start + offset, buf, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
void init_ramdisk() {
|
||||
Log("ramdisk info: start = %p, end = %p, size = %d bytes",
|
||||
&ramdisk_start, &ramdisk_end, RAMDISK_SIZE);
|
||||
}
|
||||
|
||||
size_t get_ramdisk_size() {
|
||||
return RAMDISK_SIZE;
|
||||
}
|
10
nanos-lite/src/syscall.c
Normal file
10
nanos-lite/src/syscall.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include <common.h>
|
||||
#include "syscall.h"
|
||||
void do_syscall(Context *c) {
|
||||
uintptr_t a[4];
|
||||
a[0] = c->GPR1;
|
||||
|
||||
switch (a[0]) {
|
||||
default: panic("Unhandled syscall ID = %d", a[0]);
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
# CONFIG_ITRACE is not set
|
||||
CONFIG_PMEM_MALLOC=y
|
||||
CONFIG_DEVICE=y
|
Reference in New Issue
Block a user