diff --git a/Makefile.compile b/Makefile.compile index d4b40d4b..ccb399b3 100644 --- a/Makefile.compile +++ b/Makefile.compile @@ -20,6 +20,7 @@ CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ LD = $(CROSS_COMPILE)ld OBJCOPY = $(CROSS_COMPILE)objcopy +READELF = $(CROSS_COMPILE)readelf ISA_DEF = __ISA_$(shell echo $(ISA) | tr a-z A-Z)__ diff --git a/am/arch/x86-nemu/include/arch.h b/am/arch/x86-nemu/include/arch.h index adc23803..70ba1d4d 100644 --- a/am/arch/x86-nemu/include/arch.h +++ b/am/arch/x86-nemu/include/arch.h @@ -17,26 +17,6 @@ struct _RegSet { typedef struct _RegSet TrapFrame; -static inline uint8_t inb(int port) { - char data; - asm volatile("inb %1, %0" : "=a"(data) : "d"((uint16_t)port)); - return data; -} - -static inline uint32_t inl(int port) { - long data; - asm volatile("inl %1, %0" : "=a"(data) : "d"((uint16_t)port)); - return data; -} - -static inline void outb(int port, uint8_t data) { - asm volatile("outb %%al, %%dx" : : "a"(data), "d"((uint16_t)port)); -} - -static inline void outl(int port, uint32_t data) { - asm volatile("outl %%eax, %%dx" : : "a"(data), "d"((uint16_t)port)); -} - #ifdef __cplusplus extern "C" { #endif diff --git a/am/arch/x86-nemu/include/x86.h b/am/arch/x86-nemu/include/x86.h index c4268e34..df89356f 100644 --- a/am/arch/x86-nemu/include/x86.h +++ b/am/arch/x86-nemu/include/x86.h @@ -48,14 +48,6 @@ // IDT size #define NR_IRQ 256 // IDT size -// interrupts -#define T_IRQ0 32 -#define IRQ_TIMER 0 -#define IRQ_KBD 1 -#define IRQ_SPURIOUS 31 -#define IRQ_ERROR 19 - - // The following macros will not be seen by the assembler #ifndef __ASSEMBLER__ @@ -95,24 +87,6 @@ typedef struct GateDesc { { (uint32_t)(entry) & 0xffff, (cs), 0, 0, (type), 0, (dpl), \ 1, (uint32_t)(entry) >> 16 } -static inline void cli() { - asm volatile("cli"); -} - -static inline void sti() { - asm volatile("sti"); -} - -static inline void hlt() { - asm volatile("hlt"); -} - -static inline uint32_t get_efl() { - volatile uint32_t efl; - asm volatile("pushf; pop %0": "=r"(efl)); - return efl; -} - static inline uint32_t get_cr0(void) { volatile uint32_t val; asm volatile("movl %%cr0, %0" : "=r"(val)); @@ -132,16 +106,29 @@ static inline void set_idt(GateDesc *idt, int size) { asm volatile("lidt (%0)" : : "r"(data)); } -static inline uint32_t get_cr2() { - volatile uint32_t val; - asm volatile("movl %%cr2, %0" : "=r"(val)); - return val; -} - static inline void set_cr3(void *pdir) { asm volatile("movl %0, %%cr3" : : "r"(pdir)); } +static inline uint8_t inb(int port) { + char data; + asm volatile("inb %1, %0" : "=a"(data) : "d"((uint16_t)port)); + return data; +} + +static inline uint32_t inl(int port) { + long data; + asm volatile("inl %1, %0" : "=a"(data) : "d"((uint16_t)port)); + return data; +} + +static inline void outb(int port, uint8_t data) { + asm volatile("outb %%al, %%dx" : : "a"(data), "d"((uint16_t)port)); +} + +static inline void outl(int port, uint32_t data) { + asm volatile("outl %%eax, %%dx" : : "a"(data), "d"((uint16_t)port)); +} #endif diff --git a/am/arch/x86-nemu/src/asye.c b/am/arch/x86-nemu/src/asye.c index f261a1c8..272ef848 100644 --- a/am/arch/x86-nemu/src/asye.c +++ b/am/arch/x86-nemu/src/asye.c @@ -12,30 +12,33 @@ uintptr_t irq_handle(_RegSet *r) { _RegSet *next = r; if (H) { _Event ev; + intptr_t args[4]; switch (r->irq) { case 32: ev.event = _EVENT_IRQ_TIME; break; case 0x80: { ev.event = _EVENT_SYSCALL; - intptr_t args[4]; args[0] = r->eax; - args[1] = r->edx; + args[1] = r->ebx; args[2] = r->ecx; - args[3] = r->ebx; - ev.cause = (intptr_t)&args; + args[3] = r->edx; + ev.cause = (intptr_t)args; break; } case 0x81: ev.event = _EVENT_TRAP; break; default: ev.event = _EVENT_ERROR; break; } - r->esp = (uintptr_t)r; - r = H(ev, r); - if (r != NULL) { + next = H(ev, r); + if (ev.event == _EVENT_SYSCALL) { + r->eax = args[0]; + } + + if (next == NULL) { next = r; } } - return next->esp; + return (uintptr_t)next; } static GateDesc idt[NR_IRQ]; @@ -56,13 +59,12 @@ void _asye_init(_RegSet*(*h)(_Event, _RegSet*)) { } _RegSet *_make(_Area stack, void *entry, void *arg) { - // TODO: pass arg stack.end -= 4 * sizeof(int); // 4 = retaddr + argc + argv + envp _RegSet *r = (_RegSet*)stack.end - 1; r->esp = (uintptr_t)r; r->cs = 0x8; r->eip = (uintptr_t)entry; - r->eflags = 0; + r->eflags = 0x2 | FL_IF; return r; } @@ -71,11 +73,5 @@ void _trap() { } int _istatus(int enable) { - int ret = (get_efl() & FL_IF) != 0; - if (enable) { - sti(); - } else { - cli(); - } - return ret; + return 0; } diff --git a/am/arch/x86-nemu/src/ioe.c b/am/arch/x86-nemu/src/ioe.c index 97f3c830..87bd40a5 100644 --- a/am/arch/x86-nemu/src/ioe.c +++ b/am/arch/x86-nemu/src/ioe.c @@ -1,5 +1,4 @@ #include -#include #include #define RTC_PORT 0x48 // Note that this is not standard @@ -9,22 +8,15 @@ void _ioe_init() { boot_time = inl(RTC_PORT); } -// -------------------- cycles and uptime -------------------- - unsigned long _uptime() { return inl(RTC_PORT) - boot_time; - //return 0; } -// -------------------- video -------------------- - uint32_t* const fb = (uint32_t *)0x40000; -#define SCREEN_W 320 -#define SCREEN_H 200 _Screen _screen = { - .width = SCREEN_W, - .height = SCREEN_H, + .width = 400, + .height = 300, }; extern void* memcpy(void *, const void *, int); @@ -47,10 +39,6 @@ void _draw_rect(const uint32_t *pixels, int x, int y, int w, int h) { void _draw_sync() { } -// -------------------- keyboard -------------------- - -#define KEYDOWN_MASK 0x8000 - int _read_key() { int status = inb(0x64); if ((status & 0x1) == 0) return _KEY_NONE; diff --git a/am/arch/x86-nemu/src/pte.c b/am/arch/x86-nemu/src/pte.c index 010fbef4..e763ec92 100644 --- a/am/arch/x86-nemu/src/pte.c +++ b/am/arch/x86-nemu/src/pte.c @@ -1,4 +1,3 @@ -#include #include #define PG_ALIGN __attribute((aligned(PGSIZE))) @@ -9,7 +8,7 @@ void* (*palloc_f)(); void (*pfree_f)(void*); _Area segments[] = { // Kernel memory mappings - {.start = (void*)0, .end = (void*)PMEM_SIZE}, // Low memory: kernel data + {.start = (void*)0, .end = (void*)PMEM_SIZE} }; #define NR_KSEG_MAP (sizeof(segments) / sizeof(segments[0])) @@ -46,16 +45,11 @@ void _protect(_Protect *p) { for (int i = 0; i < 1024; i ++) updir[i] = kpdir[i]; - // exact copy of kernel page table - // no user memory is mapped - p->area.start = (void*)0x8000000; p->area.end = (void*)0xc0000000; - // return [ULOW, UHIGH) } void _release(_Protect *p) { - // free all spaces } void _switch(_Protect *p) { diff --git a/am/arch/x86-nemu/src/trm.c b/am/arch/x86-nemu/src/trm.c index 9b1dfa6d..7e9028ff 100644 --- a/am/arch/x86-nemu/src/trm.c +++ b/am/arch/x86-nemu/src/trm.c @@ -1,5 +1,4 @@ #include -#include #include // Define this macro after serial has been implemented diff --git a/apps/nanos-lite/Makefile b/apps/nanos-lite/Makefile index cc65baa0..948be0ae 100644 --- a/apps/nanos-lite/Makefile +++ b/apps/nanos-lite/Makefile @@ -3,31 +3,25 @@ SRCS = $(shell find -L ./src/ -name "*.c" -o -name "*.cpp" -o -name "*.S") LIBS = klib include $(AM_HOME)/Makefile.app -NANOS_MAX_SIZE = 0 #1048576 FSIMG_PATH = $(NAVY_HOME)/fsimg FSIMG_FILES = $(shell find $(FSIMG_PATH) -type f) RAMDISK_FILE = build/ramdisk.img -.PHONY: fsimg update +.PHONY: update -fsimg: +update-fsimg: $(MAKE) -C $(NAVY_HOME) ISA=$(ISA) - -$(FSIMG_FILES): fsimg - -#src/files.h: $(FSIMG_FILES) -# wc -c $(FSIMG_FILES) | grep -v 'total$$' | sed -e 's+ $(FSIMG_PATH)+ +' | awk -v sum=$(NANOS_MAX_SIZE) '{print "\x7b\x22" $$2 "\x22\x2c " $$1 "\x2c " sum "\x7d\x2c";sum += $$1}' > $@ - -src/initrd.S: $(RAMDISK_FILE) - touch $@ + for f in $(FSIMG_FILES); do \ + if $(READELF) -h $$f 2> /dev/null > /dev/null; then \ + $(OBJCOPY) --set-section-flags .bss=alloc,contents -O binary $$f; \ + fi \ + done src/syscall.h: $(NAVY_HOME)/libs/libos/src/syscall.h ln -sf $^ $@ -#$(RAMDISK_FILE): $(FSIMG_FILES) -# cat $^ > $@ - -$(RAMDISK_FILE): $(NAVY_HOME)/tests/hello/build/hello-x86 - $(OBJCOPY) --set-section-flags .bss=alloc,contents -O binary $^ $@ - -update: src/initrd.S src/syscall.h +update: update-fsimg src/syscall.h + @cat $(FSIMG_FILES) > $(RAMDISK_FILE) + # $(OBJCOPY) --set-section-flags .bss=alloc,contents -O binary $(NAVY_HOME)/tests/hello/build/hello-x86 $(RAMDISK_FILE) + @touch src/initrd.S + @wc -c $(FSIMG_FILES) | grep -v 'total$$' | sed -e 's+ $(FSIMG_PATH)+ +' | awk -v sum=0 '{print "\x7b\x22" $$2 "\x22\x2c " $$1 "\x2c " sum "\x7d\x2c";sum += $$1}' > src/files.h diff --git a/apps/nanos-lite/include/common.h b/apps/nanos-lite/include/common.h index 39056b86..c1a3e375 100644 --- a/apps/nanos-lite/include/common.h +++ b/apps/nanos-lite/include/common.h @@ -1,9 +1,6 @@ #ifndef __COMMON_H__ #define __COMMON_H__ -/* Uncomment the following macro after paging is enabling. */ -//#define __PAGE - #include #include #include "debug.h" diff --git a/apps/nanos-lite/include/fs.h b/apps/nanos-lite/include/fs.h index adc9a71c..b8fae442 100644 --- a/apps/nanos-lite/include/fs.h +++ b/apps/nanos-lite/include/fs.h @@ -11,4 +11,6 @@ ssize_t fs_write(int, const void *, size_t); off_t fs_lseek(int, off_t, int); int fs_close(int); +size_t fs_filesz(int); + #endif diff --git a/apps/nanos-lite/include/memory.h b/apps/nanos-lite/include/memory.h index 8405cd4c..9bdfc31d 100644 --- a/apps/nanos-lite/include/memory.h +++ b/apps/nanos-lite/include/memory.h @@ -7,6 +7,8 @@ #define PGSIZE 4096 #endif +#define PG_ALIGN __attribute((aligned(PGSIZE))) + #ifndef PMEM_SIZE #define PMEM_SIZE (128 * 1024 * 1024) #endif @@ -16,6 +18,5 @@ #define PGROUNDDOWN(a) (((a)) & ~PGMASK) void* new_page(void); -void* kmalloc(uint32_t); #endif diff --git a/apps/nanos-lite/include/proc.h b/apps/nanos-lite/include/proc.h new file mode 100644 index 00000000..65b68040 --- /dev/null +++ b/apps/nanos-lite/include/proc.h @@ -0,0 +1,22 @@ +#ifndef __PROC_H__ +#define __PROC_H__ + +#include "common.h" +#include "memory.h" + +#define STACK_SIZE (128 * PGSIZE) + +typedef union { + uint8_t stack[STACK_SIZE] PG_ALIGN; + struct { + _RegSet *tf; + _Protect as; + uintptr_t cur_brk; + // we do not free memory, so use `max_brk' to determine whether to call mm_malloc() + uintptr_t max_brk; + }; +} PCB; + +extern PCB *current; + +#endif diff --git a/apps/nanos-lite/src/device.c b/apps/nanos-lite/src/device.c new file mode 100644 index 00000000..678e46fb --- /dev/null +++ b/apps/nanos-lite/src/device.c @@ -0,0 +1,46 @@ +#include "common.h" + +#define NAME(key) \ + [_KEY_##key] = #key, + +const char *names[256] = { + [_KEY_NONE] = "NONE", + _KEYS(NAME) +}; + +static unsigned long last_time_ms = 0; + +size_t read_events(void *buf) { + int key = _read_key(); + char keydown_char = (key & 0x8000 ? 'd' : 'u'); + key &= ~0x8000; + if (key != _KEY_NONE) { + if (key == _KEY_F12 && keydown_char == 'u') { + extern void change_game(void); + change_game(); + } + return sprintf(buf, "k%c %s\n", keydown_char, names[key]) - 1; + } + else { + unsigned long time_ms; + while ( (time_ms = _uptime()) - last_time_ms < 33 ); + last_time_ms = time_ms; + return sprintf(buf, "t %d\n", time_ms) - 1; + } +} + +static char dispinfo[128]; + +void dispinfo_read(void *buf, off_t offset, size_t len) { + memcpy(buf, dispinfo + offset, len); +} + +void fb_write(const void *buf, off_t offset, size_t len) { + offset /= sizeof(uint32_t); + _draw_rect(buf, offset % _screen.width, offset / _screen.width, len / sizeof(uint32_t), 1); +} + +void init_device() { + _ioe_init(); + sprintf(dispinfo, "WIDTH: %d\nHEIGHT: %d", _screen.width, _screen.height); +} diff --git a/apps/nanos-lite/src/event.c b/apps/nanos-lite/src/event.c deleted file mode 100644 index 1ccbdc42..00000000 --- a/apps/nanos-lite/src/event.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "common.h" - -#define NAME(key) \ - [_KEY_##key] = #key, - -const char *names[256] = { - [_KEY_NONE] = "NONE", - _KEYS(NAME) -}; - -size_t read_events(void *buf) { - uint32_t time_ms = _uptime(); - int key = _read_key(); - char keydown_char = (key & 0x8000 ? 'd' : 'u'); - key &= ~0x8000; - - return sprintf(buf, "t %d\nk%c %s ", time_ms, keydown_char, names[key]); -} diff --git a/apps/nanos-lite/src/fs.c b/apps/nanos-lite/src/fs.c index 938532cf..0e5ed158 100644 --- a/apps/nanos-lite/src/fs.c +++ b/apps/nanos-lite/src/fs.c @@ -7,28 +7,43 @@ typedef struct { } file_info; typedef struct { - bool used; uint32_t index; off_t offset; } Fstate; -extern uint32_t* const fb; - /* This is the information about all files in disk. */ -static const file_info file_table[] __attribute__((used)) = { - {"/dev/fb", 320 * 200 * sizeof(*fb), 0}, +static file_info file_table[] __attribute__((used)) = { + {"/dev/fb", 0, 0}, {"/dev/events", 0, 0}, + {"/proc/dispinfo", 128, 0}, #include "files.h" }; #define NR_FILES (sizeof(file_table) / sizeof(file_table[0])) -enum {FD_STDIN, FD_STDOUT, FD_STDERR, FD_FB, FD_EVENTS, FD_NORMAL}; +enum {FD_STDIN, FD_STDOUT, FD_STDERR, FD_FB, FD_EVENTS, FD_DISPINFO, FD_NORMAL}; Fstate files[FD_NORMAL + NR_FILES]; +void init_fs() { + int i; + for (i = 0; i < NR_FILES; i ++) { + if (strcmp(file_table[i].name, "/dev/fb") == 0) { + file_table[i].size = _screen.width * _screen.height * sizeof(uint32_t); + return; + } + } +} + + +size_t fs_filesz(int fd) { + return file_table[ files[fd].index ].size; +} + void ramdisk_read(void *, uint32_t, uint32_t); void ramdisk_write(const void *, uint32_t, uint32_t); size_t read_events(void *buf); +void dispinfo_read(void *buf, off_t offset, size_t len); +void fb_write(const void *buf, off_t offset, size_t len); int fs_open(const char *pathname, int flags, int mode) { int i, fd; @@ -37,10 +52,9 @@ int fs_open(const char *pathname, int flags, int mode) { switch (i) { case 0: fd = FD_FB; break; case 1: fd = FD_EVENTS; break; + case 2: fd = FD_DISPINFO; break; default: fd = FD_NORMAL + i; break; } - assert(files[fd].used == false); - files[fd].used = true; files[fd].index = i; files[fd].offset = 0; return fd; @@ -60,7 +74,12 @@ ssize_t fs_read(int fd, void *buf, size_t len) { int remain_bytes = file_table[ files[fd].index ].size - files[fd].offset; int bytes_to_read = (remain_bytes > len ? len : remain_bytes); - ramdisk_read(buf, file_table[files[fd].index].disk_offset + files[fd].offset, bytes_to_read); + if (fd == FD_DISPINFO) { + dispinfo_read(buf, file_table[files[fd].index].disk_offset + files[fd].offset, bytes_to_read); + } + else { + ramdisk_read(buf, file_table[files[fd].index].disk_offset + files[fd].offset, bytes_to_read); + } files[fd].offset += bytes_to_read; return bytes_to_read; } @@ -78,7 +97,7 @@ ssize_t fs_write(int fd, const void *buf, size_t len) { return len; case FD_FB: - memcpy((void *)fb + files[fd].offset, buf, bytes_to_write); + fb_write(buf, files[fd].offset, bytes_to_write); break; default: @@ -112,9 +131,5 @@ off_t fs_lseek(int fd, off_t offset, int whence) { } int fs_close(int fd) { - if(fd >= 0 && fd <= 2) return 0; - - assert(files[fd].used == true); - files[fd].used = false; return 0; } diff --git a/apps/nanos-lite/src/irq.c b/apps/nanos-lite/src/irq.c index d4a9f20c..28e3db6f 100644 --- a/apps/nanos-lite/src/irq.c +++ b/apps/nanos-lite/src/irq.c @@ -1,13 +1,14 @@ #include "common.h" -_RegSet* schedule(void); -void do_syscall(_RegSet *); +_RegSet* schedule(_RegSet *); +_RegSet* do_syscall(uintptr_t *); static _RegSet* do_event(_Event e, _RegSet* r) { _RegSet *ret = NULL; switch (e.event) { - case _EVENT_TRAP: ret = schedule(); break; - case _EVENT_SYSCALL: do_syscall(r); break; + case _EVENT_IRQ_TIME: ret = schedule(r); break; + case _EVENT_TRAP: ret = schedule(r); break; + case _EVENT_SYSCALL: ret = do_syscall((uintptr_t *)e.cause); break; default: panic("Unhandled event ID = %d", e.event); } diff --git a/apps/nanos-lite/src/loader.c b/apps/nanos-lite/src/loader.c index f49b56f7..fc9aa622 100644 --- a/apps/nanos-lite/src/loader.c +++ b/apps/nanos-lite/src/loader.c @@ -2,18 +2,24 @@ #include "memory.h" #include "fs.h" -#define INIT_FILE "/bin/pal" - void ramdisk_read(void *, off_t, size_t); -#define STACK_SIZE (128 * PGSIZE) +#define DEFAULT_ENTRY ((void *)0x8048000) -uintptr_t loader() { - Log("Loading user program %s...", INIT_FILE); +uintptr_t loader(_Protect *as, const char *filename) { + Log("Loading user program %s...", filename); - extern uint8_t ramdisk_start; - extern uint8_t ramdisk_end; - ramdisk_read((void *)0x4000000, 0, &ramdisk_end - &ramdisk_start); + int fd = fs_open(filename, 0, 0); - return 0x4000000; + size_t size = fs_filesz(fd); + size_t i; + for (i = 0; i < size; i += PGSIZE) { + void *pa = new_page(); + _map(as, DEFAULT_ENTRY + i, pa); + fs_read(fd, pa, PGSIZE); + } + + fs_close(fd); + + return (uintptr_t)DEFAULT_ENTRY; } diff --git a/apps/nanos-lite/src/main.c b/apps/nanos-lite/src/main.c index 91bab44b..b32ec9e8 100644 --- a/apps/nanos-lite/src/main.c +++ b/apps/nanos-lite/src/main.c @@ -1,10 +1,14 @@ #include "common.h" void init_mm(void); +void init_device(void); void init_irq(void); -void load_first_prog(void); +void init_fs(void); +void load_prog(const char *); int main() { + init_mm(); + Log("'Hello World!' from Nanos-lite"); Log("Build time: %s, %s", __TIME__, __DATE__); @@ -13,12 +17,16 @@ int main() { Log("ramdisk info: start = %p, end = %p, size = %d bytes", &ramdisk_start, &ramdisk_end, &ramdisk_end - &ramdisk_start); - _ioe_init(); + init_device(); Log("Initializing interrupt/exception handler..."); init_irq(); - load_first_prog(); + init_fs(); + + load_prog("/bin/pal"); + load_prog("/bin/hello"); + load_prog("/bin/litenes"); _trap(); diff --git a/apps/nanos-lite/src/mm.c b/apps/nanos-lite/src/mm.c index 4c414d98..7ce6fd39 100644 --- a/apps/nanos-lite/src/mm.c +++ b/apps/nanos-lite/src/mm.c @@ -1,10 +1,7 @@ +#include "proc.h" #include "memory.h" static void *pf = NULL; -static _Protect user_as; // user process address space -_Protect* get_user_as(void) { - return &user_as; -} void* new_page(void) { assert(pf < (void *)PMEM_SIZE); @@ -17,37 +14,21 @@ void free_page(void *p) { panic("not implement yet"); } -void* kmalloc(uint32_t size) { - assert(size > 0); - - void *pa = new_page(); - uint32_t alloc_size = PGSIZE; - for (; alloc_size < size; alloc_size += PGSIZE) { - new_page(); - } - - return pa; -} - -static uintptr_t cur_brk = 0; -// we do not free memory, so use `max_brk' to determine whether to call mm_malloc() -static uintptr_t max_brk = 0; - /* The brk() system call handler. */ bool mm_brk(uint32_t new_brk) { - if(cur_brk == 0) { - cur_brk = max_brk = new_brk; + if(current->cur_brk == 0) { + current->cur_brk = current->max_brk = new_brk; } else { - if (new_brk > max_brk) { - uintptr_t page_start = PGROUNDUP(max_brk); + if (new_brk > current->max_brk) { + uintptr_t page_start = PGROUNDUP(current->max_brk); uintptr_t page_end = PGROUNDUP(new_brk); for (; page_start <= page_end; page_start += PGSIZE) { - _map(&user_as, (void *)page_start, new_page()); + _map(¤t->as, (void *)page_start, new_page()); } - max_brk = new_brk; + current->max_brk = new_brk; } - cur_brk = new_brk; + current->cur_brk = new_brk; } // success @@ -55,9 +36,9 @@ bool mm_brk(uint32_t new_brk) { } void init_mm() { + _pte_init(new_page, free_page); + extern char _end; pf = (void *)PGROUNDUP((uintptr_t)&_end); Log("free physical pages starting from %p", pf); - - _pte_init(new_page, free_page); } diff --git a/apps/nanos-lite/src/proc.c b/apps/nanos-lite/src/proc.c index 66c8bebf..2440c726 100644 --- a/apps/nanos-lite/src/proc.c +++ b/apps/nanos-lite/src/proc.c @@ -1,23 +1,48 @@ -#include "common.h" +#include "proc.h" -#define NR_PROC 4 -#define STACK_SIZE (128 * PGSIZE) +#define MAX_NR_PROC 4 -_RegSet* pcb[NR_PROC]; +PCB pcb[MAX_NR_PROC]; +PCB *current = NULL; +int nr_proc = 0; -uintptr_t loader(void); +uintptr_t loader(_Protect *as, const char *filename); -void load_first_prog() { - uintptr_t entry = loader(); +void load_prog(const char *filename) { + int i = nr_proc ++; + _protect(&pcb[i].as); + + uintptr_t entry = loader(&pcb[i].as, filename); _Area stack; - stack.end = _heap.end; - stack.start = stack.end - STACK_SIZE; + stack.start = pcb[i].stack; + stack.end = stack.start + sizeof(pcb[i].stack); - pcb[0] = _make(stack, (void *)entry, NULL); + pcb[i].tf = _make(stack, (void *)entry, NULL); } -_RegSet* schedule() { - Log("schedule"); - return pcb[0]; +static int cnt = 0; +static PCB* game_pcb = &pcb[0]; + +void change_game() { + Log("game change!"); + game_pcb = (game_pcb == &pcb[0] ? &pcb[2] : &pcb[0]); +} + +_RegSet* schedule(_RegSet *prev) { + // when current == NULL at the very beginning, it will not cover + // any valid data, so it will be safe to write to memory near NULL + current->tf = prev; + if (current == game_pcb) { + cnt ++; + if (cnt == 200) { + current = &pcb[1]; + cnt = 0; + } + } + else { + current = game_pcb; + } + _switch(¤t->as); + return current->tf; } diff --git a/apps/nanos-lite/src/syscall.c b/apps/nanos-lite/src/syscall.c index a242e7de..4e41e427 100644 --- a/apps/nanos-lite/src/syscall.c +++ b/apps/nanos-lite/src/syscall.c @@ -37,18 +37,19 @@ int sys_brk(uintptr_t brk) { return mm_brk(brk); } -void do_syscall(_RegSet *r) { +_RegSet* do_syscall(uintptr_t *args) { int ret = 0; - switch (r->eax) { - case SYS_exit: sys_exit(r->ebx); break; - case SYS_read: ret = sys_read(r->ebx, (void *)r->ecx, r->edx); break; - case SYS_write: ret = sys_write(r->ebx, (const void *)r->ecx, r->edx); break; - case SYS_open: ret = sys_open((const char *)r->ebx, r->ecx, r->edx); break; - case SYS_lseek: ret = sys_lseek(r->ebx, r->ecx, r->edx); break; - case SYS_close: ret = sys_close(r->ebx); break; - case SYS_brk: ret = sys_brk(r->ebx); break; - default: panic("Unhandled syscall ID = %d, eip = 0x%08x", r->eax, r->eip); + switch (args[0]) { + case SYS_exit: sys_exit(args[1]); break; + case SYS_read: ret = sys_read(args[1], (void *)args[2], args[3]); break; + case SYS_write: ret = sys_write(args[1], (const void *)args[2], args[3]); break; + case SYS_open: ret = sys_open((const char *)args[1], args[2], args[3]); break; + case SYS_lseek: ret = sys_lseek(args[1], args[2], args[3]); break; + case SYS_close: ret = sys_close(args[1]); break; + case SYS_brk: ret = sys_brk(args[1]); break; + default: panic("Unhandled syscall ID = %d", args[0]); } - r->eax = ret; + args[0] = ret; + return NULL; }