From ee3ffc891299b9aa9126af1b8835eee4a0119be5 Mon Sep 17 00:00:00 2001 From: cl3nn0 Date: Thu, 9 Jun 2022 17:12:11 +0800 Subject: [PATCH 1/2] lab 5 & 6 --- bootloader/main.c | 16 ++- bootloader/makefile | 2 +- config.txt | 2 +- include/buddy.h | 1 + include/cpio.h | 12 ++- include/dtb.h | 4 + include/esr.h | 10 ++ include/exception.h | 31 ++++-- include/gpio.h | 3 +- include/malloc.h | 3 + include/mbox.h | 8 +- include/mmu.h | 63 +++++++++++ include/reset.h | 22 ++-- include/sched.h | 60 +++++++++++ include/shell.h | 22 +--- include/signal.h | 16 +++ include/simple_alloc.h | 1 + include/string.h | 142 ++---------------------- include/syscall.h | 24 +++++ include/task.h | 2 + include/timer.h | 8 +- include/tpf.h | 11 ++ include/uart.h | 6 +- initramfs.cpio | Bin 68096 -> 248320 bytes kernel/boot.s | 239 ++++++++--------------------------------- kernel/buddy.c | 31 +++--- kernel/cpio.c | 35 +++++- kernel/ctx_switch.s | 57 ++++++++++ kernel/dtb.c | 4 +- kernel/entry.s | 196 +++++++++++++++++++++++++++++++++ kernel/exception.c | 83 +++++++++++--- kernel/linker.ld | 7 +- kernel/main.c | 18 +++- kernel/makefile | 12 ++- kernel/malloc.c | 52 +++++++-- kernel/mbox.c | 39 +++++-- kernel/mmu.c | 129 ++++++++++++++++++++++ kernel/reset.c | 16 +++ kernel/sched.c | 159 +++++++++++++++++++++++++++ kernel/shell.c | 89 +++++++++------ kernel/signal.c | 62 +++++++++++ kernel/string.c | 131 ++++++++++++++++++++++ kernel/syscall.c | 205 +++++++++++++++++++++++++++++++++++ kernel/task.c | 37 +++---- kernel/timer.c | 34 ++++-- kernel/uart.c | 35 +++--- makefile | 7 +- 47 files changed, 1628 insertions(+), 518 deletions(-) create mode 100644 include/esr.h create mode 100644 include/mmu.h create mode 100644 include/sched.h create mode 100644 include/signal.h create mode 100644 include/syscall.h create mode 100644 include/tpf.h create mode 100644 kernel/ctx_switch.s create mode 100644 kernel/entry.s create mode 100644 kernel/mmu.c create mode 100644 kernel/reset.c create mode 100644 kernel/sched.c create mode 100644 kernel/signal.c create mode 100644 kernel/string.c create mode 100644 kernel/syscall.c diff --git a/bootloader/main.c b/bootloader/main.c index 115257c39..7c1035969 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -1,9 +1,23 @@ +#include "uart.h" + extern char _kernel_start[]; // 0x80000 char* _dtb; +// little endian to unsigned int (4 bytes) +unsigned int LE_to_uint(char *s) { + unsigned int res = 0; + res += (unsigned int)(s[0] & 0xff); + res += (unsigned int)((s[1] & 0xff) << 8); + res += (unsigned int)((s[2] & 0xff) << 16); + res += (unsigned int)((s[3] & 0xff) << 24); + return res; +} + void load_kernel() { + char size_buf[5] = {0}; unsigned int size = 0; - uart_read(&size, 4); // read kernel8.img size + uart_read(size_buf, 4); // read kernel8.img size + size = LE_to_uint(size_buf); uart_write_string("[+] Get kernel8.img size : 0x"); uart_write_hex(size); uart_write_string("\r\n"); diff --git a/bootloader/makefile b/bootloader/makefile index 6e744a8a5..110f6ced6 100644 --- a/bootloader/makefile +++ b/bootloader/makefile @@ -1,4 +1,4 @@ -CROSS = aarch64-unknown-linux-gnu +CROSS = aarch64-linux-gnu CC = $(CROSS)-gcc CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles LD = $(CROSS)-ld diff --git a/config.txt b/config.txt index 13201285b..49fc25695 100644 --- a/config.txt +++ b/config.txt @@ -1,3 +1,3 @@ kernel=bootloader.img arm_64bit=1 -initramfs initramfs.cpio 0x2000000 \ No newline at end of file +initramfs initramfs.cpio 0x20000000 diff --git a/include/buddy.h b/include/buddy.h index 6526c04b1..d50d9ddca 100644 --- a/include/buddy.h +++ b/include/buddy.h @@ -1,5 +1,6 @@ #ifndef BUDDY_H #define BUDDY_H +#include "mmu.h" #include "dtb.h" #include "list.h" #include "math.h" diff --git a/include/cpio.h b/include/cpio.h index 898851bfb..b608184d3 100644 --- a/include/cpio.h +++ b/include/cpio.h @@ -1,8 +1,9 @@ #ifndef CPIO_H #define CPIO_H +#include "sched.h" #include "simple_alloc.h" -// #define INITRD_ADDR (0x8000000) // QEMU: 0x8000000, Rpi3: 0x20000000 +// QEMU: 0x8000000, Rpi3: 0x20000000 extern void* INITRD_ADDR; typedef struct cpio_newc_header { @@ -35,4 +36,13 @@ void cpio_ls_callback(char* param, cpio_newc_header* header, char* file_name, un void cpio_cat_callback(char* param, cpio_newc_header* header, char* file_name, unsigned int name_size, char* file_data, unsigned int data_size); void cpio_prog_callback(char* param, cpio_newc_header* header, char* file_name, unsigned int name_size, char* file_data, unsigned int data_size); +extern char *syscall_file_start_addr; +extern unsigned int syscall_file_size; +void cpio_get_file_start_callback(char* param, cpio_newc_header* header, char* file_name, unsigned int name_size, char* file_data, unsigned int data_size); +void cpio_get_file_size_callback(char* param, cpio_newc_header* header, char* file_name, unsigned int name_size, char* file_data, unsigned int data_size); +char* get_file_start(char* path); +unsigned int get_file_size(char* path); + +void cpio_exec_callback(char* param, cpio_newc_header* header, char* file_name, unsigned int name_size, char* file_data, unsigned int data_size); + #endif \ No newline at end of file diff --git a/include/dtb.h b/include/dtb.h index 8e3d69a14..73186299c 100644 --- a/include/dtb.h +++ b/include/dtb.h @@ -1,6 +1,10 @@ #ifndef DTB_H #define DTB_H +#include "mmu.h" +#include "uart.h" +#include "string.h" +extern char* DTB_ADDRESS; extern void* INITRD_ADDR; extern void* INITRD_END; diff --git a/include/esr.h b/include/esr.h new file mode 100644 index 000000000..47fe15490 --- /dev/null +++ b/include/esr.h @@ -0,0 +1,10 @@ +#ifndef ESR_H +#define ESR_H + +typedef struct { + unsigned int iss : 25, // Instruction specific syndrome + il : 1, // Instruction length bit + ec : 6; // Exception class +} esr_el1_t; + +#endif \ No newline at end of file diff --git a/include/exception.h b/include/exception.h index 8c9a6c6ee..588e859c8 100644 --- a/include/exception.h +++ b/include/exception.h @@ -1,10 +1,16 @@ #ifndef EXCEPTION_H #define EXCEPTION_H -#include "timer.h" +#include "tpf.h" +#include "esr.h" +#include "mmu.h" #include "uart.h" +#include "task.h" +#include "timer.h" +#include "sched.h" +#include "syscall.h" // https://github.com/Tekki/raspberrypi-documentation/blob/master/hardware/raspberrypi/bcm2836/QA7_rev3.4.pdf (p.16) -#define CORE0_INTERRUPT_SOURCE ((volatile unsigned int*)(0x40000060)) +#define CORE0_INTERRUPT_SOURCE ((volatile unsigned int*)(PHYS_TO_VIRT(0x40000060))) #define INTERRUPT_SOURCE_GPU (1<<8) #define INTERRUPT_SOURCE_CNTPNSIRQ (1<<1) @@ -14,7 +20,7 @@ number of 'normal' interrupt status bits have been added to this register. This pending base' register different from the other 'base' interrupt registers */ // https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf (p.112~115) -#define PBASE 0x3F000000 +#define PBASE PHYS_TO_VIRT(0x3F000000) #define IRQ_BASIC_PENDING ((volatile unsigned int*)(PBASE+0x0000B200)) #define IRQ_PENDING_1 ((volatile unsigned int*)(PBASE+0x0000B204)) #define IRQ_PENDING_2 ((volatile unsigned int*)(PBASE+0x0000B208)) @@ -27,10 +33,19 @@ pending base' register different from the other 'base' interrupt registers #define DISABLE_BASIC_IRQS ((volatile unsigned int*)(PBASE+0x0000B224)) #define IRQ_PENDING_1_AUX_INT (1<<29) -void sync_64_router(unsigned long long x0); -void irq_router(unsigned long long x0); +void sync_64_router(trapframe_t *tpf, unsigned long x1); +void irq_router(trapframe_t *tpf); void invalid_exception_router(unsigned long long x0); -void enable_interrupt(); -void disable_interrupt(); -#endif \ No newline at end of file +static inline void enable_interrupt() { + asm volatile("msr daifclr, 0xf"); +} +static inline void disable_interrupt() { + asm volatile("msr daifset, 0xf"); +} + +unsigned long long is_disable_interrupt(); +void lock(); +void unlock(); + +#endif diff --git a/include/gpio.h b/include/gpio.h index 435fdf7c0..29d7a405c 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -1,7 +1,8 @@ #ifndef GPIO_H #define GPIO_H +#include "mmu.h" -#define MMIO_BASE 0x3f000000 +#define MMIO_BASE PHYS_TO_VIRT(0x3f000000) #define GPIO_BASE (MMIO_BASE + 0x200000) #define GPFSEL0 ((volatile unsigned int*)(GPIO_BASE + 0x00)) diff --git a/include/malloc.h b/include/malloc.h index 7d039176f..495497d7e 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -15,6 +15,9 @@ void sc_init(); void *sc_alloc(int size); int sc_free(void *sc); +void *kmalloc(int size); +void kfree(void *ptr); + void sc_test(); #endif \ No newline at end of file diff --git a/include/mbox.h b/include/mbox.h index 715b67fbd..b398f0f2f 100644 --- a/include/mbox.h +++ b/include/mbox.h @@ -2,6 +2,8 @@ #define MAILBOX_H #include "gpio.h" +extern volatile unsigned int __attribute__((aligned(16))) mbox[72]; + #define VIDEOCORE_MBOX (MMIO_BASE + 0xB880) // MMIO base address + MAILBOX offset #define MAILBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX)) #define MAILBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10)) @@ -34,8 +36,8 @@ #define GET_BOARD_REVISION 0x00010002 #define GET_ARM_MEMORY 0x00010005 -unsigned int get_board_revision(volatile unsigned int [36]); -unsigned int get_arm_memory(volatile unsigned int [36]); -unsigned int mailbox_call(volatile unsigned int [36], unsigned char); +unsigned int get_board_revision(unsigned int* board_revision); +unsigned int get_arm_memory(unsigned int* base_addr,unsigned int* size); +unsigned int mailbox_call(unsigned char); #endif \ No newline at end of file diff --git a/include/mmu.h b/include/mmu.h new file mode 100644 index 000000000..44f45cea4 --- /dev/null +++ b/include/mmu.h @@ -0,0 +1,63 @@ +#ifndef MMU_H +#define MMU_H +#include "esr.h" +#include "uart.h" +#include "list.h" +#include "sched.h" +#include "string.h" +#include "malloc.h" +#include "exception.h" + +#define TCR_CONFIG_REGION_48bit (((64 - 48) << 0) | ((64 - 48) << 16)) +#define TCR_CONFIG_4KB ((0b00 << 14) | (0b10 << 30)) +#define TCR_CONFIG_DEFAULT (TCR_CONFIG_REGION_48bit | TCR_CONFIG_4KB) + +#define MAIR_DEVICE_nGnRnE 0b00000000 +#define MAIR_NORMAL_NOCACHE 0b01000100 +#define MAIR_IDX_DEVICE_nGnRnE 0 +#define MAIR_IDX_NORMAL_NOCACHE 1 +#define MAIR_CONFIG_DEFAULT ((MAIR_DEVICE_nGnRnE << (MAIR_IDX_DEVICE_nGnRnE * 8)) | (MAIR_NORMAL_NOCACHE << (MAIR_IDX_NORMAL_NOCACHE * 8))) + +#define PD_TABLE 0b11L +#define PD_BLOCK 0b01L +#define PD_UNX (1L << 54) +#define PD_KNX (1L << 53) +#define PD_ACCESS (1L << 10) +#define PD_UK_ACCESS (1L << 6) +#define PD_RDONLY (1L << 7) +#define BOOT_PGD_ATTR PD_TABLE +#define BOOT_PUD_ATTR (PD_ACCESS | (MAIR_IDX_DEVICE_nGnRnE << 2) | PD_BLOCK) + +#define PHYS_TO_VIRT(x) (x + 0xffff000000000000) +#define VIRT_TO_PHYS(x) (x - 0xffff000000000000) +#define ENTRY_ADDR_MASK 0xfffffffff000L + +#define kernel_pgd_addr 0x1000 +#define kernel_pud_addr 0x2000 + +#define DATA_ABORT_LOWER 0b100100 +#define INS_ABORT_LOWER 0b100000 + +#define TF_LEVEL0 0b000100 +#define TF_LEVEL1 0b000101 +#define TF_LEVEL2 0b000110 +#define TF_LEVEL3 0b000111 + +void *set_2M_kernel_mmu(void *x0); +void map_one_page(unsigned long *pgd_p, unsigned long va, unsigned long pa, unsigned long flag); +void add_vma(struct thread *t, unsigned long va, unsigned long size, unsigned long pa, unsigned long rwx, int is_alloced); +void free_page_tables(unsigned long *page_table, int level); +void handle_abort(esr_el1_t* esr_el1); +void map_one_page_rwx(unsigned long *pgd_p, unsigned long va, unsigned long pa, unsigned long rwxflag); +void seg_fault(); + +typedef struct vm_area_struct { + list_head_t listhead; + unsigned long virt_addr; + unsigned long phys_addr; + unsigned long area_size; + unsigned long rwx; // r = 1, w = 2, x = 4 + int is_alloced; +} vm_area_struct_t; + +#endif \ No newline at end of file diff --git a/include/reset.h b/include/reset.h index 120556c2a..b1210922a 100644 --- a/include/reset.h +++ b/include/reset.h @@ -1,23 +1,13 @@ #ifndef RESET_H #define RESET_H +#include "mmu.h" #define PM_PASSWORD 0x5a000000 -#define PM_RSTC 0x3f10001c -#define PM_WDOG 0x3f100024 +#define PM_RSTC PHYS_TO_VIRT(0x3f10001c) +#define PM_WDOG PHYS_TO_VIRT(0x3f100024) -void set(long addr, unsigned int value) { - volatile unsigned int* point = (unsigned int*)addr; - *point = value; -} - -void reset(int tick) { // reboot after watchdog timer expire - set(PM_RSTC, PM_PASSWORD | 0x20); // full reset - set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick -} - -void cancel_reset() { - set(PM_RSTC, PM_PASSWORD | 0); // full reset - set(PM_WDOG, PM_PASSWORD | 0); // number of watchdog tick -} +void set(long addr, unsigned int value); +void reset(int tick); +void cancel_reset(); #endif \ No newline at end of file diff --git a/include/sched.h b/include/sched.h new file mode 100644 index 000000000..7c6fc8ce8 --- /dev/null +++ b/include/sched.h @@ -0,0 +1,60 @@ +#ifndef SCHED_H +#define SCHED_H +#include "mmu.h" +#include "list.h" +#include "buddy.h" +#include "string.h" +#include "signal.h" +#include "malloc.h" +#include "exception.h" +#include "simple_alloc.h" + +#define PIDMAX 4096 +#define USTACK_SIZE 0x4000 +#define KSTACK_SIZE 0x4000 +#define SIGNAL_MAX 32 + +extern void switch_to(void *curr_context, void *next_context); +extern void store_context(void *curr_context); +extern void load_context(void *curr_context); +extern void *get_current(); + +typedef struct thread_context { + unsigned long x19, x20, x21, x22, x23, x24, x25, x26, x27, x28; + unsigned long fp, lr, sp; + void* ttbr0_el1; +} thread_context_t; + +typedef struct thread { + list_head_t listhead; + thread_context_t context; + char *data; + unsigned int datasize; + int iszombie; + int pid; + int isused; + char* stack_alloced_ptr; + char* kernel_stack_alloced_ptr; + void (*singal_handler[SIGNAL_MAX+1])(); + int sigcount[SIGNAL_MAX + 1]; + void (*curr_signal_handler)(); + int signal_is_checking; + list_head_t vma_list; + thread_context_t signal_saved_context; +} thread_t; + +extern thread_t *curr_thread; +extern list_head_t *run_queue; +extern list_head_t *wait_queue; +extern thread_t threads[PIDMAX + 1]; + +void init_thread_sched(); +void idle(); +void schedule(); +void kill_zombies(); +thread_t *thread_create(void *start, unsigned int filesize); +void thread_exit(); +int exec_thread(char *data, unsigned int filesize); +void schedule_timer(char *notuse); + +#endif diff --git a/include/shell.h b/include/shell.h index 97cdc33d3..56f775c64 100644 --- a/include/shell.h +++ b/include/shell.h @@ -6,6 +6,7 @@ #include "mbox.h" #include "reset.h" #include "string.h" +#include "sched.h" #include "timer.h" #include "buddy.h" #include "malloc.h" @@ -34,28 +35,11 @@ void cmd_async(); void cmd_prog(); void cmd_sec2(); void cmd_setTimeout(char* param); +void cmd_foo(); void cmd_preempt(); void cmd_pageTest(); void cmd_chunkTest(); +void cmd_exec(char* param); void cmd_unknown(); -struct cmd cmd_list[] = { - {"help", cmd_help, "print this help menu"}, - {"hello", cmd_hello, "print Hello World!"}, - // {"reboot", cmd_reboot, "reboot the device"}, - {"revision", cmd_revision, "print board revision"}, - {"memory", cmd_memory, "print ARM memory base address and size"}, - {"ls", cmd_ls, "list directory contents"}, - {"cat", cmd_cat, "print file content"}, - {"dtb", cmd_dtb, "show device tree"}, - {"initramfs", cmd_initramfs, "show initramfs address"}, - // {"async", cmd_async, "test async print"}, - {"prog", cmd_prog, "load a user program in the initramfs, and jump to it"}, - {"sec2", cmd_sec2, "print the seconds after booting and set the next timeout to 2 seconds later."}, - {"setTimeout",cmd_setTimeout,"prints message after seconds"}, - // {"preempt", cmd_preempt, "test preemption"}, - {"pageTest", cmd_pageTest, "test page frame allocator"}, - {"chunkTest", cmd_chunkTest, "test small chunk allocator"}, -}; - #endif \ No newline at end of file diff --git a/include/signal.h b/include/signal.h new file mode 100644 index 000000000..6261190c8 --- /dev/null +++ b/include/signal.h @@ -0,0 +1,16 @@ +#ifndef SIGNAL_H +#define SIGNAL_H +#include "tpf.h" +#include "sched.h" +#include "buddy.h" +#include "syscall.h" +#include "exception.h" + +#define USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED 0xffffffff9000L + +void check_signal(trapframe_t *tpf); +void run_signal(trapframe_t* tpf, int signal); +void signal_handler_wrapper(); +void signal_default_handler(); + +#endif \ No newline at end of file diff --git a/include/simple_alloc.h b/include/simple_alloc.h index c05aaed9d..980d03084 100644 --- a/include/simple_alloc.h +++ b/include/simple_alloc.h @@ -1,5 +1,6 @@ #ifndef SIMPLE_ALLOC_H #define SIMPLE_ALLOC_H +#include "uart.h" // from linker.ld extern char _simple_alloc_start; diff --git a/include/string.h b/include/string.h index fb9ca4402..e22fba17c 100644 --- a/include/string.h +++ b/include/string.h @@ -3,136 +3,16 @@ #define ENDL "\r\n" -void memcpy(char *s1, const char *s2, unsigned int len) { - for (unsigned int i = 0; i < len; i++) - s1[i] = s2[i]; -} - -void memset(char *s1, const char c, unsigned int len) { - for (unsigned int i = 0; i < len; i++) - s1[i] = c; -} - -unsigned int strlen(char *s) { - unsigned int len = 0; - while (1) { - if (*(s + len) == '\0') - break; - len++; - } - return len; -} - -int strcmp(const char *s1, const char *s2) { - unsigned int i = 0; - for (i = 0; i < strlen(s1); i++) { - if (s1[i] != s2[i]) - return s1[i] - s2[i]; - } - return s1[i] - s2[i]; -} - -int strncmp(const char *s1, const char *s2, unsigned int n) { - unsigned int i = 0; - for (i = 0; i < n; i++) { - if (s1[i] != s2[i]) - return s1[i] - s2[i]; - } - return 0; -} - -void strrev(char *s) { - unsigned int len = strlen(s); - char tmp; - for(unsigned int i = 0; i < len/2; i++){ - tmp = s[i]; - s[i] = s[len-i-1]; - s[len-i-1] = tmp; - } -} - -// string to int -int atoi(char* s) { - int res = 0; - for (int i = 0; s[i] != '\0'; ++i) { - if(s[i] > '9' || s[i] < '0') - return res; - res = res * 10 + s[i] - '0'; - } - return res; -} - -// int to string -char* itoa(int x) { - char str[MAX_BUF_SIZE]; - memset(str, 0, MAX_BUF_SIZE); - int i = 0, negative = 0; - // handle 0 explicitly - if (x == 0) { - str[i++] = '0'; - str[i] = '\0'; - return str; - } - // handle negative numbers - if (x < 0) { - negative = 1; - x = -x; - } - // process individual digits - while (x != 0) { - str[i++] = x % 10 + '0'; - x = x / 10; - } - if (negative) - str[i++] = '-'; - str[i] = '\0'; - strrev(str); - return str; -} - -// unsigned int to hex string -void uint_to_hex(unsigned int x, char *s) { - int i = 0, rem = 0, len = strlen(s); - memset(s, 0, len); - // handle 0 explicitly - if (x == 0) { - s[i++] = '0'; - s[i] = '\0'; - return ; - } - // process individual digits - while (x != 0) { - rem = x % 16; - if (rem >= 10) - s[i++] = rem - 10 + 'A'; - else - s[i++] = rem + '0'; - x = x / 16; - } - s[i] = '\0'; - strrev(s); -} - -// hex string to unsigned int -unsigned int hex_to_uint(const char *s, unsigned int size) { - unsigned int ret = 0; - for (unsigned int i = 0; i < size; i++) { - ret *= 16; - if (s[i] >= '0' && s[i] <= '9') { - ret += s[i] - '0'; - } else if (s[i] >= 'a' && s[i] <= 'f') { - ret += s[i] - 'a' + 10; - } else if (s[i] >= 'A' && s[i] <= 'F') { - ret += s[i] - 'A' + 10; - } - } - return ret; -} - -// big endian to unsigned int -unsigned int BE_to_uint(void *ptr) { - unsigned char *bytes = (unsigned char *)ptr; - return bytes[3] | bytes[2] << 8 | bytes[1] << 16 | bytes[0] << 24; -} +void memcpy(char *s1, char *s2, unsigned int len); +void memset(char *s1, char c, unsigned int len); +unsigned int strlen(char *s); +int strcmp(char *s1, char *s2); +int strncmp(char *s1, char *s2, unsigned int n); +void strrev(char *s); +int atoi(char* s); +char* itoa(int x, char *str); +void uint_to_hex(unsigned int x, char *s); +unsigned int hex_to_uint(char *s, unsigned int size); +unsigned int BE_to_uint(void *ptr); #endif \ No newline at end of file diff --git a/include/syscall.h b/include/syscall.h new file mode 100644 index 000000000..e0a9382a9 --- /dev/null +++ b/include/syscall.h @@ -0,0 +1,24 @@ +#ifndef SYSCALL_H +#define SYSCALL_H +#include "mmu.h" +#include "tpf.h" +#include "cpio.h" +#include "mbox.h" +#include "sched.h" +#include "buddy.h" +#include "exception.h" + +int getpid(trapframe_t *tpf); +unsigned long uartread(trapframe_t *tpf, char buf[], unsigned long size); +unsigned long uartwrite(trapframe_t *tpf, const char buf[], unsigned long size); +int exec(trapframe_t *tpf, const char *name, char *const argv[]); +int fork(trapframe_t *tpf); +void exit(trapframe_t *tpf, int status); +int syscall_mbox_call(trapframe_t *tpf, unsigned char ch, unsigned int *mbox); +void kill(trapframe_t *tpf, int pid); +void signal_register(int signal, void (*handler)()); +void signal_kill(int pid, int signal); +void sigreturn(trapframe_t *tpf); +void *sys_mmap(trapframe_t *tpf, void *addr, unsigned long len, int prot, int flags, int fd, int file_offset); + +#endif \ No newline at end of file diff --git a/include/task.h b/include/task.h index 255a2ff77..d743dd6d2 100644 --- a/include/task.h +++ b/include/task.h @@ -1,6 +1,8 @@ #ifndef TASK_H #define TASK_H #include "list.h" +#include "malloc.h" +#include "exception.h" #include "simple_alloc.h" typedef struct task { diff --git a/include/timer.h b/include/timer.h index 501fc3e3a..b9b41306a 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,10 +1,14 @@ #ifndef TIMER_H #define TIMER_H +#include "mmu.h" +#include "uart.h" #include "list.h" +#include "string.h" +#include "malloc.h" #include "simple_alloc.h" // https://github.com/Tekki/raspberrypi-documentation/blob/master/hardware/raspberrypi/bcm2836/QA7_rev3.4.pdf (p.13) -#define CORE0_TIMER_IRQ_CTRL 0x40000040 +#define CORE0_TIMER_IRQ_CTRL PHYS_TO_VIRT(0x40000040) #define STR(x) #x #define XSTR(s) STR(s) @@ -22,7 +26,7 @@ void core_timer_enable(); void core_timer_disable(); void core_timer_handler(); -void add_timer(void *function, unsigned long long timeout, char *args); +void add_timer(void *function, unsigned long long timeout, char *args, int bytick); void set_core_timer_interrupt_abs(unsigned long long tick); void set_core_timer_interrupt_rel(unsigned long long expired_time); unsigned long long get_tick_plus_s(unsigned long long second); diff --git a/include/tpf.h b/include/tpf.h new file mode 100644 index 000000000..dee9bb95e --- /dev/null +++ b/include/tpf.h @@ -0,0 +1,11 @@ +#ifndef TPF_H +#define TPF_H + +typedef struct trapframe { + unsigned long x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; + unsigned long x11, x12, x13, x14, x15, x16, x17, x18, x19, x20; + unsigned long x21, x22, x23, x24, x25, x26, x27, x28, x29, x30; + unsigned long spsr_el1, elr_el1, sp_el0; +} trapframe_t; + +#endif \ No newline at end of file diff --git a/include/uart.h b/include/uart.h index a642e6518..c9837fc08 100644 --- a/include/uart.h +++ b/include/uart.h @@ -1,10 +1,12 @@ #ifndef UART_H #define UART_H #include "gpio.h" +#include "sprintf.h" +#include "exception.h" -#define MAX_BUF_SIZE 0x100 +#define MAX_BUF_SIZE 0x1000 -#define IRQS1 ((volatile unsigned int*)(0x3f00b210)) +#define IRQS1 ((volatile unsigned int*)(PHYS_TO_VIRT(0x3f00b210))) #define AUX_BASE (MMIO_BASE + 0x00215000) diff --git a/initramfs.cpio b/initramfs.cpio index c755722c9ac2b79e0f33afa544a532c06e3789ef..011046531134dab1c4c5801d992bc8dfa44a9c3c 100644 GIT binary patch literal 248320 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 literal 68096 zcmeIy%We}_7{Kw*xwO=5+KNS_E*K*u+6oP4oJs6ZRWd?BLW+t6S#(#;#7-L7!I5nt zR|vr)&{ycT55Oz1Mmz*t!~=wLwLKG)I8hf}{7)30+jlPWn=?l>R6`|7HS)Zk)s;?Z z(rKGqCHosTS4rw}wY6DK)2+jai_O0I=$T9d9YNen4(Qf@Bp&{CG|FTtW7Hh!mz^Tz+<$JeHzwp1Rk8u~9$s*&gQtf_QrCRu87mF#cWTqUlqTQ=)yx|NxD zo$4Let=oOU$A{)gz7K7Uws$ z<+*Rrw4auB+nL#vpU%8ncdmUy$S!c8<90U6B+iG!F!=KM>2vMoYWXR{`3ozQ&vi|A zn5QfY{2m6B^0LS+-EYqNWyhQO=6zRT{nvi|Rh^svMZc>Lew?|7W>b0pU;3^-`9Zg5 z2kUZqeBryY=YQevN;NY7y*B9 z!Drr_-X-07Cf)U{xNgJrH;75KGufM(^bVhPJA=5_)_ZueeSi1i zqu-uXpX;*{N54jDY diff --git a/kernel/boot.s b/kernel/boot.s index 76d3b9775..57d933a3f 100644 --- a/kernel/boot.s +++ b/kernel/boot.s @@ -1,3 +1,4 @@ +#include "mmu.h" .section ".text.boot" .global _start @@ -15,13 +16,56 @@ _start: 2: bl from_el2_to_el1 + // set tcr_el1 to TCR_CONFIG_DEFAULT (0x0000000080100010) + movz x4, 0x0010 + movk x4, 0x8010, lsl 16 + msr tcr_el1, x4 + + // set memory attributes to MAIR_CONFIG_DEFAULT (0x0000000000004400) + movz x4, 0x4400 + msr mair_el1, x4 + + // enable MMU + mov x4, 0x1000 // PGD's page frame at 0x1000 + mov x1, 0x2000 // PUD's page frame at 0x2000 + + // ldr x2, = BOOT_PGD_ATTR + movz x2, 0x0003 + orr x2, x1, x2 // combine the physical address of next level page with attribute. + str x2, [x4] + + // ldr x2, = BOOT_PUD_ATTR + movz x2, 0x0401 + mov x3, 0x00000000 + orr x3, x2, x3 + str x3, [x1] // 1st 1GB mapped by the 1st entry of PUD + mov x3, 0x40000000 + orr x3, x2, x3 + str x3, [x1, 8] // 2nd 1GB mapped by the 2nd entry of PUD + + msr ttbr0_el1, x4 // load PGD to the bottom translation-based register. + msr ttbr1_el1, x4 // also load PGD to the upper translation based register. + + mov sp, 0x3c000000 + bl set_2M_kernel_mmu + + mrs x2, sctlr_el1 + orr x2 , x2, 1 + msr sctlr_el1, x2 // enable MMU, cache remains disabled + + // indirect branch to the upper VA + ldr x2, =set_exception_vector_table + br x2 + set_exception_vector_table: adr x1, exception_vector_table msr vbar_el1, x1 - // set top of stack just before our code (stack grows to a lower address per AAPCS64) - ldr x1, =_start - mov sp, x1 + // set top of stack at 0xffff00003c000000 (last usable memory) + movz x3, 0x0000 + movk x3, 0x3c00, lsl 16 + movk x3, 0xffff, lsl 48 + mov sp, x3 // clear bss ldr x1, =_bss_start @@ -47,192 +91,3 @@ from_el2_to_el1: msr spsr_el2, x1 msr elr_el2, lr eret // return to EL1 - -// save general registers to stack -.macro save_all - sub sp, sp, 32 * 9 - stp x0, x1, [sp ,16 * 0] - stp x2, x3, [sp ,16 * 1] - stp x4, x5, [sp ,16 * 2] - stp x6, x7, [sp ,16 * 3] - stp x8, x9, [sp ,16 * 4] - stp x10, x11, [sp ,16 * 5] - stp x12, x13, [sp ,16 * 6] - stp x14, x15, [sp ,16 * 7] - stp x16, x17, [sp ,16 * 8] - stp x18, x19, [sp ,16 * 9] - stp x20, x21, [sp ,16 * 10] - stp x22, x23, [sp ,16 * 11] - stp x24, x25, [sp ,16 * 12] - stp x26, x27, [sp ,16 * 13] - stp x28, x29, [sp ,16 * 14] - str x30, [sp, 16 * 15] - -// for nested interrupt - mrs x0, spsr_el1 - str x0, [sp, 16 * 16] - mrs x0, elr_el1 - str x0, [sp, 16 * 17] - ldp x0, x1, [sp ,16 * 0] -.endm - -// load general registers from stack -.macro load_all - ldp x0, x1, [sp ,16 * 0] - ldp x2, x3, [sp ,16 * 1] - ldp x4, x5, [sp ,16 * 2] - ldp x6, x7, [sp ,16 * 3] - ldp x8, x9, [sp ,16 * 4] - ldp x10, x11, [sp ,16 * 5] - ldp x12, x13, [sp ,16 * 6] - ldp x14, x15, [sp ,16 * 7] - ldp x16, x17, [sp ,16 * 8] - ldp x18, x19, [sp ,16 * 9] - ldp x20, x21, [sp ,16 * 10] - ldp x22, x23, [sp ,16 * 11] - ldp x24, x25, [sp ,16 * 12] - ldp x26, x27, [sp ,16 * 13] - ldp x28, x29, [sp ,16 * 14] - ldr x30, [sp, 16 * 15] - -// for nested interrupt - ldr x0, [sp, 16 * 16] - msr spsr_el1, x0 - ldr x0, [sp, 16 * 17] - msr elr_el1, x0 - ldp x0, x1, [sp ,16 * 0] - - add sp, sp, 32 * 9 -.endm - -.macro ventry label - .align 7 - b \label -.endm - -.align 11 // vector table should be aligned to 0x800 -.global exception_vector_table -exception_vector_table: - // Exception from the current EL while using SP_EL0 - ventry sync_el1t_invalid // Synchronous EL1t - ventry irq_el1t_invalid // IRQ EL1t - ventry fiq_el1t_invalid // FIQ EL1t - ventry err_el1t_invalid // Error EL1t - - // Exception from the current EL while using SP_ELx - ventry sync_el1h_invalid // Synchronous EL1h - ventry irq_el1h // IRQ EL1h - ventry fiq_el1h_invalid // FIQ EL1h - ventry err_el1h_invalid // Error EL1h - - // Exception from a lower EL and at least one lower EL is AArch64 - ventry sync_el0_64 // Synchronous 64-bit EL0 - ventry irq_el0_64 // IRQ 64-bit EL0 - ventry fiq_el0_64_invalid // FIQ 64-bit EL0 - ventry err_el0_64_invalid // Error 64-bit EL0 - - // Exception from a lower EL and at least all lower EL are AArch32 - ventry sync_el0_32_invalid // Synchronous 32-bit EL0 - ventry irq_el0_32_invalid // IRQ 32-bit EL0 - ventry fiq_el0_32_invalid // FIQ 32-bit EL0 - ventry err_el0_32_invalid // Error 32-bit EL0 - -sync_el1t_invalid: - save_all - mov x0, 1 - bl invalid_exception_router - load_all - eret -irq_el1t_invalid: - save_all - mov x0, 2 - bl invalid_exception_router - load_all - eret -fiq_el1t_invalid: - save_all - mov x0, 3 - bl invalid_exception_router - load_all - eret -err_el1t_invalid: - save_all - mov x0, 4 - bl invalid_exception_router - load_all - eret - -sync_el1h_invalid: - save_all - mov x0, 5 - bl invalid_exception_router - load_all - eret -irq_el1h: - save_all - mov x0, 6 - bl irq_router - load_all - eret -fiq_el1h_invalid: - save_all - mov x0, 7 - bl invalid_exception_router - load_all - eret -err_el1h_invalid: - save_all - mov x0, 8 - bl invalid_exception_router - load_all - eret - -sync_el0_64: - save_all - mov x0, 9 - bl sync64_router - load_all - eret -irq_el0_64: - save_all - mov x0, 10 - bl irq_router - load_all - eret -fiq_el0_64_invalid: - save_all - mov x0, 11 - bl invalid_exception_router - load_all - eret -err_el0_64_invalid: - save_all - mov x0, 12 - bl invalid_exception_router - load_all - eret - -sync_el0_32_invalid: - save_all - mov x0, 13 - bl invalid_exception_router - load_all - eret -irq_el0_32_invalid: - save_all - mov x0, 14 - bl invalid_exception_router - load_all - eret -fiq_el0_32_invalid: - save_all - mov x0, 15 - bl invalid_exception_router - load_all - eret -err_el0_32_invalid: - save_all - mov x0, 16 - bl invalid_exception_router - load_all - eret diff --git a/kernel/buddy.c b/kernel/buddy.c index 594fcde18..dd64edbea 100644 --- a/kernel/buddy.c +++ b/kernel/buddy.c @@ -91,7 +91,7 @@ void page_alloc_init() { } void *alloc_pages(int num) { - uart_printf("------------ In function alloc_pages(%d) ------------\r\n", num); + // uart_printf_async("------------ In function alloc_pages(%d) ------------\r\n", num); int idx, exp, alloc_exp; frame_hdr *hdr; @@ -113,7 +113,7 @@ void *alloc_pages(int num) { return 0; // start allocate - hdr = freelists[alloc_exp].next; + hdr = (frame_hdr *)freelists[alloc_exp].next; idx = addr_to_idx(hdr); list_del_entry(&hdr->list); @@ -130,12 +130,12 @@ void *alloc_pages(int num) { buddy_hdr = idx_to_addr(buddy_idx); list_add(&buddy_hdr->list, &freelists[alloc_exp]); - uart_printf("[-] Release redundant memory (idx : %d -> %d), this block has exp : %d\r\n", idx, buddy_idx, alloc_exp); + // uart_printf_async("[-] Release redundant memory (idx : %d -> %d), this block has exp : %d\r\n", idx, buddy_idx, alloc_exp); } frame_ents[idx].exp = exp; frame_ents[idx].allocated = 1; - uart_printf("[+] Successfully allocate (idx : %d, exp : %d)\r\n", idx, exp); + // uart_printf_async("[+] Successfully allocate (idx : %d, exp : %d)\r\n", idx, exp); return (void *)hdr; } @@ -149,7 +149,7 @@ static inline void _free_page(frame_hdr *page) { buddy_idx = idx ^ (1 << exp); // merge while (exp < MAX_ORDER - 1 && !frame_ents[buddy_idx].allocated && frame_ents[buddy_idx].exp == exp) { - uart_printf("[*] Coalesce blocks (idx : %d & %d), and their new exp is %d\r\n", idx, buddy_idx, exp + 1); + // uart_printf_async("[*] Coalesce blocks (idx : %d & %d), and their new exp is %d\r\n", idx, buddy_idx, exp + 1); frame_hdr *hdr; exp += 1; hdr = idx_to_addr(idx); @@ -166,11 +166,12 @@ static inline void _free_page(frame_hdr *page) { } void free_page(void *page) { - uart_printf("++++++++++++ In function free_page(idx = %d) ++++++++++++\r\n", addr_to_idx(page)); + // uart_printf_async("++++++++++++ In function free_page(idx = %d) ++++++++++++\r\n", addr_to_idx(page)); _free_page((frame_hdr *)page); } void memory_reserve(void *start, void *end) { + uart_printf("Reserve => 0x%x ~ 0x%x\r\n", (unsigned long long int)start, (unsigned long long int)end); start = (void *)((unsigned long long int)start & ~(PAGE_SIZE - 1)); end = (void *)ALIGN((unsigned long long int)end, PAGE_SIZE); // allocated all pages from start to end @@ -178,23 +179,27 @@ void memory_reserve(void *start, void *end) { int idx = addr_to_idx(start); frame_ents[idx].allocated = 1; start = (void *)((unsigned long long int)start + PAGE_SIZE); - // uart_printf("Reserve page idx : %d, address : 0x%x\r\n", idx, idx_to_addr(idx)); + // uart_printf_async("Reserve page idx : %d, address : 0x%x\r\n", idx, idx_to_addr(idx)); } } void mm_init() { // buddy system first stage init - buddy_alloc_init((void *)0, (void *)0x3c000000); + buddy_alloc_init((void *)PHYS_TO_VIRT(0), (void *)PHYS_TO_VIRT(0x3c000000)); // small chunk first stage init sc_alloc_init(); // Spin tables for multicore boot - memory_reserve((void *)0, (void *)0x1000); + memory_reserve((void *)PHYS_TO_VIRT(0), (void *)PHYS_TO_VIRT(0x5000)); // Kernel image in the physical memory memory_reserve(&_text_start, &_heap_start); // Initramfs memory_reserve(INITRD_ADDR, INITRD_END); + // Device tree (qemu = 83580, rpi3 = 32937) + memory_reserve(DTB_ADDRESS, DTB_ADDRESS + 83580); // for simple_alloc - memory_reserve((void *)0x3b000000, (void *)0x3c000000); + memory_reserve((void *)PHYS_TO_VIRT(0x2c000000), (void *)PHYS_TO_VIRT(0x2e000000)); + // for kernel stack + memory_reserve((void *)PHYS_TO_VIRT(0x2e000000), (void *)PHYS_TO_VIRT(0x3c000000)); // buddy system second stage init page_alloc_init(); // small chunk second stage init @@ -211,7 +216,7 @@ void page_allocator_test() char *ptr5 = alloc_pages(2); // idx = 32786 char *ptr6 = alloc_pages(1); // idx = 32785 - uart_printf("------------------------------------------------------------\r\n"); + // uart_printf_async("------------------------------------------------------------\r\n"); // test alloc_pages -> release redundant memory free_page(ptr3); // idx = 4 (idx 5, 6, 7 are also freed) @@ -219,14 +224,14 @@ void page_allocator_test() char *ptr8 = alloc_pages(2); // idx = 6 char *ptr9 = alloc_pages(1); // idx = 5 - uart_printf("------------------------------------------------------------\r\n"); + // uart_printf_async("------------------------------------------------------------\r\n"); // test free_page -> coalesce blocks free_page(ptr7); free_page(ptr8); free_page(ptr9); - uart_printf("------------------------------------------------------------\r\n"); + // uart_printf_async("------------------------------------------------------------\r\n"); // free all pointer free_page(ptr1); diff --git a/kernel/cpio.c b/kernel/cpio.c index 380151633..ee4cc7891 100644 --- a/kernel/cpio.c +++ b/kernel/cpio.c @@ -2,6 +2,9 @@ cpio_newc_header* header; +char *syscall_file_start_addr; +unsigned int syscall_file_size; + void cpio_init() { header = 0; } @@ -34,7 +37,7 @@ void cpio_newc_parser(cpio_callback_t callback, char* param) { } void cpio_newc_parse_header(char** cpio_ptr, cpio_newc_header** header) { - *header = *cpio_ptr; + *header = (cpio_newc_header *)*cpio_ptr; *cpio_ptr += sizeof(cpio_newc_header); } @@ -59,7 +62,7 @@ void cpio_cat_callback(char* param, cpio_newc_header* header, char* file_name, u uart_write_string("\r\n"); else uart_write_char(*file_data); - *file_data++; + file_data++; } uart_printf("\r\n"); } @@ -77,3 +80,31 @@ void cpio_prog_callback(char* param, cpio_newc_header* header, char* file_name, :: "r" (file_data), "r" (prog_stack + 0x10000) ); } + +void cpio_get_file_start_callback(char* param, cpio_newc_header* header, char* file_name, unsigned int name_size, char* file_data, unsigned int data_size) { + if (strcmp(file_name, param)) + return; + syscall_file_start_addr = file_data; +} + +void cpio_get_file_size_callback(char* param, cpio_newc_header* header, char* file_name, unsigned int name_size, char* file_data, unsigned int data_size) { + if (strcmp(file_name, param)) + return; + syscall_file_size = data_size; +} + +char* get_file_start(char* path) { + cpio_newc_parser(cpio_get_file_start_callback, path); + return syscall_file_start_addr; +} + +unsigned int get_file_size(char* path) { + cpio_newc_parser(cpio_get_file_size_callback, path); + return syscall_file_size; +} + +void cpio_exec_callback(char* param, cpio_newc_header* header, char* file_name, unsigned int name_size, char* file_data, unsigned int data_size) { + if (strcmp(file_name, param)) + return; + exec_thread(file_data, data_size); +} diff --git a/kernel/ctx_switch.s b/kernel/ctx_switch.s new file mode 100644 index 000000000..2cc3a6fe6 --- /dev/null +++ b/kernel/ctx_switch.s @@ -0,0 +1,57 @@ +.global switch_to +switch_to: + stp x19, x20, [x0, 16 * 0] + stp x21, x22, [x0, 16 * 1] + stp x23, x24, [x0, 16 * 2] + stp x25, x26, [x0, 16 * 3] + stp x27, x28, [x0, 16 * 4] + stp fp, lr, [x0, 16 * 5] + mov x9, sp + str x9, [x0, 16 * 6] + + ldp x19, x20, [x1, 16 * 0] + ldp x21, x22, [x1, 16 * 1] + ldp x23, x24, [x1, 16 * 2] + ldp x25, x26, [x1, 16 * 3] + ldp x27, x28, [x1, 16 * 4] + ldp fp, lr, [x1, 16 * 5] + ldp x9, x0, [x1, 16 * 6] + mov sp, x9 + msr tpidr_el1, x1 + + dsb ish // ensure write has completed + msr ttbr0_el1, x0 // switch translation based address. + tlbi vmalle1is // invalidate all TLB entries + dsb ish // ensure completion of TLB invalidatation + isb // clear pipeline + + ret + +.global store_context +store_context: + stp x19, x20, [x0, 16 * 0] + stp x21, x22, [x0, 16 * 1] + stp x23, x24, [x0, 16 * 2] + stp x25, x26, [x0, 16 * 3] + stp x27, x28, [x0, 16 * 4] + stp fp, lr, [x0, 16 * 5] + mov x9, sp + str x9, [x0, 16 * 6] + ret + +.global load_context +load_context: + ldp x19, x20, [x0, 16 * 0] + ldp x21, x22, [x0, 16 * 1] + ldp x23, x24, [x0, 16 * 2] + ldp x25, x26, [x0, 16 * 3] + ldp x27, x28, [x0, 16 * 4] + ldp fp, lr, [x0, 16 * 5] + ldr x9, [x0, 16 * 6] + mov sp, x9 + ret + +.global get_current +get_current: + mrs x0, tpidr_el1 + ret diff --git a/kernel/dtb.c b/kernel/dtb.c index 5f55235c6..6a3e32d52 100644 --- a/kernel/dtb.c +++ b/kernel/dtb.c @@ -71,11 +71,11 @@ void dtb_parser(dtb_callback_t callback) { void dtb_get_initrd_callback(unsigned int token_type, char* name, char* data) { if (token_type == FDT_PROP && !strcmp(name, "linux,initrd-start")) { - INITRD_ADDR = BE_to_uint(data); + INITRD_ADDR = (void *)(PHYS_TO_VIRT((unsigned long long int)BE_to_uint(data))); uart_printf("Initramfs address: 0x%x\r\n", INITRD_ADDR); } if (token_type == FDT_PROP && !strcmp(name, "linux,initrd-end")) { - INITRD_END = BE_to_uint(data); + INITRD_END = (void *)(PHYS_TO_VIRT((unsigned long long int)BE_to_uint(data))); } } diff --git a/kernel/entry.s b/kernel/entry.s new file mode 100644 index 000000000..1cd6c3601 --- /dev/null +++ b/kernel/entry.s @@ -0,0 +1,196 @@ +// save general registers to stack +.global save_all +.macro save_all + sub sp, sp, 32 * 9 + stp x0, x1, [sp ,16 * 0] + stp x2, x3, [sp ,16 * 1] + stp x4, x5, [sp ,16 * 2] + stp x6, x7, [sp ,16 * 3] + stp x8, x9, [sp ,16 * 4] + stp x10, x11, [sp ,16 * 5] + stp x12, x13, [sp ,16 * 6] + stp x14, x15, [sp ,16 * 7] + stp x16, x17, [sp ,16 * 8] + stp x18, x19, [sp ,16 * 9] + stp x20, x21, [sp ,16 * 10] + stp x22, x23, [sp ,16 * 11] + stp x24, x25, [sp ,16 * 12] + stp x26, x27, [sp ,16 * 13] + stp x28, x29, [sp ,16 * 14] + str x30, [sp, 16 * 15] + +// for nested interrupt + mrs x0, spsr_el1 + str x0, [sp, 16 * 15 + 8] + mrs x0, elr_el1 + str x0, [sp, 16 * 16] + mrs x0, sp_el0 + str x0, [sp, 16 * 16 + 8] +// restore x0 + ldp x0, x1, [sp ,16 * 0] +.endm + +// load general registers from stack +.global load_all +.macro load_all + ldp x0, x1, [sp ,16 * 0] + ldp x2, x3, [sp ,16 * 1] + ldp x4, x5, [sp ,16 * 2] + ldp x6, x7, [sp ,16 * 3] + ldp x8, x9, [sp ,16 * 4] + ldp x10, x11, [sp ,16 * 5] + ldp x12, x13, [sp ,16 * 6] + ldp x14, x15, [sp ,16 * 7] + ldp x16, x17, [sp ,16 * 8] + ldp x18, x19, [sp ,16 * 9] + ldp x20, x21, [sp ,16 * 10] + ldp x22, x23, [sp ,16 * 11] + ldp x24, x25, [sp ,16 * 12] + ldp x26, x27, [sp ,16 * 13] + ldp x28, x29, [sp ,16 * 14] + ldr x30, [sp, 16 * 15] + +// for nested interrupt + ldr x0, [sp, 16 * 15 + 8] + msr spsr_el1, x0 + ldr x0, [sp, 16 * 16] + msr elr_el1, x0 + ldr x0, [sp, 16 * 16 + 8] + msr sp_el0, x0 +// restore x0 + ldp x0, x1, [sp ,16 * 0] + add sp, sp, 32 * 9 +.endm + +.macro ventry label + .align 7 + b \label +.endm + +.align 11 // vector table should be aligned to 0x800 +.global exception_vector_table +exception_vector_table: + // Exception from the current EL while using SP_EL0 + ventry sync_el1t_invalid // Synchronous EL1t + ventry irq_el1t_invalid // IRQ EL1t + ventry fiq_el1t_invalid // FIQ EL1t + ventry err_el1t_invalid // Error EL1t + + // Exception from the current EL while using SP_ELx + ventry sync_el1h_invalid // Synchronous EL1h + ventry irq_el1h // IRQ EL1h + ventry fiq_el1h_invalid // FIQ EL1h + ventry err_el1h_invalid // Error EL1h + + // Exception from a lower EL and at least one lower EL is AArch64 + ventry sync_el0_64 // Synchronous 64-bit EL0 + ventry irq_el0_64 // IRQ 64-bit EL0 + ventry fiq_el0_64_invalid // FIQ 64-bit EL0 + ventry err_el0_64_invalid // Error 64-bit EL0 + + // Exception from a lower EL and at least all lower EL are AArch32 + ventry sync_el0_32_invalid // Synchronous 32-bit EL0 + ventry irq_el0_32_invalid // IRQ 32-bit EL0 + ventry fiq_el0_32_invalid // FIQ 32-bit EL0 + ventry err_el0_32_invalid // Error 32-bit EL0 + +sync_el1t_invalid: + // save_all + mov x0, 1 + bl invalid_exception_router + // load_all + eret +irq_el1t_invalid: + save_all + mov x0, 2 + bl invalid_exception_router + load_all + eret +fiq_el1t_invalid: + save_all + mov x0, 3 + bl invalid_exception_router + load_all + eret +err_el1t_invalid: + save_all + mov x0, 4 + bl invalid_exception_router + load_all + eret + +sync_el1h_invalid: + // save_all + mov x0, 5 + bl invalid_exception_router + // load_all + eret +irq_el1h: + save_all + mov x0, sp // trap frame + bl irq_router + load_all + eret +fiq_el1h_invalid: + save_all + mov x0, 7 + bl invalid_exception_router + load_all + eret +err_el1h_invalid: + save_all + mov x0, 8 + bl invalid_exception_router + load_all + eret + +sync_el0_64: + save_all + mov x0, sp // trap frame + mrs x1, esr_el1 + bl sync64_router + load_all + eret +irq_el0_64: + save_all + mov x0, sp // trap frame + bl irq_router + load_all + eret +fiq_el0_64_invalid: + save_all + mov x0, 11 + bl invalid_exception_router + load_all + eret +err_el0_64_invalid: + save_all + mov x0, 12 + bl invalid_exception_router + load_all + eret + +sync_el0_32_invalid: + save_all + mov x0, 13 + bl invalid_exception_router + load_all + eret +irq_el0_32_invalid: + save_all + mov x0, 14 + bl invalid_exception_router + load_all + eret +fiq_el0_32_invalid: + save_all + mov x0, 15 + bl invalid_exception_router + load_all + eret +err_el0_32_invalid: + save_all + mov x0, 16 + bl invalid_exception_router + load_all + eret diff --git a/kernel/exception.c b/kernel/exception.c index 1063843a7..5fb5a96e7 100644 --- a/kernel/exception.c +++ b/kernel/exception.c @@ -1,14 +1,44 @@ #include "exception.h" -void sync64_router(unsigned long long x0) { - unsigned long long spsr_el1, elr_el1, esr_el1; - asm volatile("mrs %0, spsr_el1\n\t" : "=r" (spsr_el1) :: "memory"); - asm volatile("mrs %0, elr_el1\n\t" : "=r" (elr_el1) :: "memory"); - asm volatile("mrs %0, esr_el1\n\t" : "=r" (esr_el1) :: "memory"); - uart_printf("Exception : sync_el0_64, SPSR_EL1 : 0x%x, ELR_EL1 : 0x%x, ESR_EL1 : 0x%x\r\n", spsr_el1, elr_el1, esr_el1); +void sync64_router(trapframe_t *tpf, unsigned long x1) { + // for page fault + esr_el1_t *esr; + esr = (esr_el1_t *)&x1; + if (esr->ec == DATA_ABORT_LOWER || esr->ec == INS_ABORT_LOWER) { + handle_abort(esr); + return; + } + // for sys call + enable_interrupt(); + unsigned long long syscall_no = tpf->x8; + + if (syscall_no == 0) + getpid(tpf); + else if (syscall_no == 1) + uartread(tpf, (char *)tpf->x0, tpf->x1); + else if (syscall_no == 2) + uartwrite(tpf, (char *)tpf->x0, tpf->x1); + else if (syscall_no == 3) + exec(tpf, (char *)tpf->x0, (char **)tpf->x1); + else if (syscall_no == 4) + fork(tpf); + else if (syscall_no == 5) + exit(tpf, tpf->x0); + else if (syscall_no == 6) + syscall_mbox_call(tpf, (unsigned char)tpf->x0, (unsigned int *)tpf->x1); + else if (syscall_no == 7) + kill(tpf, (int)tpf->x0); + else if (syscall_no == 8) + signal_register(tpf->x0, (void (*)())tpf->x1); + else if (syscall_no == 9) + signal_kill(tpf->x0, tpf->x1); + else if (syscall_no == 10) + sys_mmap(tpf, (void *)tpf->x0, tpf->x1, tpf->x2, tpf->x3, tpf->x4, tpf->x5); + else if (syscall_no == 31) + sigreturn(tpf); } -void irq_router(unsigned long long x0) { +void irq_router(trapframe_t *tpf) { // from core timer (CNTPNS) IRQ_EL0_64 if (*CORE0_INTERRUPT_SOURCE & INTERRUPT_SOURCE_CNTPNSIRQ) { // masks the device’s interrupt line @@ -19,6 +49,10 @@ void irq_router(unsigned long long x0) { run_preemptive_tasks(); // unmasks the device’s interrupt line core_timer_enable(); + + // at least 2 thread running -> schedule for any timer IRQ + if (run_queue->next->next != run_queue) + schedule(); } // from uart (AUX_INT && GPU0) IRQ_EL1h else if (*IRQ_PENDING_1 & IRQ_PENDING_1_AUX_INT && *CORE0_INTERRUPT_SOURCE & INTERRUPT_SOURCE_GPU) { @@ -41,6 +75,11 @@ void irq_router(unsigned long long x0) { } // can read else if (*AUX_MU_IIR_REG & (0b10 << 1)) { + // NOT SURE == clear fifo + if (!mini_uart_r_interrupt_is_enable()) { + *AUX_MU_IIR_REG = 0xc2; + return; + } // masks the device’s interrupt line (enable by handler) disable_mini_uart_r_interrupt(); // uart IRQ priority = 200 @@ -49,9 +88,14 @@ void irq_router(unsigned long long x0) { run_preemptive_tasks(); } else { - uart_printf("------ UNKNOWN ------\r\n"); + uart_printf("------ UNKNOWN IRQ from UART ------\r\n"); } } + + // only run signal handler when return to user mode + if ((tpf->spsr_el1 & 0b1100) == 0) { + check_signal(tpf); + } } void invalid_exception_router(unsigned long long x0) { @@ -61,10 +105,25 @@ void invalid_exception_router(unsigned long long x0) { while (1); } -void enable_interrupt() { - asm volatile("msr daifclr, 0xf"); +// 0 => enable, 1 => disable +unsigned long long is_disable_interrupt() { + unsigned long long daif; + asm volatile("mrs %0, daif\n\t" : "=r"(daif)); + return daif; } -void disable_interrupt() { - asm volatile("msr daifset, 0xf"); +static unsigned long long lock_count = 0; +void lock() { + disable_interrupt(); + lock_count++; +} + +void unlock() { + lock_count--; + if (lock_count < 0) { + uart_printf("Error : unlock()\r\n"); + while(1); + } + if (lock_count == 0) + enable_interrupt(); } diff --git a/kernel/linker.ld b/kernel/linker.ld index 51a4f53f9..654d459bf 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -1,12 +1,13 @@ /* entry point */ ENTRY(_start) -_simple_alloc_start = 0x3b000000; -_simple_alloc_end = 0x3bffffff; +_simple_alloc_start = 0xffff00002c000000; +_simple_alloc_end = 0xffff00002dffffff; SECTIONS { - . = 0x80000; + . = 0xffff000000000000; + . += 0x80000; _text_start = .; .text : diff --git a/kernel/main.c b/kernel/main.c index 14a9aaccb..6d585c0b9 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,11 +1,23 @@ +#include "mmu.h" #include "dtb.h" +#include "cpio.h" +#include "task.h" +#include "shell.h" +#include "buddy.h" +#include "exception.h" void kernel_main(char* x0) { - dtb_init(x0); - + // init dtb + dtb_init(PHYS_TO_VIRT((unsigned long)x0)); + // init memory + mm_init(); + // init task task_list_init(); - enable_mini_uart_interrupt(); + // enable interrupt + // enable_mini_uart_interrupt(); enable_interrupt(); // enable interrupt in EL1 -> EL1 + // init cpio (unnecessary) + cpio_init(); shell(); } \ No newline at end of file diff --git a/kernel/makefile b/kernel/makefile index b61af5544..22f4753a1 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -1,4 +1,4 @@ -CROSS = aarch64-unknown-linux-gnu +CROSS = aarch64-linux-gnu CC = $(CROSS)-gcc CFLAGS = -Wall -ffreestanding -nostdinc -nostdlib -nostartfiles -g LD = $(CROSS)-ld @@ -7,17 +7,19 @@ OBJCPY = $(CROSS)-objcopy INCLUDE = -I ../include SRCS = $(wildcard ./*.c) OBJS = $(patsubst %.c, %.o, $(SRCS)) +SRCS_ASM = $(wildcard ./*.s) +OBJS_ASM = $(patsubst %.s, %.o, $(SRCS_ASM)) all: clean kernel8.img -boot.o: boot.s - $(CC) $(CFLAGS) $(INCLUDE) -c boot.s -o boot.o +%.o: %.s + $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ %.o: %.c $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ -kernel8.img: boot.o $(OBJS) - $(LD) -nostdlib -nostartfiles boot.o $(OBJS) -T linker.ld -o kernel8.elf +kernel8.img: $(OBJS) $(OBJS_ASM) + $(LD) -nostdlib -nostartfiles $(OBJS) $(OBJS_ASM) -T linker.ld -o kernel8.elf $(OBJCPY) -O binary kernel8.elf kernel8.img clean: diff --git a/kernel/malloc.c b/kernel/malloc.c index 3d5d3ddb5..4e238d07d 100644 --- a/kernel/malloc.c +++ b/kernel/malloc.c @@ -39,7 +39,12 @@ void sc_init() { } void *sc_alloc(int size) { - uart_printf("------------ In function sc_alloc(0x%x) ------------\r\n", size); + // uart_printf("------------ In function sc_alloc(0x%x) ------------\r\n", size); + if (size > 0x1000) { + uart_printf("Error : sc_alloc(size), size > 0x1000\r\n"); + return 0; + } + sc_hdr *hdr; unsigned int size_idx = find_size_idx(size); @@ -56,32 +61,34 @@ void *sc_alloc(int size) { hdr = (sc_hdr *)((char *)page + i); list_add_tail(&hdr->list, &sc_freelists[size_idx]); } - uart_printf("[+] In small chunk alloc (alloc page idx : %d, cut into chunk size : 0x%x)\r\n", frame_idx, sc_sizes[size_idx]); + // uart_printf("[+] In small chunk alloc (alloc page idx : %d, cut into chunk size : 0x%x)\r\n", frame_idx, sc_sizes[size_idx]); } // allocate this chunk and remove from free list - hdr = sc_freelists[size_idx].next; + hdr = (sc_hdr *)sc_freelists[size_idx].next; list_del_entry(&hdr->list); - uart_printf("[-] Successfully allocate a small chunk, addr : 0x%x, chunk size : 0x%x\r\n", hdr, sc_sizes[size_idx]); + // uart_printf("[-] Successfully allocate a small chunk, addr : 0x%x, chunk size : 0x%x\r\n", hdr, sc_sizes[size_idx]); return hdr; } int sc_free(void *sc) { - uart_printf("++++++++++++ In function sc_free ++++++++++++\r\n"); + // uart_printf("++++++++++++ In function sc_free ++++++++++++\r\n"); sc_hdr *hdr; int frame_idx = addr_to_idx(sc); int size_idx; // this chunk is not managed by Small Chunk allocator - if (!sc_frame_ents[frame_idx].splitted) + if (!sc_frame_ents[frame_idx].splitted) { + // uart_printf("Error : sc_free()\r\n"); return -1; + } // add this chunk to free list size_idx = sc_frame_ents[frame_idx].size_idx; hdr = (sc_hdr *)sc; list_add(&hdr->list, &sc_freelists[size_idx]); - uart_printf("[+] Successfully free a chunk (addr : 0x%x, chunk size : 0x%x)\r\n", sc, sc_sizes[size_idx]); + // uart_printf("[+] Successfully free a chunk (addr : 0x%x, chunk size : 0x%x)\r\n", sc, sc_sizes[size_idx]); return 0; } @@ -105,3 +112,34 @@ void sc_test() { char *ptr6 = sc_alloc(0x369); // Allocate a page and create 0x400 chunks sc_free(ptr6); } + +void *kmalloc(int size) { + void *ret; + + lock(); + + if (size <= PAGE_SIZE) { + ret = sc_alloc(size); + } + else { + int page_cnt = ALIGN(size, PAGE_SIZE) / PAGE_SIZE; + ret = alloc_pages(page_cnt); + } + + unlock(); + + return ret; +} + +void kfree(void *ptr) { + lock(); + + if (!sc_free(ptr)) { + unlock(); + return; + } + + free_page(ptr); + unlock(); + return; +} diff --git a/kernel/mbox.c b/kernel/mbox.c index 4c81dfdcb..c1f9baa5e 100644 --- a/kernel/mbox.c +++ b/kernel/mbox.c @@ -1,6 +1,8 @@ #include "mbox.h" -unsigned int get_board_revision(volatile unsigned int mbox[36]){ +volatile unsigned int __attribute__((aligned(16))) mbox[72]; + +unsigned int get_board_revision(unsigned int* board_revision){ mbox[0] = 7 * 4; // buffer size in bytes mbox[1] = REQUEST_CODE; // tags begin @@ -11,10 +13,17 @@ unsigned int get_board_revision(volatile unsigned int mbox[36]){ // tags end mbox[6] = END_TAG; - return mailbox_call(mbox, MAILBOX_CH_PROP); + if (mailbox_call(MAILBOX_CH_PROP)) { + *board_revision = mbox[5]; + return 0; + } + else { + // uart_printf("Unable to query serial\r\n"); + return -1; + } } -unsigned int get_arm_memory(volatile unsigned int mbox[36]){ +unsigned int get_arm_memory(unsigned int* base_addr,unsigned int* size){ mbox[0] = 8 * 4; // buffer size in bytes mbox[1] = REQUEST_CODE; // tags begin @@ -25,26 +34,34 @@ unsigned int get_arm_memory(volatile unsigned int mbox[36]){ mbox[6] = 0; // size in bytes // tags end mbox[7] = END_TAG; - - return mailbox_call(mbox, MAILBOX_CH_PROP); + + if (mailbox_call(MAILBOX_CH_PROP)) { + *base_addr = mbox[5]; + *size = mbox[6]; + return 0; + } + else { + // uart_printf("Unable to query serial\r\n"); + return -1; + } } // Make a mailbox call. Returns 0 on failure, non-zero on success -unsigned int mailbox_call(volatile unsigned int mbox[36], unsigned char ch){ +unsigned int mailbox_call(unsigned char ch){ /* Combine the message address (upper 28 bits) with channel number (lower 4 bits) */ unsigned int req = (((unsigned int)((unsigned long)mbox) & (~0xF)) | (ch & 0xF)); /* wait until we can write to the mailbox */ - while(*MAILBOX_STATUS & MAILBOX_FULL){asm volatile("nop");} + do{asm volatile("nop");}while(*MAILBOX_STATUS & MAILBOX_FULL); /* write the address of our message to the mailbox with channel identifier */ *MAILBOX_WRITE = req; /* now wait for the response */ - while(1){ + while (1) { /* wait the response signal */ - while(*MAILBOX_STATUS & MAILBOX_EMPTY){asm volatile("nop");} + do{asm volatile("nop");}while(*MAILBOX_STATUS & MAILBOX_EMPTY); /* read the response to compare our req and request_code */ - if(req == *MAILBOX_READ) + if(req == PHYS_TO_VIRT(*MAILBOX_READ)) return mbox[1] == MAILBOX_RESPONSE; } return 0; -} +} \ No newline at end of file diff --git a/kernel/mmu.c b/kernel/mmu.c new file mode 100644 index 000000000..36833c6bb --- /dev/null +++ b/kernel/mmu.c @@ -0,0 +1,129 @@ +#include "mmu.h" + +// PGD's page frame at 0x1000 +// PUD's page frame at 0x2000 + +// 2-level translation (1GB) => 3-level translation (2MB) +void* set_2M_kernel_mmu(void *x0) { + // first entry (0x00000000 ~ 0x3FFFFFFF) + unsigned long *pud_table_1 = (unsigned long *)0x3000; + for (int i = 0; i < 512; i++) { + // 0x3F000000 to 0x3FFFFFFF for peripherals + if ((0x00000000 + (0x200000L) * i) >= 0x3F000000L) + pud_table_1[i] = PD_ACCESS | PD_BLOCK | (0x00000000 + (0x200000L) * i) | (MAIR_DEVICE_nGnRnE << 2) | PD_UK_ACCESS | PD_UNX | PD_KNX; + else + pud_table_1[i] = PD_ACCESS | PD_BLOCK | (0x00000000 | (0x200000L) * i) | (MAIR_IDX_NORMAL_NOCACHE << 2); + } + // second entry (0x40000000 ~ 0x7FFFFFFF) + unsigned long *pud_table_2 = (unsigned long *)0x4000; + for (int i = 0; i < 512; i++) + pud_table_2[i] = PD_ACCESS | PD_BLOCK | (0x40000000L | (0x200000L) * i) | (MAIR_IDX_NORMAL_NOCACHE << 2); + // set PUD + *(unsigned long *)(kernel_pud_addr) = PD_ACCESS | PD_TABLE | (unsigned long)pud_table_1; + *(unsigned long *)(kernel_pud_addr + 0x8) = PD_ACCESS | PD_TABLE | (unsigned long)pud_table_2; + + return x0; +} + +void map_one_page(unsigned long *virt_pgd_p, unsigned long va, unsigned long pa, unsigned long flag) { + unsigned long *table_p = virt_pgd_p; + for (int level = 0; level < 4; level++) { + // get index from VA + unsigned int idx = (va >> (39 - level * 9)) & 0x1ff; + // map page to table + if (level == 3) { + table_p[idx] = pa; + table_p[idx] |= PD_ACCESS | PD_TABLE | (MAIR_IDX_NORMAL_NOCACHE << 2) | PD_KNX | flag; + return; + } + // malloc for empty entry + if (!table_p[idx]) { + unsigned long* newtable_p = kmalloc(0x1000); + memset(newtable_p, 0, 0x1000); + table_p[idx] = VIRT_TO_PHYS((unsigned long)newtable_p); + table_p[idx] |= PD_ACCESS | PD_TABLE | (MAIR_IDX_NORMAL_NOCACHE << 2); + } + // get next level entry + table_p = (unsigned long*)PHYS_TO_VIRT((unsigned long)(table_p[idx] & ENTRY_ADDR_MASK)); + } +} + +void add_vma(thread_t *t, unsigned long va, unsigned long size, unsigned long pa, unsigned long rwx, int is_alloced) { + // alignment + size = size % 0x1000 ? size + (0x1000 - size % 0x1000) : size; + + vm_area_struct_t *new_area = kmalloc(sizeof(vm_area_struct_t)); + new_area->rwx = rwx; + new_area->area_size = size; + new_area->virt_addr = va; + new_area->phys_addr = pa; + new_area->is_alloced = is_alloced; + list_add_tail((list_head_t *)new_area, &t->vma_list); +} + +void free_page_tables(unsigned long *page_table, int level) { + unsigned long *table_virt = (unsigned long*)PHYS_TO_VIRT((char*)page_table); + for (int i = 0; i < 512; i++) { + if (table_virt[i] != 0) { + unsigned long *next_table = (unsigned long*)(table_virt[i] & ENTRY_ADDR_MASK); + if (table_virt[i] & PD_TABLE) { + if (level!=2) { + free_page_tables(next_table, level + 1); + } + table_virt[i] = 0L; + kfree(PHYS_TO_VIRT((char *)next_table)); + } + } + } +} + +void handle_abort(esr_el1_t* esr_el1) { + // get fault VA + unsigned long long far_el1; + asm volatile("mrs %0, FAR_EL1\n\t" : "=r"(far_el1)); + // check if far_el1 is in VMA + list_head_t *pos; + vm_area_struct_t *the_area_ptr = 0; + list_for_each (pos, &curr_thread->vma_list) { + if (((vm_area_struct_t *)pos)->virt_addr <= far_el1 && ((vm_area_struct_t *)pos)->virt_addr + ((vm_area_struct_t *)pos)->area_size >= far_el1) { + the_area_ptr = (vm_area_struct_t *)pos; + break; + } + } + // far_el1 is not in VMA + if (!the_area_ptr) { + uart_printf("far_el1 is not in VMA\r\n"); + seg_fault(); + } + // for translation fault + if ((esr_el1->iss & 0x3f) == TF_LEVEL0 || (esr_el1->iss & 0x3f) == TF_LEVEL1 || (esr_el1->iss & 0x3f) == TF_LEVEL2 || (esr_el1->iss & 0x3f) == TF_LEVEL3) { + uart_printf("[Translation fault]: 0x%x\r\n", far_el1); + // offset align down 0x1000 + unsigned long addr_offset = (far_el1 - the_area_ptr->virt_addr); + addr_offset = (addr_offset % 0x1000) == 0 ? addr_offset : addr_offset - (addr_offset % 0x1000); + map_one_page_rwx(PHYS_TO_VIRT(curr_thread->context.ttbr0_el1), the_area_ptr->virt_addr + addr_offset, the_area_ptr->phys_addr + +addr_offset, the_area_ptr->rwx); + } + else { + seg_fault(); + } +} + +void map_one_page_rwx(unsigned long *pgd_p, unsigned long va, unsigned long pa, unsigned long rwxflag) { + unsigned long flag = 0; + // read + if (rwxflag & 0b1) + flag |= PD_UK_ACCESS; + // write + if (!(rwxflag & 0b10)) + flag |= PD_RDONLY; + // execute + if (!(rwxflag & 0b100)) + flag |= PD_UNX; + // map page + map_one_page(pgd_p, va, pa, flag); +} + +void seg_fault() { + uart_printf("[Segmentation fault]: Kill Process\r\n"); + thread_exit(); +} diff --git a/kernel/reset.c b/kernel/reset.c new file mode 100644 index 000000000..e5c1f046c --- /dev/null +++ b/kernel/reset.c @@ -0,0 +1,16 @@ +#include "reset.h" + +void set(long addr, unsigned int value) { + volatile unsigned int* point = (unsigned int*)addr; + *point = value; +} + +void reset(int tick) { // reboot after watchdog timer expire + set(PM_RSTC, PM_PASSWORD | 0x20); // full reset + set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick +} + +void cancel_reset() { + set(PM_RSTC, PM_PASSWORD | 0); // full reset + set(PM_WDOG, PM_PASSWORD | 0); // number of watchdog tick +} diff --git a/kernel/sched.c b/kernel/sched.c new file mode 100644 index 000000000..3a15fae96 --- /dev/null +++ b/kernel/sched.c @@ -0,0 +1,159 @@ +#include "sched.h" + +thread_t *curr_thread; +list_head_t *run_queue; +list_head_t *wait_queue; +thread_t threads[PIDMAX + 1]; + +void init_thread_sched() { + lock(); + run_queue = kmalloc(sizeof(list_head_t)); + wait_queue = kmalloc(sizeof(list_head_t)); + INIT_LIST_HEAD(run_queue); + INIT_LIST_HEAD(wait_queue); + + // init pids + for (int i = 0; i <= PIDMAX; i++) { + threads[i].pid = i; + threads[i].isused = 0; + threads[i].iszombie = 0; + } + // malloc a space for current kernel thread to prevent crash + asm volatile("msr tpidr_el1, %0" :: "r"(kmalloc(sizeof(thread_t)))); + + thread_t* idlethread = thread_create(idle, 0x1000); + curr_thread = idlethread; + unlock(); +} + +void idle() { + while (1) { + kill_zombies(); + schedule(); + } +} + +void schedule() { + lock(); + do { + curr_thread = (thread_t *)curr_thread->listhead.next; + } while (list_is_head(&curr_thread->listhead, run_queue) || curr_thread->iszombie); + unlock(); + switch_to(get_current(), &curr_thread->context); +} + +void kill_zombies() { + lock(); + list_head_t *curr; + list_for_each(curr, run_queue) { + if (((thread_t *)curr)->iszombie) { + list_del_entry(curr); + kfree(((thread_t *)curr)->kernel_stack_alloced_ptr); + // free tables (VA) + free_page_tables(((thread_t *)curr)->context.ttbr0_el1, 0); + // free alloced area and vma struct + list_head_t *pos = ((thread_t *)curr)->vma_list.next; + while (pos != &((thread_t *)curr)->vma_list) { + if (((vm_area_struct_t *)pos)->is_alloced) + kfree((void*)PHYS_TO_VIRT(((vm_area_struct_t *)pos)->phys_addr)); + list_head_t* next_pos = pos->next; + kfree(pos); + pos = next_pos; + } + // free PGD + kfree(PHYS_TO_VIRT(((thread_t *)curr)->context.ttbr0_el1)); + ((thread_t *)curr)->isused = 0; + ((thread_t *)curr)->iszombie = 0; + // free user stack & kernel stack + // kfree(((thread_t *)curr)->stack_alloced_ptr); + } + } + unlock(); +} + +thread_t *thread_create(void *start, unsigned int filesize) { + lock(); + thread_t *r; + for (int i = 0; i <= PIDMAX; i++) { + if (!threads[i].isused) { + r = &threads[i]; + break; + } + } + + INIT_LIST_HEAD(&r->vma_list); + r->isused = 1; + r->iszombie = 0; + r->signal_is_checking = 0; + r->context.lr = (unsigned long long)start; + r->stack_alloced_ptr = kmalloc(USTACK_SIZE); + r->kernel_stack_alloced_ptr = kmalloc(KSTACK_SIZE); + r->data = kmalloc(filesize); + r->datasize = filesize; + r->context.sp = (unsigned long long )r->kernel_stack_alloced_ptr + KSTACK_SIZE; + r->context.fp = r->context.sp; + + r->context.ttbr0_el1 = kmalloc(0x1000); + memset(r->context.ttbr0_el1, 0, 0x1000); + // initial signal handler with signal_default_handler (kill thread) + for (int i = 0; i < SIGNAL_MAX; i++) { + r->singal_handler[i] = signal_default_handler; + r->sigcount[i] = 0; + } + + list_add(&r->listhead, run_queue); + unlock(); + return r; +} + +void thread_exit() { + lock(); + curr_thread->iszombie = 1; + unlock(); + schedule(); +} + +int exec_thread(char *data, unsigned int filesize) { + thread_t *t = thread_create(data, filesize); + // device memory + add_vma(t, 0x3C000000L, 0x3000000L, 0x3C000000L, 3, 0); + // user stack + add_vma(t, 0xffffffffb000, 0x4000, (unsigned long)VIRT_TO_PHYS(t->stack_alloced_ptr), 7, 1); + // code + add_vma(t, 0x0, filesize, (unsigned long)VIRT_TO_PHYS(t->data), 7, 1); + // signal wrapper + add_vma(t, USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED, 0x2000, (unsigned long)VIRT_TO_PHYS(signal_handler_wrapper), 5, 0); + + t->context.ttbr0_el1 = VIRT_TO_PHYS(t->context.ttbr0_el1); + t->context.sp = 0xfffffffff000; + t->context.fp = 0xfffffffff000; + t->context.lr = 0L; + // copy file into data + for (int i = 0; i < filesize; i++) + t->data[i] = data[i]; + + curr_thread = t; + add_timer(schedule_timer, 1, "", 0); + // eret to EL0 + asm volatile( + "msr spsr_el1, xzr\n\t" + "msr tpidr_el1, %0\n\t" + "msr elr_el1, %1\n\t" + "msr sp_el0, %2\n\t" + "mov sp, %3\n\t" + "dsb ish\n\t" // ensure write has completed + "msr ttbr0_el1, %4\n\t" + "tlbi vmalle1is\n\t" // invalidate all TLB entries + "dsb ish\n\t" // ensure completion of TLB invalidatation + "isb\n\t" // clear pipeline" + "eret\n\t" + :: "r"(&t->context), "r"(t->context.lr), "r"(t->context.sp), "r"(t->kernel_stack_alloced_ptr + KSTACK_SIZE), "r"(t->context.ttbr0_el1) + ); + return 0; +} + +void schedule_timer(char *notuse) { + unsigned long long cntfrq_el0; + asm volatile("mrs %0, cntfrq_el0\n\t" : "=r"(cntfrq_el0)); + add_timer(schedule_timer, cntfrq_el0 >> 5, "", 1); +} diff --git a/kernel/shell.c b/kernel/shell.c index 5cba051b9..998453ade 100644 --- a/kernel/shell.c +++ b/kernel/shell.c @@ -1,6 +1,27 @@ #include "shell.h" -char buf[0x100]; +char buf[0x1000]; + +struct cmd cmd_list[] = { + {"help", cmd_help, "print this help menu"}, + {"hello", cmd_hello, "print Hello World!"}, + // {"reboot", cmd_reboot, "reboot the device"}, + {"revision", cmd_revision, "print board revision"}, + {"memory", cmd_memory, "print ARM memory base address and size"}, + {"ls", cmd_ls, "list directory contents"}, + {"cat", cmd_cat, "print file content"}, + {"dtb", cmd_dtb, "show device tree"}, + {"initramfs", cmd_initramfs, "show initramfs address"}, + // {"async", cmd_async, "test async print"}, + // {"prog", cmd_prog, "load a user program in the initramfs, and jump to it"}, + // {"sec2", cmd_sec2, "print the seconds after booting and set the next timeout to 2 seconds later."}, + // {"setTimeout",cmd_setTimeout,"prints message after seconds"}, + // {"testfoo", cmd_foo, "test thread"}, + // {"preempt", cmd_preempt, "test preemption"}, + // {"pageTest", cmd_pageTest, "test page frame allocator"}, + // {"chunkTest", cmd_chunkTest, "test small chunk allocator"}, + {"exec", cmd_exec, "run img file"}, +}; void welcome_msg() { uart_printf("************************************************\r\n"); @@ -11,7 +32,8 @@ void read_cmd() { unsigned int idx = 0; while (1) { // read char - c = uart_read_char_async(); + uart_read(&c, 1); + // c = uart_read_char_async(); // handle buffer switch (c) { case '\r': @@ -88,28 +110,16 @@ void cmd_reboot(char* param) { } void cmd_revision() { - volatile unsigned int mbox[36]; - if (get_board_revision(mbox)) { - uart_printf("Board Revision : 0x"); - uart_write_hex(mbox[5]); - uart_printf("\r\n"); - } - else - uart_printf("Failed to get board revision\r\n"); + unsigned int board_revision; + get_board_revision(&board_revision); + uart_printf("Board Revision : 0x%x\r\n", board_revision); } void cmd_memory() { - volatile unsigned int mbox[36]; - if (get_arm_memory(mbox)) { - uart_printf("ARM Memory Base Address : 0x"); - uart_write_hex(mbox[5]); - uart_printf("\r\n"); - uart_printf("ARM Memory Size : 0x"); - uart_write_hex(mbox[6]); - uart_printf("\r\n"); - } - else - uart_printf("Failed to get ARM memory base address and size\r\n"); + unsigned int arm_mem_base, arm_mem_size; + get_arm_memory(&arm_mem_base, &arm_mem_size); + uart_printf("ARM Memory Base Address : 0x%x\r\n", arm_mem_base); + uart_printf("ARM Memory Size : 0x%x\r\n", arm_mem_size); } void cmd_ls(char* param) { @@ -137,7 +147,7 @@ void cmd_prog(char* param) { } void cmd_sec2() { - add_timer(two_second_alert, 2, ""); + add_timer(two_second_alert, 2, "", 0); } void cmd_setTimeout(char* param) { @@ -150,15 +160,15 @@ void cmd_setTimeout(char* param) { msg[idx++] = '\n'; msg[idx++] = '\0'; char *seconds = param + 1; - add_timer(uart_write_string, atoi(seconds), msg); + add_timer(uart_write_string, atoi(seconds), msg, 0); } void cmd_preempt() { char tmp[0x100]; for (int i = 0; i < 0x100; i++) tmp[i] = ('A' + (i % 26)); - add_timer(uart_write_string, 1, "Timer\r\n"); - uart_write_string_async(tmp); + add_timer(uart_write_string, 1, "Timer\r\n", 0); + uart_write_string(tmp); } void cmd_pageTest() { @@ -169,18 +179,37 @@ void cmd_chunkTest() { sc_test(); } +void cmd_exec(char* param) { + cpio_newc_parser(cpio_exec_callback, param); +} + void cmd_unknown() { uart_printf("Err: command %s not found, try \r\n", buf); } -void shell() { - cpio_init(); - welcome_msg(); +void foo() { + for (int i = 0; i < 10; i++) { + uart_printf("Thread id : %d, i : %d\r\n", curr_thread->pid, i); + nop_delay(100000); + schedule(); + } + thread_exit(); +} - mm_init(); +void cmd_foo() { + for (int i = 0; i < 3; i++) { + thread_create(foo, 0x1000); + } + schedule(); +} +void shell() { + welcome_msg(); + // init thread scheduler + init_thread_sched(); + // init timer timer_list_init(); - core_timer_enable(); + core_timer_enable(); while (1) { uart_printf("# "); diff --git a/kernel/signal.c b/kernel/signal.c new file mode 100644 index 000000000..9755c99f1 --- /dev/null +++ b/kernel/signal.c @@ -0,0 +1,62 @@ +#include "signal.h" + +void check_signal(trapframe_t *tpf) { + lock(); + // prevent nested signal handler + if (curr_thread->signal_is_checking) { + unlock(); + return; + } + curr_thread->signal_is_checking = 1; + unlock(); + + for (int i = 0; i <= SIGNAL_MAX; i++) { + // store context before running handler + store_context(&curr_thread->signal_saved_context); + // if there is a signal handler + if (curr_thread->sigcount[i] > 0) { + lock(); + curr_thread->sigcount[i]--; + unlock(); + run_signal(tpf, i); + } + } + lock(); + curr_thread->signal_is_checking = 0; + unlock(); +} + +void run_signal(trapframe_t* tpf, int signal) { + // assign signal handler + curr_thread->curr_signal_handler = curr_thread->singal_handler[signal]; + // run default handler in kernel mode + if (curr_thread->curr_signal_handler == signal_default_handler) { + signal_default_handler(); + return; + } + // run signal handler in user mode + // char *temp_signal_userstack = kmalloc(USTACK_SIZE); + asm volatile( + "msr elr_el1, %0\n\t" + "msr sp_el0, %1\n\t" + "msr spsr_el1, %2\n\t" + "mov x0, %3\n\t" + "eret\n\t" + :: "r"(USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED + ((unsigned long)signal_handler_wrapper % 0x1000)), "r"(tpf->sp_el0), "r"(tpf->spsr_el1), "r"(curr_thread->curr_signal_handler) + ); +} + +void signal_handler_wrapper() { + // run signal handler + // (curr_thread->curr_signal_handler)(); + // sigreturn + asm volatile( + "blr x0\n\t" + "mov x8, 31\n\t" + "svc 0\n\t" + ); +} + +void signal_default_handler() { + kill(0, curr_thread->pid); +} diff --git a/kernel/string.c b/kernel/string.c new file mode 100644 index 000000000..3b6c025ee --- /dev/null +++ b/kernel/string.c @@ -0,0 +1,131 @@ +#include "string.h" + +void memcpy(char *s1, char *s2, unsigned int len) { + for (unsigned int i = 0; i < len; i++) + s1[i] = s2[i]; +} + +void memset(char *s1, char c, unsigned int len) { + for (unsigned int i = 0; i < len; i++) + s1[i] = c; +} + +unsigned int strlen(char *s) { + unsigned int len = 0; + while (1) { + if (*(s + len) == '\0') + break; + len++; + } + return len; +} + +int strcmp(char *s1, char *s2) { + unsigned int i = 0; + for (i = 0; i < strlen(s1); i++) { + if (s1[i] != s2[i]) + return s1[i] - s2[i]; + } + return s1[i] - s2[i]; +} + +int strncmp(char *s1, char *s2, unsigned int n) { + unsigned int i = 0; + for (i = 0; i < n; i++) { + if (s1[i] != s2[i]) + return s1[i] - s2[i]; + } + return 0; +} + +void strrev(char *s) { + unsigned int len = strlen(s); + char tmp; + for(unsigned int i = 0; i < len/2; i++){ + tmp = s[i]; + s[i] = s[len-i-1]; + s[len-i-1] = tmp; + } +} + +// string to int +int atoi(char* s) { + int res = 0; + for (int i = 0; s[i] != '\0'; ++i) { + if(s[i] > '9' || s[i] < '0') + return res; + res = res * 10 + s[i] - '0'; + } + return res; +} + +// int to string +char* itoa(int x, char *str) { + int i = 0, negative = 0; + // handle 0 explicitly + if (x == 0) { + str[i++] = '0'; + str[i] = '\0'; + return str; + } + // handle negative numbers + if (x < 0) { + negative = 1; + x = -x; + } + // process individual digits + while (x != 0) { + str[i++] = x % 10 + '0'; + x = x / 10; + } + if (negative) + str[i++] = '-'; + str[i] = '\0'; + strrev(str); + return str; +} + +// unsigned int to hex string +void uint_to_hex(unsigned int x, char *s) { + int i = 0, rem = 0, len = strlen(s); + memset(s, 0, len); + // handle 0 explicitly + if (x == 0) { + s[i++] = '0'; + s[i] = '\0'; + return ; + } + // process individual digits + while (x != 0) { + rem = x % 16; + if (rem >= 10) + s[i++] = rem - 10 + 'A'; + else + s[i++] = rem + '0'; + x = x / 16; + } + s[i] = '\0'; + strrev(s); +} + +// hex string to unsigned int +unsigned int hex_to_uint(char *s, unsigned int size) { + unsigned int ret = 0; + for (unsigned int i = 0; i < size; i++) { + ret *= 16; + if (s[i] >= '0' && s[i] <= '9') { + ret += s[i] - '0'; + } else if (s[i] >= 'a' && s[i] <= 'f') { + ret += s[i] - 'a' + 10; + } else if (s[i] >= 'A' && s[i] <= 'F') { + ret += s[i] - 'A' + 10; + } + } + return ret; +} + +// big endian to unsigned int +unsigned int BE_to_uint(void *ptr) { + unsigned char *bytes = (unsigned char *)ptr; + return bytes[3] | bytes[2] << 8 | bytes[1] << 16 | bytes[0] << 24; +} diff --git a/kernel/syscall.c b/kernel/syscall.c new file mode 100644 index 000000000..83db612d7 --- /dev/null +++ b/kernel/syscall.c @@ -0,0 +1,205 @@ +#include "syscall.h" + +// syscall no 0 +int getpid(trapframe_t *tpf) { + tpf->x0 = curr_thread->pid; + return curr_thread->pid; +} + +// syscall no 1 +unsigned long uartread(trapframe_t *tpf, char buf[], unsigned long size) { + int i = 0; + for (int i = 0; i < size; i++) + uart_read(&buf[i], 1); + tpf->x0 = i; + return i; +} + +// syscall no 2 +unsigned long uartwrite(trapframe_t *tpf, const char buf[], unsigned long size) { + int i = 0; + for (int i = 0; i < size; i++) + uart_write_char(buf[i]); + tpf->x0 = i; + return i; +} + +// syscall no 3 +int exec(trapframe_t *tpf, const char *name, char *const argv[]) { + // free alloced area and vma struct + list_head_t *pos = curr_thread->vma_list.next; + while (pos != &curr_thread->vma_list) { + if (((vm_area_struct_t *)pos)->is_alloced) + kfree((void *)PHYS_TO_VIRT(((vm_area_struct_t *)pos)->phys_addr)); + list_head_t *next_pos = pos->next; + kfree(pos); + pos = next_pos; + } + + INIT_LIST_HEAD(&curr_thread->vma_list); + curr_thread->datasize = get_file_size((char*)name); + char *new_data = get_file_start((char *)name); + // re-alloc code & user stack + curr_thread->data = kmalloc(curr_thread->datasize); + curr_thread->stack_alloced_ptr = kmalloc(USTACK_SIZE); + + asm volatile("dsb ish\n\t"); // ensure write has completed + free_page_tables(curr_thread->context.ttbr0_el1, 0); + memset(PHYS_TO_VIRT(curr_thread->context.ttbr0_el1), 0, 0x1000); + asm volatile( + "tlbi vmalle1is\n\t" // invalidate all TLB entries + "dsb ish\n\t" // ensure completion of TLB invalidatation + "isb\n\t" // clear pipeline + ); + + // code + add_vma(curr_thread, 0, curr_thread->datasize, (unsigned long)VIRT_TO_PHYS(curr_thread->data), 7, 1); + // user stack + add_vma(curr_thread, 0xffffffffb000, 0x4000, (unsigned long)VIRT_TO_PHYS(curr_thread->stack_alloced_ptr), 7, 1); + // device memory + add_vma(curr_thread, 0x3C000000L, 0x3000000L, 0x3C000000L, 3, 0); + // signal wrapper + add_vma(curr_thread, USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED, 0x2000, (unsigned long)VIRT_TO_PHYS(signal_handler_wrapper), 5, 0); + // copy file into data + memcpy(curr_thread->data, new_data, curr_thread->datasize); + + // clear signal handler + for (int i = 0; i <= SIGNAL_MAX; i++) + curr_thread->singal_handler[i] = signal_default_handler; + + // set return address, stack pointer and return value + tpf->elr_el1 = 0; + tpf->sp_el0 = 0xfffffffff000; + tpf->x0 = 0; + return 0; +} + +// syscall no 4 +int fork(trapframe_t *tpf) { + lock(); + thread_t *newt = thread_create(curr_thread->data, curr_thread->datasize); + + // copy signal handler + for (int i = 0; i <= SIGNAL_MAX; i++) + newt->singal_handler[i] = curr_thread->singal_handler[i]; + + // copy vma + list_head_t *pos; + list_for_each(pos, &curr_thread->vma_list) { + // ignore device memory and signal wrapper + if (((vm_area_struct_t *)pos)->virt_addr == USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED || ((vm_area_struct_t *)pos)->virt_addr == 0x3C000000L) + continue; + // alloc new area for child & copy content + char *new_alloc = kmalloc(((vm_area_struct_t *)pos)->area_size); + add_vma(newt, ((vm_area_struct_t *)pos)->virt_addr, ((vm_area_struct_t *)pos)->area_size, (unsigned long)VIRT_TO_PHYS(new_alloc), ((vm_area_struct_t *)pos)->rwx, 1); + memcpy(new_alloc, (void*)PHYS_TO_VIRT(((vm_area_struct_t *)pos)->phys_addr), ((vm_area_struct_t *)pos)->area_size); + } + // device memory + add_vma(newt, 0x3C000000L, 0x3000000L, 0x3C000000L, 3, 0); + // signal wrapper + add_vma(newt, USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED, 0x2000, (unsigned long)VIRT_TO_PHYS(signal_handler_wrapper), 5, 0); + + int parent_pid = curr_thread->pid; + // copy kernel stack into new process + for (int i = 0; i < KSTACK_SIZE; i++) + newt->kernel_stack_alloced_ptr[i] = curr_thread->kernel_stack_alloced_ptr[i]; + + store_context(get_current()); + + // child + if (parent_pid != curr_thread->pid) { + tpf->x0 = 0; + return 0; + } + // parent + else { + void *temp_ttbr0_el1 = newt->context.ttbr0_el1; + newt->context = curr_thread->context; + newt->context.ttbr0_el1 = VIRT_TO_PHYS(temp_ttbr0_el1); + newt->context.fp += newt->kernel_stack_alloced_ptr - curr_thread->kernel_stack_alloced_ptr; + newt->context.sp += newt->kernel_stack_alloced_ptr - curr_thread->kernel_stack_alloced_ptr; + unlock(); + tpf->x0 = newt->pid; + return newt->pid; + } +} + +// syscall no 5 +void exit(trapframe_t *tpf, int status) { + thread_exit(); +} + +// syscall no 6 +int syscall_mbox_call(trapframe_t *tpf, unsigned char ch, unsigned int *mbox_user) { + lock(); + unsigned int size_of_mbox = mbox_user[0]; + memcpy((char *)mbox, mbox_user, size_of_mbox); + mailbox_call(ch); + memcpy(mbox_user, (char *)mbox, size_of_mbox); + tpf->x0 = 8; + unlock(); + return 0; +} + +// syscall no 7 +void kill(trapframe_t *tpf, int pid) { + lock(); + // check for invalid pid + if (pid >= PIDMAX || pid < 0 || !threads[pid].isused) { + unlock(); + return; + } + + threads[pid].iszombie = 1; + unlock(); + schedule(); +} + +// syscall no 8 +void signal_register(int signal, void (*handler)()) { + // invalid signal + if (signal > SIGNAL_MAX || signal < 0) + return; + curr_thread->singal_handler[signal] = handler; +} + +// syscall no 9 +void signal_kill(int pid, int signal) { + // check for invalid pid + if (pid >= PIDMAX || pid < 0 || !threads[pid].isused) + return; + lock(); + threads[pid].sigcount[signal]++; + unlock(); +} + +// syscall no 31 +void sigreturn(trapframe_t *tpf) { + load_context(&curr_thread->signal_saved_context); +} + +// syscall no 10 (only implement anonymous page mapping) +void *sys_mmap(trapframe_t *tpf, void *addr, unsigned long len, int prot, int flags, int fd, int file_offset) { + // rounds up + len = len % 0x1000 ? len + (0x1000 - len % 0x1000) : len; + addr = (unsigned long)addr % 0x1000 ? addr + (0x1000 - (unsigned long)addr % 0x1000) : addr; + + // check if overlap + list_head_t *pos; + vm_area_struct_t *the_area_ptr = 0; + list_for_each(pos, &curr_thread->vma_list) { + if ((unsigned long)(addr + len) > ((vm_area_struct_t *)pos)->virt_addr && (unsigned long)addr < ((vm_area_struct_t *)pos)->virt_addr + ((vm_area_struct_t *)pos)->area_size) { + the_area_ptr = (vm_area_struct_t *)pos; + break; + } + } + // if overlap => new region's start address at the end of the area + if (the_area_ptr) { + tpf->x0 = (unsigned long)sys_mmap(tpf, (void *)(the_area_ptr->virt_addr + the_area_ptr->area_size), len, prot, flags, fd, file_offset); + return (void *)tpf->x0; + } + // else, add vma + add_vma(curr_thread, (unsigned long)addr, len, VIRT_TO_PHYS((unsigned long)kmalloc(len)), prot, 1); + tpf->x0 = (unsigned long)addr; + return (void*)tpf->x0; +} diff --git a/kernel/task.c b/kernel/task.c index 78e34f074..c0ed7f36b 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -6,23 +6,19 @@ int curr_priority = 9999; struct list_head *task_list; void task_list_init() { + task_list = kmalloc(sizeof(list_head_t)); INIT_LIST_HEAD(task_list); } void add_task(void *function, unsigned long long priority) { - task_t *tmp_task = simple_alloc(sizeof(task_t)); + task_t *tmp_task = kmalloc(sizeof(task_t)); // store function into task tmp_task->func = function; // store priority into task tmp_task->priority = priority; - // init list head - INIT_LIST_HEAD(&tmp_task->listhead); - - // critical section - disable_interrupt(); - // add tmp_task into task_list (sorted) + lock(); struct list_head *curr; list_for_each(curr, task_list) { if (((task_t *)curr)->priority > tmp_task->priority) { @@ -35,41 +31,38 @@ void add_task(void *function, unsigned long long priority) { if (list_is_head(curr, task_list)) list_add_tail(&tmp_task->listhead, task_list); - enable_interrupt(); + unlock(); } void run_preemptive_tasks() { - // do the tasks with interrupts enabled - enable_interrupt(); - - while (!list_empty(task_list)) { + while (1) { // critical section - disable_interrupt(); + lock(); + + // if there is no task + if (list_empty(task_list)) { + unlock(); + break; + } task_t *tmp_task = (task_t *)task_list->next; // check for preemption if (tmp_task->priority >= curr_priority) { - enable_interrupt(); + unlock(); break; } - // verify preemption - // if (curr_priority != 9999) { - // uart_printf("---preemption---\r\n"); - // uart_printf("task priority : %d, curr priority %d\r\n", tmp_task->priority, curr_priority); - // } list_del_entry((struct list_head *)tmp_task); // store previous task priority. if there is not preemption => prev_priority = 9999 int prev_priority = curr_priority; // before running the task, set its priority to curr_priority curr_priority = tmp_task->priority; - enable_interrupt(); // run task + unlock(); ((void (*)())tmp_task->func)(); // after running the task, set prev_priority equals to curr_priority - disable_interrupt(); curr_priority = prev_priority; - enable_interrupt(); + kfree(tmp_task); } } diff --git a/kernel/timer.c b/kernel/timer.c index 3dab56463..f2a0ca1a6 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -4,6 +4,12 @@ struct list_head *timer_event_list; void timer_list_init() { + unsigned long long tmp; + asm volatile("mrs %0, cntkctl_el1" : "=r"(tmp)); + tmp |= 1; + asm volatile("msr cntkctl_el1, %0" :: "r"(tmp)); + + timer_event_list = kmalloc(sizeof(list_head_t)); INIT_LIST_HEAD(timer_event_list); } @@ -26,29 +32,33 @@ void core_timer_disable() { } void core_timer_handler() { + lock(); // if there is no timer_event => set large tval if (list_empty(timer_event_list)) { set_core_timer_interrupt_abs(get_tick_plus_s(10000)); + unlock(); return; } // next timer_event timer_event_callback((timer_event_t *)timer_event_list->next); + unlock(); } -void add_timer(void *function, unsigned long long timeout, char *args) { - timer_event_t *tmp_timer_event = simple_alloc(sizeof(timer_event_t)); +void add_timer(void *function, unsigned long long timeout, char *args, int bytick) { + timer_event_t *tmp_timer_event = kmalloc(sizeof(timer_event_t)); // store function into timer_event tmp_timer_event->func = function; // store argument string into timer_event - tmp_timer_event->args = simple_alloc(strlen(args) + 1); + tmp_timer_event->args = kmalloc(strlen(args) + 1); memcpy(tmp_timer_event->args, args, strlen(args) + 1); // store interrupt time into timer_event - tmp_timer_event->interrupt_time = get_tick_plus_s(timeout); - - // init list head - INIT_LIST_HEAD(&tmp_timer_event->listhead); + if (bytick == 0) + tmp_timer_event->interrupt_time = get_tick_plus_s(timeout); + else + tmp_timer_event->interrupt_time = get_tick_plus_s(0) + timeout; // add timer_event into timer_event_list (sorted) + lock(); struct list_head *curr; list_for_each (curr, timer_event_list) { // put this timer before the first element larger than it @@ -65,6 +75,7 @@ void add_timer(void *function, unsigned long long timeout, char *args) { // set interrupt to first event set_core_timer_interrupt_abs(((timer_event_t *)timer_event_list->next)->interrupt_time); + unlock(); } // set timer interrupt (absolutely) use cval @@ -95,10 +106,13 @@ unsigned long long get_tick_plus_s(unsigned long long second) { // execute timer_event function and set next timer interrupt void timer_event_callback(timer_event_t *timer_event) { - // delete the event - list_del_entry((struct list_head *)timer_event); // call the callback function in timer_event ((void (*)(char *))timer_event->func)(timer_event->args); + // delete the event + list_del_entry((struct list_head *)timer_event); + // free the timer event and its args + kfree(timer_event->args); + kfree(timer_event); // if next timer_event is existing => set interrupt if (!list_empty(timer_event_list)) @@ -117,5 +131,5 @@ void two_second_alert(char *str) { // print message uart_printf("Core Timer Interrupt -> seconds after booting : %d\r\n", cntpct_el0 / cntfrq_el0); // set next timer - add_timer(two_second_alert, 2, ""); + add_timer(two_second_alert, 2, "", 0); } diff --git a/kernel/uart.c b/kernel/uart.c index a41ae1e4b..7f46e8936 100644 --- a/kernel/uart.c +++ b/kernel/uart.c @@ -1,7 +1,7 @@ #include "uart.h" -char uart_read_buf[0x100] = {}; -char uart_write_buf[0x100] = {}; +char uart_read_buf[MAX_BUF_SIZE] = {}; +char uart_write_buf[MAX_BUF_SIZE] = {}; unsigned int uart_read_buf_begin = 0, uart_read_buf_end = 0; unsigned int uart_write_buf_begin = 0, uart_write_buf_end = 0; @@ -52,8 +52,7 @@ void uart_init() { } void uart_write_char(char c) { - while (!(*AUX_MU_LSR_REG & 0x20)) - nop_delay(1); + do{asm volatile("nop");}while(!(*AUX_MU_LSR_REG & 0x20)); *AUX_MU_IO_REG = (unsigned int)c; } @@ -88,8 +87,7 @@ int uart_printf(char *fmt, ...) { void uart_read(char* buf, unsigned int size) { for (unsigned int i = 0; i < size; i++) { - while (!(*AUX_MU_LSR_REG & 0x01)) - nop_delay(1); + do{asm volatile("nop");}while(!(*AUX_MU_LSR_REG & 0x01)); buf[i] = (char)(*AUX_MU_IO_REG); } } @@ -104,14 +102,16 @@ void nop_delay(unsigned int t) { // read data to read buffer void uart_interrupt_r_handler() { // read buffer full => disable read interrupt - if ((uart_read_buf_end + 1) % 0x100 == uart_read_buf_begin) { + if ((uart_read_buf_end + 1) % MAX_BUF_SIZE == uart_read_buf_begin) { + // NOT SURE == clear fifo + *AUX_MU_IIR_REG = 0xc2; disable_mini_uart_r_interrupt(); return; } // read to buffer uart_read(&uart_read_buf[uart_read_buf_end++], 1); // circular buffer - if (uart_read_buf_end >= 0x100) + if (uart_read_buf_end >= MAX_BUF_SIZE) uart_read_buf_end = 0; // unmasks the device’s interrupt line @@ -120,17 +120,16 @@ void uart_interrupt_r_handler() { // write data from write buffer void uart_interrupt_w_handler() { - // verify preemption - // nop_delay(10000); // buffer is empty => disable write interrupt if (uart_write_buf_begin == uart_write_buf_end) { + *AUX_MU_IIR_REG = 0xc4; disable_mini_uart_w_interrupt(); return; } // write from buffer uart_write_char(uart_write_buf[uart_write_buf_begin++]); // circular buffer - if (uart_write_buf_begin >= 0x100) + if (uart_write_buf_begin >= MAX_BUF_SIZE) uart_write_buf_begin = 0; // unmasks the device’s interrupt line @@ -177,19 +176,19 @@ int mini_uart_w_interrupt_is_enable() { // wrtie data to write buffer void uart_write_char_async(char c) { // wait for full buffer - while ((uart_write_buf_end + 1) % 0x100 == uart_write_buf_begin) { + while ((uart_write_buf_end + 1) % MAX_BUF_SIZE == uart_write_buf_begin) { // start asynchronous transfer enable_mini_uart_w_interrupt(); } // critical section - disable_interrupt(); + lock(); // write to buffer uart_write_buf[uart_write_buf_end++] = c; // circular buffer - if (uart_write_buf_end >= 0x100) + if (uart_write_buf_end >= MAX_BUF_SIZE) uart_write_buf_end = 0; // start asynchronous transfer - enable_interrupt(); + unlock(); // enable interrupt to transfer enable_mini_uart_w_interrupt(); } @@ -235,12 +234,12 @@ char uart_read_char_async() { enable_mini_uart_r_interrupt(); // critical section - disable_interrupt(); + lock(); char r = uart_read_buf[uart_read_buf_begin++]; - if (uart_read_buf_begin >= 0x100) + if (uart_read_buf_begin >= MAX_BUF_SIZE) uart_read_buf_begin = 0; - enable_interrupt(); + unlock(); return r; } diff --git a/makefile b/makefile index b8fdd5f87..2d3075bd5 100644 --- a/makefile +++ b/makefile @@ -3,10 +3,13 @@ all: make -C bootloader run: - qemu-system-aarch64 -M raspi3b -kernel ./kernel/kernel8.img -display none -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb + qemu-system-aarch64 -M raspi3 -kernel ./kernel/kernel8.img -display none -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb + +run_display: + qemu-system-aarch64 -M raspi3 -kernel ./kernel/kernel8.img -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb debug: - qemu-system-aarch64 -M raspi3b -kernel ./kernel/kernel8.img -display none -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -s -S + qemu-system-aarch64 -M raspi3 -kernel ./kernel/kernel8.img -display none -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -s -S cpio: cd rootfs && find . | cpio -o -H newc > ../initramfs.cpio From 630b514a12fb01752ebf805cbcb36a9f8173ce16 Mon Sep 17 00:00:00 2001 From: cl3nn0 Date: Thu, 23 Jun 2022 21:38:28 +0800 Subject: [PATCH 2/2] Lab 7 --- include/buddy.h | 1 - include/dtb.h | 1 - include/exception.h | 8 +- include/gpio.h | 3 +- include/mbox.h | 8 +- include/node.h | 9 ++ include/reset.h | 5 +- include/sched.h | 16 +-- include/signal.h | 2 - include/syscall.h | 13 ++- include/timer.h | 3 +- include/tmpfs.h | 34 +++++++ include/uart.h | 2 +- include/vfs.h | 75 ++++++++++++++ initramfs.cpio | Bin 248320 -> 404992 bytes kernel/boot.s | 52 +--------- kernel/buddy.c | 20 +--- kernel/ctx_switch.s | 11 +-- kernel/dtb.c | 4 +- kernel/entry.s | 1 - kernel/exception.c | 25 +++-- kernel/linker.ld | 7 +- kernel/main.c | 6 +- kernel/malloc.c | 6 -- kernel/mbox.c | 31 ++---- kernel/sched.c | 61 +++--------- kernel/shell.c | 31 ++++-- kernel/signal.c | 8 +- kernel/syscall.c | 234 ++++++++++++++++++++++++++++---------------- kernel/tmpfs.c | 142 +++++++++++++++++++++++++++ kernel/vfs.c | 230 +++++++++++++++++++++++++++++++++++++++++++ rootfs/vfs1.img | Bin 0 -> 404216 bytes 32 files changed, 750 insertions(+), 299 deletions(-) create mode 100644 include/node.h create mode 100644 include/tmpfs.h create mode 100644 include/vfs.h create mode 100644 kernel/tmpfs.c create mode 100644 kernel/vfs.c create mode 100644 rootfs/vfs1.img diff --git a/include/buddy.h b/include/buddy.h index d50d9ddca..6526c04b1 100644 --- a/include/buddy.h +++ b/include/buddy.h @@ -1,6 +1,5 @@ #ifndef BUDDY_H #define BUDDY_H -#include "mmu.h" #include "dtb.h" #include "list.h" #include "math.h" diff --git a/include/dtb.h b/include/dtb.h index 73186299c..52c64d5dd 100644 --- a/include/dtb.h +++ b/include/dtb.h @@ -1,6 +1,5 @@ #ifndef DTB_H #define DTB_H -#include "mmu.h" #include "uart.h" #include "string.h" diff --git a/include/exception.h b/include/exception.h index 588e859c8..ab77666f5 100644 --- a/include/exception.h +++ b/include/exception.h @@ -1,8 +1,6 @@ #ifndef EXCEPTION_H #define EXCEPTION_H #include "tpf.h" -#include "esr.h" -#include "mmu.h" #include "uart.h" #include "task.h" #include "timer.h" @@ -10,7 +8,7 @@ #include "syscall.h" // https://github.com/Tekki/raspberrypi-documentation/blob/master/hardware/raspberrypi/bcm2836/QA7_rev3.4.pdf (p.16) -#define CORE0_INTERRUPT_SOURCE ((volatile unsigned int*)(PHYS_TO_VIRT(0x40000060))) +#define CORE0_INTERRUPT_SOURCE ((volatile unsigned int*)(0x40000060)) #define INTERRUPT_SOURCE_GPU (1<<8) #define INTERRUPT_SOURCE_CNTPNSIRQ (1<<1) @@ -20,7 +18,7 @@ number of 'normal' interrupt status bits have been added to this register. This pending base' register different from the other 'base' interrupt registers */ // https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf (p.112~115) -#define PBASE PHYS_TO_VIRT(0x3F000000) +#define PBASE 0x3F000000 #define IRQ_BASIC_PENDING ((volatile unsigned int*)(PBASE+0x0000B200)) #define IRQ_PENDING_1 ((volatile unsigned int*)(PBASE+0x0000B204)) #define IRQ_PENDING_2 ((volatile unsigned int*)(PBASE+0x0000B208)) @@ -33,7 +31,7 @@ pending base' register different from the other 'base' interrupt registers #define DISABLE_BASIC_IRQS ((volatile unsigned int*)(PBASE+0x0000B224)) #define IRQ_PENDING_1_AUX_INT (1<<29) -void sync_64_router(trapframe_t *tpf, unsigned long x1); +void sync_64_router(trapframe_t *tpf); void irq_router(trapframe_t *tpf); void invalid_exception_router(unsigned long long x0); diff --git a/include/gpio.h b/include/gpio.h index 29d7a405c..435fdf7c0 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -1,8 +1,7 @@ #ifndef GPIO_H #define GPIO_H -#include "mmu.h" -#define MMIO_BASE PHYS_TO_VIRT(0x3f000000) +#define MMIO_BASE 0x3f000000 #define GPIO_BASE (MMIO_BASE + 0x200000) #define GPFSEL0 ((volatile unsigned int*)(GPIO_BASE + 0x00)) diff --git a/include/mbox.h b/include/mbox.h index b398f0f2f..715b67fbd 100644 --- a/include/mbox.h +++ b/include/mbox.h @@ -2,8 +2,6 @@ #define MAILBOX_H #include "gpio.h" -extern volatile unsigned int __attribute__((aligned(16))) mbox[72]; - #define VIDEOCORE_MBOX (MMIO_BASE + 0xB880) // MMIO base address + MAILBOX offset #define MAILBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX)) #define MAILBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10)) @@ -36,8 +34,8 @@ extern volatile unsigned int __attribute__((aligned(16))) mbox[72]; #define GET_BOARD_REVISION 0x00010002 #define GET_ARM_MEMORY 0x00010005 -unsigned int get_board_revision(unsigned int* board_revision); -unsigned int get_arm_memory(unsigned int* base_addr,unsigned int* size); -unsigned int mailbox_call(unsigned char); +unsigned int get_board_revision(volatile unsigned int [36]); +unsigned int get_arm_memory(volatile unsigned int [36]); +unsigned int mailbox_call(volatile unsigned int [36], unsigned char); #endif \ No newline at end of file diff --git a/include/node.h b/include/node.h new file mode 100644 index 000000000..d5b69fb3c --- /dev/null +++ b/include/node.h @@ -0,0 +1,9 @@ +#ifndef NODE_H +#define NODE_H + +enum node_type { + dir_t, + file_t +}; + +#endif \ No newline at end of file diff --git a/include/reset.h b/include/reset.h index b1210922a..861238f01 100644 --- a/include/reset.h +++ b/include/reset.h @@ -1,10 +1,9 @@ #ifndef RESET_H #define RESET_H -#include "mmu.h" #define PM_PASSWORD 0x5a000000 -#define PM_RSTC PHYS_TO_VIRT(0x3f10001c) -#define PM_WDOG PHYS_TO_VIRT(0x3f100024) +#define PM_RSTC 0x3f10001c +#define PM_WDOG 0x3f100024 void set(long addr, unsigned int value); void reset(int tick); diff --git a/include/sched.h b/include/sched.h index 7c6fc8ce8..dff820db2 100644 --- a/include/sched.h +++ b/include/sched.h @@ -1,18 +1,18 @@ #ifndef SCHED_H #define SCHED_H -#include "mmu.h" +#include "vfs.h" #include "list.h" #include "buddy.h" -#include "string.h" #include "signal.h" #include "malloc.h" +#include "syscall.h" #include "exception.h" #include "simple_alloc.h" #define PIDMAX 4096 -#define USTACK_SIZE 0x4000 -#define KSTACK_SIZE 0x4000 -#define SIGNAL_MAX 32 +#define USTACK_SIZE 0x10000 +#define KSTACK_SIZE 0x10000 +#define SIGNAL_MAX 16 extern void switch_to(void *curr_context, void *next_context); extern void store_context(void *curr_context); @@ -22,7 +22,6 @@ extern void *get_current(); typedef struct thread_context { unsigned long x19, x20, x21, x22, x23, x24, x25, x26, x27, x28; unsigned long fp, lr, sp; - void* ttbr0_el1; } thread_context_t; typedef struct thread { @@ -39,8 +38,9 @@ typedef struct thread { int sigcount[SIGNAL_MAX + 1]; void (*curr_signal_handler)(); int signal_is_checking; - list_head_t vma_list; thread_context_t signal_saved_context; + char curr_working_dir[256]; + struct file* file_descriptors_table[16]; } thread_t; extern thread_t *curr_thread; @@ -52,7 +52,7 @@ void init_thread_sched(); void idle(); void schedule(); void kill_zombies(); -thread_t *thread_create(void *start, unsigned int filesize); +thread_t *thread_create(void *start); void thread_exit(); int exec_thread(char *data, unsigned int filesize); void schedule_timer(char *notuse); diff --git a/include/signal.h b/include/signal.h index 6261190c8..e748449dc 100644 --- a/include/signal.h +++ b/include/signal.h @@ -6,8 +6,6 @@ #include "syscall.h" #include "exception.h" -#define USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED 0xffffffff9000L - void check_signal(trapframe_t *tpf); void run_signal(trapframe_t* tpf, int signal); void signal_handler_wrapper(); diff --git a/include/syscall.h b/include/syscall.h index e0a9382a9..3920de259 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -1,13 +1,15 @@ #ifndef SYSCALL_H #define SYSCALL_H -#include "mmu.h" #include "tpf.h" +#include "vfs.h" #include "cpio.h" #include "mbox.h" #include "sched.h" #include "buddy.h" #include "exception.h" +#define MAX_FD 16 + int getpid(trapframe_t *tpf); unsigned long uartread(trapframe_t *tpf, char buf[], unsigned long size); unsigned long uartwrite(trapframe_t *tpf, const char buf[], unsigned long size); @@ -19,6 +21,13 @@ void kill(trapframe_t *tpf, int pid); void signal_register(int signal, void (*handler)()); void signal_kill(int pid, int signal); void sigreturn(trapframe_t *tpf); -void *sys_mmap(trapframe_t *tpf, void *addr, unsigned long len, int prot, int flags, int fd, int file_offset); + +int sys_open(trapframe_t *tpf, const char *pathname, int flags); +int sys_close(trapframe_t *tpf, int fd); +long sys_write(trapframe_t *tpf, int fd, const void *buf, unsigned long count); +long sys_read(trapframe_t *tpf, int fd, void *buf, unsigned long count); +int sys_mkdir(trapframe_t *tpf, const char *pathname, unsigned mode); +int sys_mount(trapframe_t *tpf, const char *src, const char *target, const char *filesystem, unsigned long flags, const void *data); +int sys_chdir(trapframe_t *tpf, const char *path); #endif \ No newline at end of file diff --git a/include/timer.h b/include/timer.h index b9b41306a..ce887c3f9 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,6 +1,5 @@ #ifndef TIMER_H #define TIMER_H -#include "mmu.h" #include "uart.h" #include "list.h" #include "string.h" @@ -8,7 +7,7 @@ #include "simple_alloc.h" // https://github.com/Tekki/raspberrypi-documentation/blob/master/hardware/raspberrypi/bcm2836/QA7_rev3.4.pdf (p.13) -#define CORE0_TIMER_IRQ_CTRL PHYS_TO_VIRT(0x40000040) +#define CORE0_TIMER_IRQ_CTRL 0x40000040 #define STR(x) #x #define XSTR(s) STR(s) diff --git a/include/tmpfs.h b/include/tmpfs.h new file mode 100644 index 000000000..f9cec3892 --- /dev/null +++ b/include/tmpfs.h @@ -0,0 +1,34 @@ +#ifndef TMPFS_H +#define TMPFS_H +#include "vfs.h" +#include "node.h" +#include "uart.h" +#include "malloc.h" + +#define FILE_NAME_MAX 32 +#define MAX_DIR_ENTRY 32 +#define MAX_FILE_SIZE 4096 + +struct tmpfs_inode { + enum node_type type; + char name[FILE_NAME_MAX]; + struct vnode *entry[MAX_DIR_ENTRY]; + char *data; + unsigned long datasize; +}; + +int register_tmpfs(); +int tmpfs_setup_mount(struct filesystem *fs, struct mount *_mount); +struct vnode *tmpfs_create_vnode(struct mount *_mount, enum node_type type); + +int tmpfs_write(struct file *file, const void *buf, unsigned long len); +int tmpfs_read(struct file *file, void *buf, unsigned long len); +int tmpfs_open(struct vnode *file_node, struct file **target); +int tmpfs_close(struct file *file); +long tmpfs_getsize(struct vnode *vnode); + +int tmpfs_lookup(struct vnode *dir_node, struct vnode **target, const char *component_name); +int tmpfs_create(struct vnode *dir_node, struct vnode **target, const char *component_name); +int tmpfs_mkdir(struct vnode *dir_node, struct vnode **target, const char *component_name); + +#endif \ No newline at end of file diff --git a/include/uart.h b/include/uart.h index c9837fc08..8e43c908a 100644 --- a/include/uart.h +++ b/include/uart.h @@ -6,7 +6,7 @@ #define MAX_BUF_SIZE 0x1000 -#define IRQS1 ((volatile unsigned int*)(PHYS_TO_VIRT(0x3f00b210))) +#define IRQS1 ((volatile unsigned int*)(0x3f00b210)) #define AUX_BASE (MMIO_BASE + 0x00215000) diff --git a/include/vfs.h b/include/vfs.h new file mode 100644 index 000000000..769daab1c --- /dev/null +++ b/include/vfs.h @@ -0,0 +1,75 @@ +#ifndef VFS_H +#define VFS_H +#include "uart.h" +#include "node.h" +#include "string.h" +#include "malloc.h" +#include "tmpfs.h" + +#define MAX_FS_REG 256 +#define MAX_PATH_NAME 256 +#define O_CREAT 00000100 + +struct vnode { + struct mount *mount; + struct vnode_operations *v_ops; + struct file_operations *f_ops; + void *internal; +}; + +// file handle +struct file { + struct vnode *vnode; + unsigned long f_pos; // RW position of this file handle + struct file_operations *f_ops; + int flags; +}; + +// mounted file system +struct mount { + struct vnode *root; + struct filesystem *fs; +}; + +struct filesystem { + const char *name; + int (*setup_mount)(struct filesystem *fs, struct mount *mount); +}; + +struct file_operations { + int (*write)(struct file *file, const void *buf, unsigned long len); + int (*read)(struct file *file, void *buf, unsigned long len); + int (*open)(struct vnode *file_node, struct file **target); + int (*close)(struct file *file); + long (*getsize)(struct vnode *vnode); +}; + +struct vnode_operations { + int (*lookup)(struct vnode *dir_node, struct vnode **target, + const char *component_name); + int (*create)(struct vnode *dir_node, struct vnode **target, + const char *component_name); + int (*mkdir)(struct vnode *dir_node, struct vnode **target, + const char *component_name); +}; + +struct mount *rootfs; +struct filesystem reg_fs[MAX_FS_REG]; + +int register_filesystem(struct filesystem *fs); +struct filesystem *find_filesystem(const char *fs_name); + +// file operations +int vfs_write(struct file *file, const void *buf, unsigned long len); +int vfs_read(struct file *file, void *buf, unsigned long len); +int vfs_open(const char *pathname, int flags, struct file **target); +int vfs_close(struct file *file); +// vnode operations +int vfs_lookup(const char *pathname, struct vnode **target); +int vfs_mkdir(const char *pathname); +int vfs_mount(const char *target, const char *filesystem); + +void init_rootfs(); +char* path_to_absolute(char* path, char* curr_working_dir); + +#endif \ No newline at end of file diff --git a/initramfs.cpio b/initramfs.cpio index 011046531134dab1c4c5801d992bc8dfa44a9c3c..b42cbe5f7db6c1b0c123971223c86e8235422bcd 100644 GIT binary patch literal 404992 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 literal 248320 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 diff --git a/kernel/boot.s b/kernel/boot.s index 57d933a3f..506583212 100644 --- a/kernel/boot.s +++ b/kernel/boot.s @@ -1,4 +1,3 @@ -#include "mmu.h" .section ".text.boot" .global _start @@ -16,56 +15,15 @@ _start: 2: bl from_el2_to_el1 - // set tcr_el1 to TCR_CONFIG_DEFAULT (0x0000000080100010) - movz x4, 0x0010 - movk x4, 0x8010, lsl 16 - msr tcr_el1, x4 - - // set memory attributes to MAIR_CONFIG_DEFAULT (0x0000000000004400) - movz x4, 0x4400 - msr mair_el1, x4 - - // enable MMU - mov x4, 0x1000 // PGD's page frame at 0x1000 - mov x1, 0x2000 // PUD's page frame at 0x2000 - - // ldr x2, = BOOT_PGD_ATTR - movz x2, 0x0003 - orr x2, x1, x2 // combine the physical address of next level page with attribute. - str x2, [x4] - - // ldr x2, = BOOT_PUD_ATTR - movz x2, 0x0401 - mov x3, 0x00000000 - orr x3, x2, x3 - str x3, [x1] // 1st 1GB mapped by the 1st entry of PUD - mov x3, 0x40000000 - orr x3, x2, x3 - str x3, [x1, 8] // 2nd 1GB mapped by the 2nd entry of PUD - - msr ttbr0_el1, x4 // load PGD to the bottom translation-based register. - msr ttbr1_el1, x4 // also load PGD to the upper translation based register. - - mov sp, 0x3c000000 - bl set_2M_kernel_mmu - - mrs x2, sctlr_el1 - orr x2 , x2, 1 - msr sctlr_el1, x2 // enable MMU, cache remains disabled - - // indirect branch to the upper VA - ldr x2, =set_exception_vector_table - br x2 - set_exception_vector_table: adr x1, exception_vector_table msr vbar_el1, x1 - // set top of stack at 0xffff00003c000000 (last usable memory) - movz x3, 0x0000 - movk x3, 0x3c00, lsl 16 - movk x3, 0xffff, lsl 48 - mov sp, x3 + // set top of stack just before our code (stack grows to a lower address per AAPCS64) + // ldr x1, =_start + // mov sp, x1 + // set top of stack at 0x3c000000 (last usable memory) + mov sp, 0x3c000000 // clear bss ldr x1, =_bss_start diff --git a/kernel/buddy.c b/kernel/buddy.c index dd64edbea..108b020d4 100644 --- a/kernel/buddy.c +++ b/kernel/buddy.c @@ -91,7 +91,6 @@ void page_alloc_init() { } void *alloc_pages(int num) { - // uart_printf_async("------------ In function alloc_pages(%d) ------------\r\n", num); int idx, exp, alloc_exp; frame_hdr *hdr; @@ -130,12 +129,10 @@ void *alloc_pages(int num) { buddy_hdr = idx_to_addr(buddy_idx); list_add(&buddy_hdr->list, &freelists[alloc_exp]); - // uart_printf_async("[-] Release redundant memory (idx : %d -> %d), this block has exp : %d\r\n", idx, buddy_idx, alloc_exp); } frame_ents[idx].exp = exp; frame_ents[idx].allocated = 1; - // uart_printf_async("[+] Successfully allocate (idx : %d, exp : %d)\r\n", idx, exp); return (void *)hdr; } @@ -149,7 +146,6 @@ static inline void _free_page(frame_hdr *page) { buddy_idx = idx ^ (1 << exp); // merge while (exp < MAX_ORDER - 1 && !frame_ents[buddy_idx].allocated && frame_ents[buddy_idx].exp == exp) { - // uart_printf_async("[*] Coalesce blocks (idx : %d & %d), and their new exp is %d\r\n", idx, buddy_idx, exp + 1); frame_hdr *hdr; exp += 1; hdr = idx_to_addr(idx); @@ -166,7 +162,6 @@ static inline void _free_page(frame_hdr *page) { } void free_page(void *page) { - // uart_printf_async("++++++++++++ In function free_page(idx = %d) ++++++++++++\r\n", addr_to_idx(page)); _free_page((frame_hdr *)page); } @@ -179,17 +174,16 @@ void memory_reserve(void *start, void *end) { int idx = addr_to_idx(start); frame_ents[idx].allocated = 1; start = (void *)((unsigned long long int)start + PAGE_SIZE); - // uart_printf_async("Reserve page idx : %d, address : 0x%x\r\n", idx, idx_to_addr(idx)); } } void mm_init() { // buddy system first stage init - buddy_alloc_init((void *)PHYS_TO_VIRT(0), (void *)PHYS_TO_VIRT(0x3c000000)); + buddy_alloc_init((void *)0, (void *)0x3c000000); // small chunk first stage init sc_alloc_init(); // Spin tables for multicore boot - memory_reserve((void *)PHYS_TO_VIRT(0), (void *)PHYS_TO_VIRT(0x5000)); + memory_reserve((void *)0, (void *)0x1000); // Kernel image in the physical memory memory_reserve(&_text_start, &_heap_start); // Initramfs @@ -197,9 +191,9 @@ void mm_init() { // Device tree (qemu = 83580, rpi3 = 32937) memory_reserve(DTB_ADDRESS, DTB_ADDRESS + 83580); // for simple_alloc - memory_reserve((void *)PHYS_TO_VIRT(0x2c000000), (void *)PHYS_TO_VIRT(0x2e000000)); + memory_reserve((void *)0x2c000000, (void *)0x2e000000); // for kernel stack - memory_reserve((void *)PHYS_TO_VIRT(0x2e000000), (void *)PHYS_TO_VIRT(0x3c000000)); + memory_reserve((void *)0x2e000000, (void *)0x3c000000); // buddy system second stage init page_alloc_init(); // small chunk second stage init @@ -216,23 +210,17 @@ void page_allocator_test() char *ptr5 = alloc_pages(2); // idx = 32786 char *ptr6 = alloc_pages(1); // idx = 32785 - // uart_printf_async("------------------------------------------------------------\r\n"); - // test alloc_pages -> release redundant memory free_page(ptr3); // idx = 4 (idx 5, 6, 7 are also freed) char *ptr7 = alloc_pages(1); // idx = 4 (split ptr3) char *ptr8 = alloc_pages(2); // idx = 6 char *ptr9 = alloc_pages(1); // idx = 5 - // uart_printf_async("------------------------------------------------------------\r\n"); - // test free_page -> coalesce blocks free_page(ptr7); free_page(ptr8); free_page(ptr9); - // uart_printf_async("------------------------------------------------------------\r\n"); - // free all pointer free_page(ptr1); free_page(ptr2); diff --git a/kernel/ctx_switch.s b/kernel/ctx_switch.s index 2cc3a6fe6..ce2cafa4d 100644 --- a/kernel/ctx_switch.s +++ b/kernel/ctx_switch.s @@ -15,16 +15,9 @@ switch_to: ldp x25, x26, [x1, 16 * 3] ldp x27, x28, [x1, 16 * 4] ldp fp, lr, [x1, 16 * 5] - ldp x9, x0, [x1, 16 * 6] - mov sp, x9 + ldr x9, [x1, 16 * 6] + mov sp, x9 msr tpidr_el1, x1 - - dsb ish // ensure write has completed - msr ttbr0_el1, x0 // switch translation based address. - tlbi vmalle1is // invalidate all TLB entries - dsb ish // ensure completion of TLB invalidatation - isb // clear pipeline - ret .global store_context diff --git a/kernel/dtb.c b/kernel/dtb.c index 6a3e32d52..a0077a9f6 100644 --- a/kernel/dtb.c +++ b/kernel/dtb.c @@ -71,11 +71,11 @@ void dtb_parser(dtb_callback_t callback) { void dtb_get_initrd_callback(unsigned int token_type, char* name, char* data) { if (token_type == FDT_PROP && !strcmp(name, "linux,initrd-start")) { - INITRD_ADDR = (void *)(PHYS_TO_VIRT((unsigned long long int)BE_to_uint(data))); + INITRD_ADDR = (void *)(unsigned long long int)BE_to_uint(data); uart_printf("Initramfs address: 0x%x\r\n", INITRD_ADDR); } if (token_type == FDT_PROP && !strcmp(name, "linux,initrd-end")) { - INITRD_END = (void *)(PHYS_TO_VIRT((unsigned long long int)BE_to_uint(data))); + INITRD_END = (void *)(unsigned long long int)BE_to_uint(data); } } diff --git a/kernel/entry.s b/kernel/entry.s index 1cd6c3601..6c08de890 100644 --- a/kernel/entry.s +++ b/kernel/entry.s @@ -147,7 +147,6 @@ err_el1h_invalid: sync_el0_64: save_all mov x0, sp // trap frame - mrs x1, esr_el1 bl sync64_router load_all eret diff --git a/kernel/exception.c b/kernel/exception.c index 5fb5a96e7..0c1579d06 100644 --- a/kernel/exception.c +++ b/kernel/exception.c @@ -1,13 +1,6 @@ #include "exception.h" -void sync64_router(trapframe_t *tpf, unsigned long x1) { - // for page fault - esr_el1_t *esr; - esr = (esr_el1_t *)&x1; - if (esr->ec == DATA_ABORT_LOWER || esr->ec == INS_ABORT_LOWER) { - handle_abort(esr); - return; - } +void sync64_router(trapframe_t *tpf) { // for sys call enable_interrupt(); unsigned long long syscall_no = tpf->x8; @@ -32,8 +25,20 @@ void sync64_router(trapframe_t *tpf, unsigned long x1) { signal_register(tpf->x0, (void (*)())tpf->x1); else if (syscall_no == 9) signal_kill(tpf->x0, tpf->x1); - else if (syscall_no == 10) - sys_mmap(tpf, (void *)tpf->x0, tpf->x1, tpf->x2, tpf->x3, tpf->x4, tpf->x5); + else if (syscall_no == 11) + sys_open(tpf, (char*)tpf->x0, tpf->x1); + else if (syscall_no == 12) + sys_close(tpf, tpf->x0); + else if (syscall_no == 13) + sys_write(tpf, tpf->x0, (char *)tpf->x1, tpf->x2); + else if (syscall_no == 14) + sys_read(tpf, tpf->x0, (char *)tpf->x1, tpf->x2); + else if (syscall_no == 15) + sys_mkdir(tpf, (char *)tpf->x0, tpf->x1); + else if (syscall_no == 16) + sys_mount(tpf, (char *)tpf->x0, (char *)tpf->x1, (char *)tpf->x2, tpf->x3, (void*)tpf->x4); + else if (syscall_no == 17) + sys_chdir(tpf, (char *)tpf->x0); else if (syscall_no == 31) sigreturn(tpf); } diff --git a/kernel/linker.ld b/kernel/linker.ld index 654d459bf..0e69a3494 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -1,13 +1,12 @@ /* entry point */ ENTRY(_start) -_simple_alloc_start = 0xffff00002c000000; -_simple_alloc_end = 0xffff00002dffffff; +_simple_alloc_start = 0x2c000000; +_simple_alloc_end = 0x2dffffff; SECTIONS { - . = 0xffff000000000000; - . += 0x80000; + . = 0x80000; _text_start = .; .text : diff --git a/kernel/main.c b/kernel/main.c index 6d585c0b9..5a21f18fb 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,16 +1,18 @@ -#include "mmu.h" #include "dtb.h" #include "cpio.h" #include "task.h" #include "shell.h" #include "buddy.h" #include "exception.h" +#include "vfs.h" void kernel_main(char* x0) { // init dtb - dtb_init(PHYS_TO_VIRT((unsigned long)x0)); + dtb_init(x0); // init memory mm_init(); + // init file system + init_rootfs(); // init task task_list_init(); // enable interrupt diff --git a/kernel/malloc.c b/kernel/malloc.c index 4e238d07d..34adeed8f 100644 --- a/kernel/malloc.c +++ b/kernel/malloc.c @@ -39,7 +39,6 @@ void sc_init() { } void *sc_alloc(int size) { - // uart_printf("------------ In function sc_alloc(0x%x) ------------\r\n", size); if (size > 0x1000) { uart_printf("Error : sc_alloc(size), size > 0x1000\r\n"); return 0; @@ -61,26 +60,22 @@ void *sc_alloc(int size) { hdr = (sc_hdr *)((char *)page + i); list_add_tail(&hdr->list, &sc_freelists[size_idx]); } - // uart_printf("[+] In small chunk alloc (alloc page idx : %d, cut into chunk size : 0x%x)\r\n", frame_idx, sc_sizes[size_idx]); } // allocate this chunk and remove from free list hdr = (sc_hdr *)sc_freelists[size_idx].next; list_del_entry(&hdr->list); - // uart_printf("[-] Successfully allocate a small chunk, addr : 0x%x, chunk size : 0x%x\r\n", hdr, sc_sizes[size_idx]); return hdr; } int sc_free(void *sc) { - // uart_printf("++++++++++++ In function sc_free ++++++++++++\r\n"); sc_hdr *hdr; int frame_idx = addr_to_idx(sc); int size_idx; // this chunk is not managed by Small Chunk allocator if (!sc_frame_ents[frame_idx].splitted) { - // uart_printf("Error : sc_free()\r\n"); return -1; } @@ -88,7 +83,6 @@ int sc_free(void *sc) { size_idx = sc_frame_ents[frame_idx].size_idx; hdr = (sc_hdr *)sc; list_add(&hdr->list, &sc_freelists[size_idx]); - // uart_printf("[+] Successfully free a chunk (addr : 0x%x, chunk size : 0x%x)\r\n", sc, sc_sizes[size_idx]); return 0; } diff --git a/kernel/mbox.c b/kernel/mbox.c index c1f9baa5e..2730ecbb8 100644 --- a/kernel/mbox.c +++ b/kernel/mbox.c @@ -1,8 +1,6 @@ #include "mbox.h" -volatile unsigned int __attribute__((aligned(16))) mbox[72]; - -unsigned int get_board_revision(unsigned int* board_revision){ +unsigned int get_board_revision(volatile unsigned int mbox[36]){ mbox[0] = 7 * 4; // buffer size in bytes mbox[1] = REQUEST_CODE; // tags begin @@ -13,17 +11,10 @@ unsigned int get_board_revision(unsigned int* board_revision){ // tags end mbox[6] = END_TAG; - if (mailbox_call(MAILBOX_CH_PROP)) { - *board_revision = mbox[5]; - return 0; - } - else { - // uart_printf("Unable to query serial\r\n"); - return -1; - } + return mailbox_call(mbox, MAILBOX_CH_PROP); } -unsigned int get_arm_memory(unsigned int* base_addr,unsigned int* size){ +unsigned int get_arm_memory(volatile unsigned int mbox[36]){ mbox[0] = 8 * 4; // buffer size in bytes mbox[1] = REQUEST_CODE; // tags begin @@ -34,20 +25,12 @@ unsigned int get_arm_memory(unsigned int* base_addr,unsigned int* size){ mbox[6] = 0; // size in bytes // tags end mbox[7] = END_TAG; - - if (mailbox_call(MAILBOX_CH_PROP)) { - *base_addr = mbox[5]; - *size = mbox[6]; - return 0; - } - else { - // uart_printf("Unable to query serial\r\n"); - return -1; - } + + return mailbox_call(mbox, MAILBOX_CH_PROP); } // Make a mailbox call. Returns 0 on failure, non-zero on success -unsigned int mailbox_call(unsigned char ch){ +unsigned int mailbox_call(volatile unsigned int mbox[36], unsigned char ch){ /* Combine the message address (upper 28 bits) with channel number (lower 4 bits) */ unsigned int req = (((unsigned int)((unsigned long)mbox) & (~0xF)) | (ch & 0xF)); /* wait until we can write to the mailbox */ @@ -60,7 +43,7 @@ unsigned int mailbox_call(unsigned char ch){ /* wait the response signal */ do{asm volatile("nop");}while(*MAILBOX_STATUS & MAILBOX_EMPTY); /* read the response to compare our req and request_code */ - if(req == PHYS_TO_VIRT(*MAILBOX_READ)) + if(req == *MAILBOX_READ) return mbox[1] == MAILBOX_RESPONSE; } return 0; diff --git a/kernel/sched.c b/kernel/sched.c index 3a15fae96..d8582a7c3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -21,7 +21,7 @@ void init_thread_sched() { // malloc a space for current kernel thread to prevent crash asm volatile("msr tpidr_el1, %0" :: "r"(kmalloc(sizeof(thread_t)))); - thread_t* idlethread = thread_create(idle, 0x1000); + thread_t* idlethread = thread_create(idle); curr_thread = idlethread; unlock(); } @@ -38,8 +38,8 @@ void schedule() { do { curr_thread = (thread_t *)curr_thread->listhead.next; } while (list_is_head(&curr_thread->listhead, run_queue) || curr_thread->iszombie); - unlock(); switch_to(get_current(), &curr_thread->context); + unlock(); } void kill_zombies() { @@ -48,30 +48,17 @@ void kill_zombies() { list_for_each(curr, run_queue) { if (((thread_t *)curr)->iszombie) { list_del_entry(curr); - kfree(((thread_t *)curr)->kernel_stack_alloced_ptr); - // free tables (VA) - free_page_tables(((thread_t *)curr)->context.ttbr0_el1, 0); - // free alloced area and vma struct - list_head_t *pos = ((thread_t *)curr)->vma_list.next; - while (pos != &((thread_t *)curr)->vma_list) { - if (((vm_area_struct_t *)pos)->is_alloced) - kfree((void*)PHYS_TO_VIRT(((vm_area_struct_t *)pos)->phys_addr)); - list_head_t* next_pos = pos->next; - kfree(pos); - pos = next_pos; - } - // free PGD - kfree(PHYS_TO_VIRT(((thread_t *)curr)->context.ttbr0_el1)); ((thread_t *)curr)->isused = 0; ((thread_t *)curr)->iszombie = 0; // free user stack & kernel stack - // kfree(((thread_t *)curr)->stack_alloced_ptr); + kfree(((thread_t *)curr)->stack_alloced_ptr); + kfree(((thread_t *)curr)->kernel_stack_alloced_ptr); } } unlock(); } -thread_t *thread_create(void *start, unsigned int filesize) { +thread_t *thread_create(void *start) { lock(); thread_t *r; for (int i = 0; i <= PIDMAX; i++) { @@ -81,20 +68,17 @@ thread_t *thread_create(void *start, unsigned int filesize) { } } - INIT_LIST_HEAD(&r->vma_list); r->isused = 1; r->iszombie = 0; - r->signal_is_checking = 0; r->context.lr = (unsigned long long)start; r->stack_alloced_ptr = kmalloc(USTACK_SIZE); r->kernel_stack_alloced_ptr = kmalloc(KSTACK_SIZE); - r->data = kmalloc(filesize); - r->datasize = filesize; - r->context.sp = (unsigned long long )r->kernel_stack_alloced_ptr + KSTACK_SIZE; + r->context.sp = (unsigned long long )r->stack_alloced_ptr + USTACK_SIZE; r->context.fp = r->context.sp; - - r->context.ttbr0_el1 = kmalloc(0x1000); - memset(r->context.ttbr0_el1, 0, 0x1000); + r->signal_is_checking = 0; + memset(r->curr_working_dir, 0, 256); + memcpy(r->curr_working_dir, "/", 1); + // initial signal handler with signal_default_handler (kill thread) for (int i = 0; i < SIGNAL_MAX; i++) { r->singal_handler[i] = signal_default_handler; @@ -114,20 +98,10 @@ void thread_exit() { } int exec_thread(char *data, unsigned int filesize) { - thread_t *t = thread_create(data, filesize); - // device memory - add_vma(t, 0x3C000000L, 0x3000000L, 0x3C000000L, 3, 0); - // user stack - add_vma(t, 0xffffffffb000, 0x4000, (unsigned long)VIRT_TO_PHYS(t->stack_alloced_ptr), 7, 1); - // code - add_vma(t, 0x0, filesize, (unsigned long)VIRT_TO_PHYS(t->data), 7, 1); - // signal wrapper - add_vma(t, USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED, 0x2000, (unsigned long)VIRT_TO_PHYS(signal_handler_wrapper), 5, 0); - - t->context.ttbr0_el1 = VIRT_TO_PHYS(t->context.ttbr0_el1); - t->context.sp = 0xfffffffff000; - t->context.fp = 0xfffffffff000; - t->context.lr = 0L; + thread_t *t = thread_create(data); + t->data = kmalloc(filesize); + t->datasize = filesize; + t->context.lr = (unsigned long)t->data; // copy file into data for (int i = 0; i < filesize; i++) t->data[i] = data[i]; @@ -141,13 +115,8 @@ int exec_thread(char *data, unsigned int filesize) { "msr elr_el1, %1\n\t" "msr sp_el0, %2\n\t" "mov sp, %3\n\t" - "dsb ish\n\t" // ensure write has completed - "msr ttbr0_el1, %4\n\t" - "tlbi vmalle1is\n\t" // invalidate all TLB entries - "dsb ish\n\t" // ensure completion of TLB invalidatation - "isb\n\t" // clear pipeline" "eret\n\t" - :: "r"(&t->context), "r"(t->context.lr), "r"(t->context.sp), "r"(t->kernel_stack_alloced_ptr + KSTACK_SIZE), "r"(t->context.ttbr0_el1) + :: "r"(&t->context), "r"(t->context.lr), "r"(t->context.sp), "r"(t->kernel_stack_alloced_ptr + KSTACK_SIZE) ); return 0; } diff --git a/kernel/shell.c b/kernel/shell.c index 998453ade..b810e6253 100644 --- a/kernel/shell.c +++ b/kernel/shell.c @@ -15,7 +15,7 @@ struct cmd cmd_list[] = { // {"async", cmd_async, "test async print"}, // {"prog", cmd_prog, "load a user program in the initramfs, and jump to it"}, // {"sec2", cmd_sec2, "print the seconds after booting and set the next timeout to 2 seconds later."}, - // {"setTimeout",cmd_setTimeout,"prints message after seconds"}, + {"setTimeout",cmd_setTimeout,"prints message after seconds"}, // {"testfoo", cmd_foo, "test thread"}, // {"preempt", cmd_preempt, "test preemption"}, // {"pageTest", cmd_pageTest, "test page frame allocator"}, @@ -33,7 +33,6 @@ void read_cmd() { while (1) { // read char uart_read(&c, 1); - // c = uart_read_char_async(); // handle buffer switch (c) { case '\r': @@ -110,16 +109,28 @@ void cmd_reboot(char* param) { } void cmd_revision() { - unsigned int board_revision; - get_board_revision(&board_revision); - uart_printf("Board Revision : 0x%x\r\n", board_revision); + volatile unsigned int mbox[36]; + if (get_board_revision(mbox)) { + uart_printf("Board Revision : 0x"); + uart_write_hex(mbox[5]); + uart_printf("\r\n"); + } + else + uart_printf("Failed to get board revision\r\n"); } void cmd_memory() { - unsigned int arm_mem_base, arm_mem_size; - get_arm_memory(&arm_mem_base, &arm_mem_size); - uart_printf("ARM Memory Base Address : 0x%x\r\n", arm_mem_base); - uart_printf("ARM Memory Size : 0x%x\r\n", arm_mem_size); + volatile unsigned int mbox[36]; + if (get_arm_memory(mbox)) { + uart_printf("ARM Memory Base Address : 0x"); + uart_write_hex(mbox[5]); + uart_printf("\r\n"); + uart_printf("ARM Memory Size : 0x"); + uart_write_hex(mbox[6]); + uart_printf("\r\n"); + } + else + uart_printf("Failed to get ARM memory base address and size\r\n"); } void cmd_ls(char* param) { @@ -198,7 +209,7 @@ void foo() { void cmd_foo() { for (int i = 0; i < 3; i++) { - thread_create(foo, 0x1000); + thread_create(foo); } schedule(); } diff --git a/kernel/signal.c b/kernel/signal.c index 9755c99f1..589bbe0e9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -35,23 +35,21 @@ void run_signal(trapframe_t* tpf, int signal) { return; } // run signal handler in user mode - // char *temp_signal_userstack = kmalloc(USTACK_SIZE); + char *temp_signal_userstack = kmalloc(USTACK_SIZE); asm volatile( "msr elr_el1, %0\n\t" "msr sp_el0, %1\n\t" "msr spsr_el1, %2\n\t" - "mov x0, %3\n\t" "eret\n\t" - :: "r"(USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED + ((unsigned long)signal_handler_wrapper % 0x1000)), "r"(tpf->sp_el0), "r"(tpf->spsr_el1), "r"(curr_thread->curr_signal_handler) + :: "r"(signal_handler_wrapper), "r"(temp_signal_userstack + USTACK_SIZE), "r"(tpf->spsr_el1) ); } void signal_handler_wrapper() { // run signal handler - // (curr_thread->curr_signal_handler)(); + (curr_thread->curr_signal_handler)(); // sigreturn asm volatile( - "blr x0\n\t" "mov x8, 31\n\t" "svc 0\n\t" ); diff --git a/kernel/syscall.c b/kernel/syscall.c index 83db612d7..4c69423da 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -26,50 +26,33 @@ unsigned long uartwrite(trapframe_t *tpf, const char buf[], unsigned long size) // syscall no 3 int exec(trapframe_t *tpf, const char *name, char *const argv[]) { - // free alloced area and vma struct - list_head_t *pos = curr_thread->vma_list.next; - while (pos != &curr_thread->vma_list) { - if (((vm_area_struct_t *)pos)->is_alloced) - kfree((void *)PHYS_TO_VIRT(((vm_area_struct_t *)pos)->phys_addr)); - list_head_t *next_pos = pos->next; - kfree(pos); - pos = next_pos; - } + // curr_thread->datasize = get_file_size((char*)name); + // char *new_data = get_file_start((char *)name); + // use VFS + char abs_path[MAX_PATH_NAME]; + memset(abs_path, 0, MAX_PATH_NAME); + memcpy(abs_path, name, strlen(name)); + path_to_absolute(abs_path, curr_thread->curr_working_dir); + + struct vnode *target_file; + vfs_lookup(abs_path, &target_file); + curr_thread->datasize = target_file->f_ops->getsize(target_file); - INIT_LIST_HEAD(&curr_thread->vma_list); - curr_thread->datasize = get_file_size((char*)name); - char *new_data = get_file_start((char *)name); - // re-alloc code & user stack - curr_thread->data = kmalloc(curr_thread->datasize); - curr_thread->stack_alloced_ptr = kmalloc(USTACK_SIZE); - - asm volatile("dsb ish\n\t"); // ensure write has completed - free_page_tables(curr_thread->context.ttbr0_el1, 0); - memset(PHYS_TO_VIRT(curr_thread->context.ttbr0_el1), 0, 0x1000); - asm volatile( - "tlbi vmalle1is\n\t" // invalidate all TLB entries - "dsb ish\n\t" // ensure completion of TLB invalidatation - "isb\n\t" // clear pipeline - ); - - // code - add_vma(curr_thread, 0, curr_thread->datasize, (unsigned long)VIRT_TO_PHYS(curr_thread->data), 7, 1); - // user stack - add_vma(curr_thread, 0xffffffffb000, 0x4000, (unsigned long)VIRT_TO_PHYS(curr_thread->stack_alloced_ptr), 7, 1); - // device memory - add_vma(curr_thread, 0x3C000000L, 0x3000000L, 0x3C000000L, 3, 0); - // signal wrapper - add_vma(curr_thread, USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED, 0x2000, (unsigned long)VIRT_TO_PHYS(signal_handler_wrapper), 5, 0); - // copy file into data - memcpy(curr_thread->data, new_data, curr_thread->datasize); + // copy data + // for (unsigned int i = 0; i < curr_thread->datasize; i++) + // curr_thread->data[i] = new_data[i]; + // use VFS + struct file *tmp_file; + vfs_open(abs_path, 0, &tmp_file); + vfs_read(tmp_file, curr_thread->data, curr_thread->datasize); + vfs_close(tmp_file); // clear signal handler for (int i = 0; i <= SIGNAL_MAX; i++) curr_thread->singal_handler[i] = signal_default_handler; - // set return address, stack pointer and return value - tpf->elr_el1 = 0; - tpf->sp_el0 = 0xfffffffff000; + tpf->elr_el1 = (unsigned long)curr_thread->data; + tpf->sp_el0 = (unsigned long)curr_thread->stack_alloced_ptr + USTACK_SIZE; tpf->x0 = 0; return 0; } @@ -77,48 +60,43 @@ int exec(trapframe_t *tpf, const char *name, char *const argv[]) { // syscall no 4 int fork(trapframe_t *tpf) { lock(); - thread_t *newt = thread_create(curr_thread->data, curr_thread->datasize); + thread_t *newt = thread_create(curr_thread->data); // copy signal handler for (int i = 0; i <= SIGNAL_MAX; i++) newt->singal_handler[i] = curr_thread->singal_handler[i]; - // copy vma - list_head_t *pos; - list_for_each(pos, &curr_thread->vma_list) { - // ignore device memory and signal wrapper - if (((vm_area_struct_t *)pos)->virt_addr == USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED || ((vm_area_struct_t *)pos)->virt_addr == 0x3C000000L) - continue; - // alloc new area for child & copy content - char *new_alloc = kmalloc(((vm_area_struct_t *)pos)->area_size); - add_vma(newt, ((vm_area_struct_t *)pos)->virt_addr, ((vm_area_struct_t *)pos)->area_size, (unsigned long)VIRT_TO_PHYS(new_alloc), ((vm_area_struct_t *)pos)->rwx, 1); - memcpy(new_alloc, (void*)PHYS_TO_VIRT(((vm_area_struct_t *)pos)->phys_addr), ((vm_area_struct_t *)pos)->area_size); - } - // device memory - add_vma(newt, 0x3C000000L, 0x3000000L, 0x3C000000L, 3, 0); - // signal wrapper - add_vma(newt, USER_SIG_WRAPPER_VIRT_ADDR_ALIGNED, 0x2000, (unsigned long)VIRT_TO_PHYS(signal_handler_wrapper), 5, 0); - + newt->datasize = curr_thread->datasize; int parent_pid = curr_thread->pid; + thread_t *parent_thread_t = curr_thread; + + // can not copy data because there are a lot of ret addresses on stack + // copy user stack into new process + for (int i = 0; i < USTACK_SIZE; i++) + newt->stack_alloced_ptr[i] = curr_thread->stack_alloced_ptr[i]; // copy kernel stack into new process for (int i = 0; i < KSTACK_SIZE; i++) newt->kernel_stack_alloced_ptr[i] = curr_thread->kernel_stack_alloced_ptr[i]; store_context(get_current()); - // child if (parent_pid != curr_thread->pid) { + // move trapframe + tpf = (trapframe_t*)((char *)tpf + (unsigned long)newt->kernel_stack_alloced_ptr - (unsigned long)parent_thread_t->kernel_stack_alloced_ptr); + tpf->sp_el0 += newt->stack_alloced_ptr - parent_thread_t->stack_alloced_ptr; tpf->x0 = 0; return 0; } // parent else { - void *temp_ttbr0_el1 = newt->context.ttbr0_el1; newt->context = curr_thread->context; - newt->context.ttbr0_el1 = VIRT_TO_PHYS(temp_ttbr0_el1); + // move fp newt->context.fp += newt->kernel_stack_alloced_ptr - curr_thread->kernel_stack_alloced_ptr; + // move kernel sp newt->context.sp += newt->kernel_stack_alloced_ptr - curr_thread->kernel_stack_alloced_ptr; + unlock(); + tpf->x0 = newt->pid; return newt->pid; } @@ -130,13 +108,20 @@ void exit(trapframe_t *tpf, int status) { } // syscall no 6 -int syscall_mbox_call(trapframe_t *tpf, unsigned char ch, unsigned int *mbox_user) { +int syscall_mbox_call(trapframe_t *tpf, unsigned char ch, unsigned int *mbox) { lock(); - unsigned int size_of_mbox = mbox_user[0]; - memcpy((char *)mbox, mbox_user, size_of_mbox); - mailbox_call(ch); - memcpy(mbox_user, (char *)mbox, size_of_mbox); - tpf->x0 = 8; + unsigned int req = (((unsigned int)((unsigned long)mbox) & (~0xF)) | (ch & 0xF)); + do{asm volatile("nop");}while(*MAILBOX_STATUS & MAILBOX_FULL); + *MAILBOX_WRITE = req; + while (1) { + do{asm volatile("nop");}while(*MAILBOX_STATUS & MAILBOX_EMPTY); + if(req == *MAILBOX_READ) { + tpf->x0 = (mbox[1] == MAILBOX_RESPONSE); + unlock(); + return mbox[1] == MAILBOX_RESPONSE; + } + } + tpf->x0 = 0; unlock(); return 0; } @@ -175,31 +160,110 @@ void signal_kill(int pid, int signal) { // syscall no 31 void sigreturn(trapframe_t *tpf) { + unsigned long signal_ustack; + if (tpf->sp_el0 % USTACK_SIZE == 0) + signal_ustack = tpf->sp_el0 - USTACK_SIZE; + else + signal_ustack = tpf->sp_el0 & (~(USTACK_SIZE - 1)); + kfree((char*)signal_ustack); load_context(&curr_thread->signal_saved_context); } -// syscall no 10 (only implement anonymous page mapping) -void *sys_mmap(trapframe_t *tpf, void *addr, unsigned long len, int prot, int flags, int fd, int file_offset) { - // rounds up - len = len % 0x1000 ? len + (0x1000 - len % 0x1000) : len; - addr = (unsigned long)addr % 0x1000 ? addr + (0x1000 - (unsigned long)addr % 0x1000) : addr; - - // check if overlap - list_head_t *pos; - vm_area_struct_t *the_area_ptr = 0; - list_for_each(pos, &curr_thread->vma_list) { - if ((unsigned long)(addr + len) > ((vm_area_struct_t *)pos)->virt_addr && (unsigned long)addr < ((vm_area_struct_t *)pos)->virt_addr + ((vm_area_struct_t *)pos)->area_size) { - the_area_ptr = (vm_area_struct_t *)pos; - break; +// syscall no 11 +int sys_open(trapframe_t *tpf, const char *pathname, int flags) { + // set pathname to absolutely path + char abs_path[MAX_PATH_NAME]; + memset(abs_path, 0, MAX_PATH_NAME); + memcpy(abs_path, pathname, strlen(pathname)); + path_to_absolute(abs_path, curr_thread->curr_working_dir); + // open + for (int i = 0; i < MAX_FD; i++) { + // find empty fd + if (!curr_thread->file_descriptors_table[i]) { + // vfs_open fail + if (vfs_open(abs_path, flags, &curr_thread->file_descriptors_table[i]) != 0) + break; + // normal case + tpf->x0 = i; + return i; } } - // if overlap => new region's start address at the end of the area - if (the_area_ptr) { - tpf->x0 = (unsigned long)sys_mmap(tpf, (void *)(the_area_ptr->virt_addr + the_area_ptr->area_size), len, prot, flags, fd, file_offset); - return (void *)tpf->x0; + // open fail + tpf->x0 = -1; + return -1; +} + +// syscall no 12 +int sys_close(trapframe_t *tpf, int fd) { + // file exist + if (curr_thread->file_descriptors_table[fd]) { + vfs_close(curr_thread->file_descriptors_table[fd]); + curr_thread->file_descriptors_table[fd] = 0; + tpf->x0 = 0; + return 0; + } + // else close fail + tpf->x0 = -1; + return -1; +} + +// syscall no 13 +long sys_write(trapframe_t *tpf, int fd, const void *buf, unsigned long count) { + // file exist + if (curr_thread->file_descriptors_table[fd]) { + tpf->x0 = vfs_write(curr_thread->file_descriptors_table[fd], buf, count); + return tpf->x0; + } + // else write fail + tpf->x0 = -1; + return tpf->x0; +} + +// syscall no 14 +long sys_read(trapframe_t *tpf, int fd, void *buf, unsigned long count) { + // file exist + if (curr_thread->file_descriptors_table[fd]) { + tpf->x0 = vfs_read(curr_thread->file_descriptors_table[fd], buf, count); + return tpf->x0; } - // else, add vma - add_vma(curr_thread, (unsigned long)addr, len, VIRT_TO_PHYS((unsigned long)kmalloc(len)), prot, 1); - tpf->x0 = (unsigned long)addr; - return (void*)tpf->x0; + // else read fail + tpf->x0 = -1; + return tpf->x0; +} + +// syscall no 15 +int sys_mkdir(trapframe_t *tpf, const char *pathname, unsigned mode) { + // set pathname to absolutely path + char abs_path[MAX_PATH_NAME]; + memset(abs_path, 0, MAX_PATH_NAME); + memcpy(abs_path, pathname, strlen(pathname)); + path_to_absolute(abs_path, curr_thread->curr_working_dir); + // mkdir + tpf->x0 = vfs_mkdir(abs_path); + return tpf->x0; +} + +// syscall no 16 +int sys_mount(trapframe_t *tpf, const char *src, const char *target, const char *filesystem, unsigned long flags, const void *data) { + // set pathname to absolutely path + char abs_path[MAX_PATH_NAME]; + memset(abs_path, 0, MAX_PATH_NAME); + memcpy(abs_path, target, strlen(target)); + path_to_absolute(abs_path, curr_thread->curr_working_dir); + // mount + tpf->x0 = vfs_mount(abs_path, filesystem); + return tpf->x0; +} + +// syscall no 17 +int sys_chdir(trapframe_t *tpf, const char *path) { + // set pathname to absolutely path + char abs_path[MAX_PATH_NAME]; + memset(abs_path, 0, MAX_PATH_NAME); + memcpy(abs_path, path, strlen(path)); + path_to_absolute(abs_path, curr_thread->curr_working_dir); + // modify curr_working_dir + memset(curr_thread->curr_working_dir, 0, 255); + memcpy(curr_thread->curr_working_dir, abs_path, strlen(abs_path)); + return 0; } diff --git a/kernel/tmpfs.c b/kernel/tmpfs.c new file mode 100644 index 000000000..80dc7367c --- /dev/null +++ b/kernel/tmpfs.c @@ -0,0 +1,142 @@ +#include "tmpfs.h" + +struct file_operations tmpfs_file_operations = {tmpfs_write, tmpfs_read, tmpfs_open, tmpfs_close, tmpfs_getsize}; +struct vnode_operations tmpfs_vnode_operations = {tmpfs_lookup, tmpfs_create, tmpfs_mkdir}; + +int register_tmpfs() { + struct filesystem fs; + fs.name = "tmpfs"; + fs.setup_mount = tmpfs_setup_mount; + return register_filesystem(&fs); +} + +int tmpfs_setup_mount(struct filesystem *fs, struct mount *_mount) { + _mount->fs = fs; + _mount->root = tmpfs_create_vnode(0, dir_t); + return 0; +} + +struct vnode* tmpfs_create_vnode(struct mount* _mount, enum node_type type) { + struct vnode *v = kmalloc(sizeof(struct vnode)); + v->f_ops = &tmpfs_file_operations; + v->v_ops = &tmpfs_vnode_operations; + v->mount = 0; + struct tmpfs_inode* inode = kmalloc(sizeof(struct tmpfs_inode)); + memset(inode, 0, sizeof(struct tmpfs_inode)); + inode->type = type; + inode->data = kmalloc(0x1000); + v->internal = inode; + return v; +} + +int tmpfs_write(struct file *file, const void *buf, unsigned long len) { + // copy data into inode & update f_pos + struct tmpfs_inode *inode = file->vnode->internal; + memcpy(inode->data + file->f_pos, buf, len); + file->f_pos += len; + // update datasize + if (inode->datasize < file->f_pos) + inode->datasize = file->f_pos; + return len; +} + +int tmpfs_read(struct file *file, void *buf, unsigned long len) { + struct tmpfs_inode *inode = file->vnode->internal; + // read until EOF + if (file->f_pos + len > inode->datasize) { + len = inode->datasize - file->f_pos; + } + memcpy(buf, inode->data + file->f_pos, len); + file->f_pos += len; + return len; +} + +int tmpfs_open(struct vnode *file_node, struct file **target) { + (*target)->vnode = file_node; + (*target)->f_ops = file_node->f_ops; + (*target)->f_pos = 0; + return 0; +} + +int tmpfs_close(struct file *file) { + kfree(file); + return 0; +} + +int tmpfs_lookup(struct vnode *dir_node, struct vnode **target, const char *component_name) { + struct tmpfs_inode *dir_inode = dir_node->internal; + int child_idx = 0; + // iterate child entry + for (; child_idx < MAX_DIR_ENTRY; child_idx++) { + struct vnode *vnode = dir_inode->entry[child_idx]; + // if there is no such child + if (!vnode) + continue; + // lookup success + struct tmpfs_inode *inode = vnode->internal; + if (strcmp(component_name, inode->name) == 0) { + *target = vnode; + return 0; + } + } + // uart_printf("[WARNING] tmpfs_lookup not found in this level\r\n"); + return -1; +} + +int tmpfs_create(struct vnode *dir_node, struct vnode **target, const char *component_name) { + // check vnode type + struct tmpfs_inode *inode = dir_node->internal; + if (inode->type != dir_t) { + uart_printf("[ERROR] tmpfs_create FAIL, dir_node is not dir_t\r\n"); + return -1; + } + // iterate child + int child_idx = 0; + for (; child_idx < MAX_DIR_ENTRY; child_idx++) { + // if there is an empty entry + if (!inode->entry[child_idx]) + break; + // prevent identical file name + struct tmpfs_inode *child_inode = inode->entry[child_idx]->internal; + if (strcmp(child_inode->name, component_name) == 0) { + uart_printf("[ERROR] tmpfs_create FAIL, file already exist\r\n"); + return -1; + } + } + // assign new vnode to child_idx + struct vnode *tmp_vnode = tmpfs_create_vnode(0, file_t); + inode->entry[child_idx] = tmp_vnode; + // assign name + struct tmpfs_inode *tmp_inode = tmp_vnode->internal; + memcpy(tmp_inode->name, component_name, strlen(component_name)); + *target = tmp_vnode; + return 0; +} + +int tmpfs_mkdir(struct vnode *dir_node, struct vnode **target, const char *component_name) { + // check vnode type + struct tmpfs_inode *inode = dir_node->internal; + if (inode->type != dir_t) { + uart_printf("[ERROR] tmpfs_mkdir FAIL, dir_node is not dir_t\r\n"); + return -1; + } + // find first empty child entry + int child_idx = 0; + for (; child_idx < MAX_DIR_ENTRY; child_idx++) { + if (!inode->entry[child_idx]) + break; + } + // assign new vnode to child_idx + struct vnode* tmp_vnode = tmpfs_create_vnode(0, dir_t); + inode->entry[child_idx] = tmp_vnode; + // assign name + struct tmpfs_inode *tmp_inode = tmp_vnode->internal; + memcpy(tmp_inode->name, component_name, strlen(component_name)); + *target = tmp_vnode; + return 0; +} + +long tmpfs_getsize(struct vnode* vnode) { + struct tmpfs_inode *inode = vnode->internal; + return inode->datasize; +} diff --git a/kernel/vfs.c b/kernel/vfs.c new file mode 100644 index 000000000..01731d73b --- /dev/null +++ b/kernel/vfs.c @@ -0,0 +1,230 @@ +#include "vfs.h" + +int register_filesystem(struct filesystem *fs) { + // find first empty reg_fs entry + for (int i = 0; i < MAX_FS_REG; i++) { + if(!reg_fs[i].name) { + reg_fs[i].name = fs->name; + reg_fs[i].setup_mount = fs->setup_mount; + return i; + } + } + // reg_fs is full + return -1; +} + +struct filesystem* find_filesystem(const char* fs_name) { + // find file system by name + for (int i = 0; i < MAX_FS_REG; i++) { + if (strcmp(reg_fs[i].name, fs_name) == 0) + return ®_fs[i]; + } + return 0; +} + +int vfs_write(struct file *file, const void *buf, unsigned long len) { + // 1. write len byte from buf to the opened file. + // 2. return written size or error code if an error occurs. + return file->f_ops->write(file, buf, len); +} + +int vfs_read(struct file *file, void *buf, unsigned long len) { + // 1. read min(len, readable size) byte to buf from the opened file. + // 2. block if nothing to read for FIFO type + // 3. return read size or error code if an error occurs. + return file->f_ops->read(file, buf, len); +} + +int vfs_open(const char *pathname, int flags, struct file **target) { + // 1. Lookup pathname + // 3. Create a new file if O_CREAT is specified in flags and vnode not found + struct vnode *node; + if (vfs_lookup(pathname, &node) != 0 && (flags & O_CREAT)) { + // find last slash in pathname + int last_slash_idx = 0; + for (int i = 0; i < strlen(pathname); i++) { + if(pathname[i] == '/') + last_slash_idx = i; + } + // find corresponding dirname from pathname + char dirname[MAX_PATH_NAME]; + memcpy(dirname, pathname, strlen(pathname)); + dirname[last_slash_idx] = 0; + // lookup dirname + if (vfs_lookup(dirname, &node) != 0) { + uart_printf("[ERROR] O_CREAT FAIL, no such directory name\r\n"); + return -1; + } + // there is dirname => O_CREAT + node->v_ops->create(node, &node, pathname + last_slash_idx + 1); + // create a new file handle for this vnode + *target = kmalloc(sizeof(struct file)); + node->f_ops->open(node, target); + (*target)->flags = flags; + return 0; + } + // 2. Create a new file handle for this vnode if found. + else { + *target = kmalloc(sizeof(struct file)); + node->f_ops->open(node, target); + (*target)->flags = flags; + return 0; + } + // lookup error code shows if file exist or not or other error occurs + // 4. Return error code if fails + return -1; +} + +int vfs_close(struct file *file) { + // 1. release the file handle + // 2. Return error code if fails + file->f_ops->close(file); + return 0; +} + +int vfs_lookup(const char *pathname, struct vnode **target) { + // root node + if (strlen(pathname) == 0) { + *target = rootfs->root; + return 0; + } + // search from root node + struct vnode *dirnode = rootfs->root; + char component_name[FILE_NAME_MAX+1]; + memset(component_name, 0, FILE_NAME_MAX+1); + int c_idx = 0; + // iterate directory + for (int i = 1; i < strlen(pathname); i++) { + // delimiter + if (pathname[i] == '/') { + // end of component name + component_name[c_idx++] = 0; + // if there is no such dirname, return -1 + if (dirnode->v_ops->lookup(dirnode, &dirnode, component_name) != 0) + return -1; + // redirect to new mounted file system + while (dirnode->mount) { + dirnode = dirnode->mount->root; + } + // reset index + c_idx = 0; + } + // copy pathname + else { + component_name[c_idx++] = pathname[i]; + } + } + // last component + component_name[c_idx++] = 0; + if (dirnode->v_ops->lookup(dirnode, &dirnode, component_name) != 0) + return -1; + // redirect to new mounted file system + while (dirnode->mount) { + dirnode = dirnode->mount->root; + } + + *target = dirnode; + return 0; +} + +int vfs_mkdir(const char *pathname) { + char dirname[MAX_PATH_NAME], newdirname[MAX_PATH_NAME]; + memset(dirname, 0, MAX_PATH_NAME); + memset(newdirname, 0, MAX_PATH_NAME); + // find last slash in pathname + int last_slash_idx = 0; + for (int i = 0; i < strlen(pathname); i++) { + if (pathname[i] == '/') + last_slash_idx = i; + } + // divide into 2 parts + memcpy(dirname, pathname, last_slash_idx); + memcpy(newdirname, pathname + last_slash_idx + 1, strlen(pathname + last_slash_idx + 1)); + + struct vnode *node; + // if there is dirname => mkdir + if (vfs_lookup(dirname, &node) == 0) { + node->v_ops->mkdir(node, &node, newdirname); + return 0; + } + // if there is no such dirname + uart_printf("[ERROR] vfs_mkdir FAIL, no such directory name\r\n"); + return -1; +} + +int vfs_mount(const char *target, const char *filesystem) { + struct vnode *dirnode; + struct filesystem *fs = find_filesystem(filesystem); + // if there is no such file system + if (!fs) { + uart_printf("[ERROR] vfs_mount FAIL, no such file system\r\n"); + return -1; + } + // if there is no such dirname + if (vfs_lookup(target, &dirnode) == -1) { + uart_printf("[ERROR] vfs_mount FAIL, no such directory name\r\n"); + return -1; + } + // mount + else { + dirnode->mount = kmalloc(sizeof(struct mount)); + fs->setup_mount(fs, dirnode->mount); + } + return 0; +} + +void init_rootfs() { + // register tmpfs as rootfs + int idx = register_tmpfs(); + rootfs = kmalloc(sizeof(struct mount)); + reg_fs[idx].setup_mount(®_fs[idx], rootfs); +} + +char* path_to_absolute(char* path, char* curr_working_dir) { + // uart_printf("\r\n[TEST in path2abs] path = %s, curr = %s\r\n\r\n", path, curr_working_dir); + // if path is relative path + if (path[0] != '/') { + char tmp[MAX_PATH_NAME]; + memset(tmp, 0, MAX_PATH_NAME); + memcpy(tmp, curr_working_dir, strlen(curr_working_dir)); + if (strcmp(curr_working_dir, "/") != 0) { + tmp[strlen(tmp)] = '/'; + } + // concatenate curr_working_dir & path + memcpy(tmp + strlen(tmp), path, strlen(path)); + memset(path, 0, strlen(path)); + memcpy(path, tmp, strlen(tmp)); + path[strlen(path)] = 0; + } + + char absolute_path[MAX_PATH_NAME]; + memset(absolute_path, 0, MAX_PATH_NAME); + int idx = 0; + for (int i = 0; i < strlen(path); i++) { + // if there is /.. + if (path[i] == '/' && path[i+1] == '.' && path[i+2] == '.') { + // find previous / + for (int j = idx; j >= 0; j--) { + if(absolute_path[j] == '/') { + absolute_path[j] = 0; + idx = j; + } + } + i += 2; + continue; + } + // ignore /. + if (path[i] == '/' && path[i+1] == '.') { + i++; + continue; + } + // normal case + absolute_path[idx++] = path[i]; + } + // end of absolute_path + absolute_path[idx] = 0; + + memset(path, 0, strlen(path)); + memcpy(path, absolute_path, strlen(absolute_path)); + return path; +} diff --git a/rootfs/vfs1.img b/rootfs/vfs1.img new file mode 100644 index 0000000000000000000000000000000000000000..2c41bd71abb5faca75b99d85fac8cb66d8abc187 GIT binary patch literal 404216 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�$5T3bfUfi!~)t8f40G1mc=YEL3e#o195=B+7?@H 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

9zL@=m*GkFg> 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

sAsSy>wpQsKfiH#t&|}wslIi!%N7MJ|6Wb z#WLRb6YY|=sr`Fh>)n=yGbrzMOYj5bt5bEj`9RhQT4&cdTf#MReCK@Fm5O8_%}q|1 z*Kv}~*%Mu}YqQk8#y(|IN$hLI_&%PEeY?MV-9J9AY4TCs?ZxD=Pj6krIlBJ+=$7Iq zXP7=cc8BqMF!(<~4mr zVwT?g$-KfPJRGi%;SYxPA?;@$#I{$d5#OBf)I<(0d67D9doOz<97z1^!Ye`so`@v^ z<#0Jc5z|M%{1g9|d>{1}CC-4HQ{40$wK?Q{ZpKhPU$yLEyZCg6y&L56YS@awt3bPL6O~okgEA+Q9rJ z@2Z@-8-#>;h11n`FoxV2ngV~eL8M!48I6=H!g%2e%` z7eAgm@q2uiJD(o@>EtEOlR@q{A@%sVk=(~Cv2E3Lwv%$O9zPzFSmHcPKLv~DtJtQN zusyMp&{jeijF(OF#p6R@j{5ET4;%TC<3Hvr<$Fu`X5AJWXJ#sWwf##M(t1?%Qg$Nd zICO%+qlq2Lxw0(&Fa~EC|D9lsJY{Txh#gwjt7)~a{-R@cHtX?v*Ka-?LuxFGy20$Q zbLK!HB1=tH)n}sjd3LN0Ni;`%%lwVsUCOQ*S2AD8^)+Ad$KBmyk*{8M^pNnJ1>95D zx98!!^%?v@)ozhNZ~*z2z|SuAwYOs9p=?UP5C89%9G|72U;6l^kH4b_evPZYqgVg; z?-UFzTqfRU!$LMNtt)E?J}!PH`m$I?WZmcayZ#`HDj-~9`a%3b*(b6Fmdn(nm+r_& zo)6pi3*_8YuMtA6_geXU*v{Is&KcK~Q&f2g!7e_8KZsvfVF@CO2FIw}C+FK1Pt{J- zEe^ftz)ENHr{3`aO|9)4g54P4P{OUC#?+_OACz;hj2(%GD+@MAK5El?T{nlzxOMEi zg%fQyo7A}j-+JNWk=&xlVHg3W6d0xad5Q{ZiJcwr}ACbR?i!&bMgTtp!eJ^q< za-);jYP%X(w|>?~rqAFH5;KBba7K{9rF0X!^^>c>TrI!|^I$*t7X_oO!s~1n#6H%m z(Y$*-Hd@JK=VSPTG+tLeDlzB+QB2#mJ2(d9;sl@fv1Qf&GN#0?@mW{P)HTZ7ceUEX zu9ZH9KPY|%@x`cfTSlwZ>MPlLFsVK6u6xoDk|T8Q_D9U9Jlje8&F|Zm}2s zplM`|R;qPPh#%5DZ%pbmRg(`=$Uger_}#7QzrP=aX6!+pPp@#|yq0S$9;*SIaPsKY zrt}^@SqEP=KKD|udEcHh)%dQkTCFbhD|TtLTC+l+)-`qhWGGpPaF8`blA)Iiotd`q z&7|ksGyKD`n$%Q82Jofo;OaJ5YxYX zdp)~~DZuxC`?UB<`I{mK{93!)K?n0#V9xBoPBmTw>{#Zgoo|j7g96yYE-0lpm+ky@ z8|2{;qZh#~0&q2Bfsenn@r+W(8Jw%GoyHgKfD>~Mg1Y0Uo34>>$>X=%bDEyr8jyjC zzZr~uV>1Zx9Pz#9ccX_vZsu9{-9apvZjrx0b&r-V zpZnOi31>~mGCH$+A(w8=G~}N*952_b#FvMsAMZYQ=Q1^=1b5f&gLs;@!vUpMi+L7o z5dM^m3C4%uBS9Xl2@D4O;=kUdbPrs1z!)XyTyUu&e%JgO>`uO8Rjo4((a(FQOJ1Rp zH3d`Ic4n(!XOFhI;ue3Es6g~9x{)|mFsj`e?qi9*Pu%-QtqXdlTi}DcX8O9hdY$Cc z^oKpcXIFflJys_97)-JXn-IJ&XxY?|6YNOZas)fZ-wB>pihsk`6qd$oc~9MTu%*3B zEc_02^uTJzp$t9x^ln<|)T>iOV=TH{47L!&~@w^RBtQ%%Ty zSmt8(-SbDYPJNZ>Cg|@ySo(&T0>J?V7ao0wtqqmVgLrTC9QXREtm=1rz1o7;%7m-@ z)HC60OAHcY3VDcE8mu1uY5{yOGk+9^#0N|o@k8^m%g4NZyv>+?f~^j~Pq9zd5&Dub zmMKgUGM>qA67KcsBhD>?+sPcvpTlpg9@U?gKi`h0NA3C@EQoe51A8HT6wVuhZL0Cb z`~Dr=E1DPtL@Qz>9uy< ztFPk+F4w7R!hFZvn~rOjWO?GgO4EW{I`^;DL^e@4PoHoMQJLIH$RvTVT{AOzwT9Sf@iDk zT#mrq$_XdfML9JzieNr}|+O)7Dm1TQ$l*ss146z*xD=qKP`F zY=At}me|7SDlBO`!%Xaz4NI)ub6Dek^R)~1v443(aqbInu<*;1zQZ}6?*TWKJ)6|h zk^bS94wL)qb-cVS00qp4%c^$Y*G__=1jCRsrm%xj?-}AC&a*wwPNg3iTdFNGmf&d; zXCPyWSORtPbBR%u_cW~(r#1lPoQc0!`rx^|C3iuy9@Kpn-knf>hQJ8&M4FE{-}r;& zM}2i3#O+DOKgCAcKgl1Y&nj?MkWJNTkh)glFFE@L`_^ziQy9>B8xY$i5XhPTLi`g?sIqzQv!J>-ku?PG-5=I%E{8ZsOJo2|Iq7U7Yy^scH2s>u&R(>hf|Dq?lJA8w2pyH8Z zp6{~HcW?Zjx(H7wxx+MjATGgfzHl{#<9rH#kfvHw8M`W{GiSoIZ!C#bN#KW5YnC>C z*!gcVe90n@N*I^1Xy1hta!8zp;+Z4E);A9hHl7e{(vkf)*VkP2 z^{C!c<5=v5xp;`>{9F9NLjvBA(gXj&Lp59ie)|uxcQr?TNh}yCx}jeavbL(Xd5s$7 zc}%zD{x|u9sztN~o449&#?&eB+gDyo+mwKCSbmEmS0Cp;C4;>95dI)|KaF|sV-nQp zvkrl85u>@3Mk3q0@8A0P_TGDZehhz5**Ud#S+Z$k(%)+U@de^zlMBkQ@uzmkjEKAebS;QTHjW*PA{YI-#IgRGG%ZeN{o1OLLtZ+i>J z6a5qs{-CbG`&DbY?1AB;iaz}I89ib*l3P*M1JRd^AJGw)==0O~gK}mG_a?H}g)?}; z|3VyGc>a`qJ7ZJTd6Yqn4ahkDK>i?Y5BIf#MG=!|y0+wew&)Uou{JSBP%5u?E$r0&PtmXSkh zsomYWoXxdSyE2Oke~|TxwT?y~#GbXd?@xn6ZhGCVX5by-lZyy{P_5?-AB(ZYIrdew zoZGe{{?R(P0lwad@CVr!;2V&9GN^;8*C~Kw3MEHZ426L{g(a4dAZF7k!xge1v1qKMuG%EZ-kprFrm#o#=?p0U^rsUPl zjYDo~MEHa3sg!L9ro*_pyN#xAf|00tmZ?ru_=DlTgFQRCXg2CE@B#dyI%iw6@hBL2 zWcY&z$s^3*;-CF`J_9354#iyd-tTJ7SwZ=*BEcV&^BChv2M2KmU5V|1|8MK#d$G8D z8TrWY2W6jl=$GqLZ4KT(42d$$=gGOO zc#Vk4-x&@5;5T0uT)TsC1`l8#OUcEl;x)ecKl$88^9O$<2TBoN-pBI?e_&mWX?pj>}oANbk%L&r;Seef-kL-_ZlV#?{}^tN-J7at>s@AU>xQn3qT3*E!`1 zu2WVqWvnCkf8Xl~&xx}XoJ4H`K8io6>L=oBp!L4phyOU0*b*AQOp}8IA6=OHN96fr z{-AEr!UOssmQ?Wnz+BqkIhQMqaPy(W9nXbohfZ{;3g%O&~|GT$NkX`>Glk!sVhKV^sKqxUY!m zealh5uAbZb%L7X@4R~QvA1)gFLBR)^M0 zVOhj9Xo*YDg7;!-D$g#wVCJf7RQQ7gQxPjh4Aw!5oi-U_mKylmjgI7RzHi5+2=ND* zcLi6=XlG{%XKYTss9g0*IcG8@-9=wf;14pYn5!~c@to*5-mF9&GV~FvjqV+a)ZW^W z;SZMCOR+~BEu?O6gE?v*hx6H5K8vkcHkFGEf6$^<1afR%`ix37Ti>n_zZ;u92h~D; zd>BN9KdAPI$U*+qqGxv`PASeBF1gvwS0R;&41Z9J172GkS&qH_#of&=;DVB)ojl&T zR&@A-62qF1q;A@+e|au5+xnz+?JTpi9lXg*bohg1SqC-U;yh?RUe98|6PaX*=OS-v zWcY(BUJ1-L;}f^*+4ZZ;U&LOrK4z#t5fT2N??;-%cL&2P*z#o*@O6hm_S{eA-i|`=hx`k+*5Anr`km2>_s|kLqeR0@Stiy-!2SXbdpQy{iPMhlqod@P#$y275 z_9*ZNX)|rbw`&lp#3Q=lwb-}f+#*_3_=9S#fE!HhE_8$cM4b;21YuO}21NVrddJQD z_71;~9WgPm2lzMngQ1->-%1{)cW{H~L;Q>~zPKa79|SXiKd88mB8QAK5_>3J(9g&g zjrxNM>ws4aW}r(B4QacYiworZkUa7c;Sauf2JEX;ZgBb^9rR_t8_rj1Y(;=SC~{b` zCpjohki!L&ko|gsJVs)>Vn3hH9~8eX4P{*QZE_GO-hpa6HAZwxexkUWQK&!2I6@!x z@+^4`#6CC+s<}2UdO(th@CVg?keUqCehhgaGJlDkj25ePWcY)$7h3@1d<5u%SFGvm z<2TP8zW1E?u_94_khM-NdY(NU#uYYI*2a|03jEU`*p1;qMub0zJ&0YvpFgeEnqR3+ zSJV(KcxM#q53(1;K3G4d zqeXjo>NQzQ0CVgrwm~h$sPG3R{+Nxf_MW9fHPsw1`oXdrGor&E1p1(s z^R=(d0(;E(BEP7SYp=5UVAe@xqQf6lxnvTLKE8IlM)p|2B{6TU> zVIztAw!ZWI82*MTHlFHBUEsSrFGqzxD07v>_1z2g^*G(G!@2Xw2LR8uI(1n`BEuh) zd6$?B-@dq$On=LHBRyIsv&&V(DvaBO$nXc@J|c(a28prEv77~^#sNCwX;~}jmiV(G zP=8Ri?VLC8i*k;Vv$*(u;JbV@fAB|gAcFX&Kb}AMBRSss_;~){kK~Xs zg)AS>AN-LV_}g*%em;NjM{=N!Nbm=LAcxp^B>00rkRv+$LB$(9$r>W-9rt^^5Cd0X zK=LF4*DpCfOG&@<@k<|nM-TiOSAR#Z{?Ffu&xahA4zYWjpYU08HYBI8%8x1sDRmaH zSXaWhGVNpegDiG|NzGlgKbP2qFiu?Lp>G7|LjzQ($B`?|Rwd+=>_lR$iyqpo?4>AvB zJb$`G4Y3%w`6j!gsLV_9_927R9E?c)L59;iwuE{PiNx7i-O)h03{6S)5 zSU>6;h5u7K_3#=j1MfuJt8Hqc)}z87WLycxdFae7Adhy<>EDpSga;WbGGAq*!XHEq zsavwGO{d9OJ1f{=AG>HWrkeM{JQ)@KAYA7>^<+yA==RN=-eC+~uVU6#)zRIp6!ylv;WWqNK_M@;aW8ciTIl*uS>ui>a)VX40 z_=9TRtv?)(`hVVy8jO<1GS+-~%|gC<=thP=$O4F+AJ6&gi}H!cA+>{J#Ksu4`{oso z41drf|B7!tE46LP7?+!82e{L$N)CEzNshbG;SW-y$ZoefDa(|-J9l=HX;kJ9Z%`at z%gFEtDR9VsSL%H*!sILkhr67~>K3oSaU;VYq;@;@;cy-#zXA21C@qQv)HXpbOT}A8 zqW+-dAmSYL)Ky%Zij5O_(1X;#6WQc!9s&N~A(IPi@iWLcq9zV!L6L*kc{qhUm)B9? z53-&c+l|in3i}?;m&*Ag_M+sG+$K@r58}T%D9)f51{dvKiW0KaD^zbpgFh(y-KlWA zfY4~SnzvN@sf#5#i3)#E&Vv@5TA6eE$Rhk3YKg0w>kKUXb5Y!0WR6mG<3x@SE0iA#Zw=iDeyg6#d&-yk8T>(P z10D`-XO2~Nekhcb9BQ(XyjTpl2-F|MHum&;I8~`(rRJ*`{$1YV4bg*KZ+(1w{?2#% zDfI{O?cSAHsIetHHMxklQfaZMll(0|Z}^jNEWMwr2h57!4LL~v9)A$tAo^gAD%auD zOLHWeL>53*%a+Ml<}d6-y(hNM9rA9&=W2}+@qd5I-2H!fPcZtgeS=Ij;P>*k-gryM zm*aaF8ni{Y%Tf!El3p&L6R|mwtF7r4&mzJf4D6}>mV>n#{^^%Iq7Up`loJL1Aaa0l zs`w;yAoeY`!fQ-q)Ee!h!XNbP$4ax9oWN&815r5v(wpa1@^ZE%*4?+^OL=}9KV4t) z-|-&)?38c|@jc3C@ZI6p_C256k$=g)5W{%&vEd0wiuE&LzZJIL_nVr*M?z53kx z;ydTN-~z&TI`jsvI`d(_Ul;Qgb)_pi|j-J$Dd)mM6q27i!TIOOfBYdZFk zId01@PsXzFQeze2dqssm7?=lF_O%>fGxJrYOO8I7PkW4~3H-rWRO%1nyQ21dJIG$8^H{!Oov82!$=9xG zKAwA{Cu^w8_Z1$S%T9JRSs8_>@CU&RUf8(y^rU7jbJO6&T$O4*w=bh`dQ_sqAM~kb zfDIH5z10P?82g6UxXs?GYEmEh5f%QRFFOjn6i=o=|((`Cb0WRC4()fz^HKN$D}*^`J$5^w){Ru|5o^6#oMVI=s2Du0*S zCn8Q+#NkrsDRo|t41e&4av+xYrazrO_(M6APo1+>=2Qswjvox~ULaQq))bdl;vSYB zr((KLtQ4xdS~6pwvx!4>>Yw73+__dsozIojWirT~YuUslKFD6q$Kr8PjGt6s zH@VZ8?@`~!f1bBLzr11K`h2%s%Wi6<#)%p$_&dLUeE;Bwa>(b9<NXsd#)} z{+=AF;pL+kdFGcUk07}7Y~fhx<9QLgc-P6Uc)29=*Z3%TpIl3~^R<4DKO5KDz_^}g zor5oj41I31*aumDU5qX7=_oW;F#${Z$yPZh;J7?5Z@}d!2jf*Ck|O#WgBb! zSrMu~h(4^c_(wR0XCzjJdIrTtV64F`bNCj=W6w^(&1*^yKX6CIUt4Wg1MAk$`uK#~ zf?I_gxA6!Zt4rM`e0jG{uzP`z3SRj~H=prr{NhdX?xy0C=COF~t>d?C(s#UO&hc{8 zf-+Y4{_#DV9e?m@d1kdfZ4U&OmH3PA&Q|goAtZJh3KS(SLa}#R^`jDx$H@c$39%IRbXM`Nls6WVh zAvIUHB!6%wdsufC!48fQHSf@c5gGoV@`=ilrzO+Jde+?;V9kP6lPlFv6(YkQl-M!m zS>~zOB6FPvcB~r|yMosa@BL~lD*Qq8Ks;_jOIk~fc`B@9>38R(ur0Q(nZ0gBr2e49 zEHdp*7SArR4^6nJ@FG*DmDb!j%}-@Np0F=EBoGj+$rU^Sw{A0)QKYEuIpz65iV#3POt*XI0Lv5eED92x!~ z)2=%2@km_*;#|3iS7bd=dtd#)I&bluHQ%UZmYi$zZqPb8LHy*{_Z1k+uZ3@6wFfCYQO zzW`o%5iI=jr0?i*29P;W;sj+c9ezLkB=zR#Ok|Mz>x?4j^$73> zsh_CYT&Dj-X6~?0k%jyj^q(4EA76ivrvK=Q2!HTLVnn6>;GfHZUoHy#!9N!Q3y)6y z!5@hd{`}2X6Z|%uk9k|gI(!Cy@c$x26!?QbltZnBeCn+a^?7;zjw$#Q{@@Sg_R%BM@SRQ!glg%%;n@AXiviSn}u@CQ}T9*AxKx@5od-MB%P zh}0isW_@4i-O>`GVrJ}(fl)l$33rU2Fs%h{Cm(*Npz#jz18MmXtA7pY0{SM4a z7(4kzSJbmi<-t+GLJaf~4gO%bAraUgyC5Fm%^xfv%LM-@d`Q3K?WCUKn7iAVw4RN1 z$G3u@H4N;{#x0fV%coz<=$T6AT1oA5gV(vYJKp-U%iVptkA64)XScV@)nENnYSs3v z*`sp_N^#2%@)Oq{j_?KHP)bj3yL_^mNbJ|E#trPUN}C#;M)}4V5`Z?m#KINE+17PS z@dqyQCx5MQbWCFoCQ`ct0_=aKrWL_;Bt5qnW&KcW%4BVlImYe^6|L@tg!790Yb3 zyB6+Ub8MyS_tomviwb{G!>=xTsFTz27*7(1Q6Vp9YniRAr`c3w_=92}`T_pnpqXZF z8nSM%7pZn0yO>cNA8JwI56XO~9}>y^W`=p>EENZ!##Yz77qXGz59*Sui~VgzcZlf9K-ofF1bWcY(J=e{rSDK_n3C6nc#Jn!foBi6T~!XMNut@h3#^N#CdzXkln zn$LMe?cpQAAN*3rA3lEh-SEeKcKyLWl;GPBNU;p9{{=P?kz5dk$ zzk1+T5B%zZ|G(-1d<HP)TF;tEp^*D>Vy54+wbBt1NR!t;lnkBS0;JU z;J^8K{N&_4l$t%`0y!nqH@8{nC08*$v<1xJHz&z2{@^eEAmdPQU~HRP<<6Y9)~ng1 z8lU>HFqT-;4{eD<$PQD3+-p#+$^60RXYgz~r;SZ+V1;M?#)JIDADjjIICtr|?3hO8 zXr)@$#Kq1H-1ElNABAf2QAlZm4c^_V{`>n;XvQ8}GvO6Z33r!kEFP=Dti7`RphmqX zg2ZhHd@wx@O1bjv9^HFXbyy5pytu90uaN`Z z+PktXMVU3*-532HDy9<(iu1srIH8P^3dr=xec6xG`wKKHtIkk=-JG>fuZWc)pg83B zK@h}_z4r;Za7%D2a9q2HWdQ8hDfPAqOng@qC2-`b()L$%OB?wN*n8X(ocGhNa6_CM zYpc{E@c%w+^hMfxT>h|+m1^y&VxF(hyfsT5r8g4dBic3i#&G^%kUk*iCL9s_Qz51M zhbp&E-I)k})dQO8x9v&&G)@PfRcNT|(bCaRQ(K>puG+kQQfGm=Zhttd*1`0zN1x7* z(hW6`SB|AFL+iW5+z`swn%b}<);IXR+x5AdsSm4ze$f23zJaezh4TkXH&S!V|3Him z6w626?)1$j9nTEcs=9GZ(;n>!=Gy`8Lf5-m(mJaPp}k#9B1eXPad|G?6WS@+E{hcX z!xGnTF9vIuNV zZS0TQt+Uq^<7z4sf3NI6_c!~&>h65s-6sCFQM(vQ&6*AuOFNZ0P(N;K+0G;u+8~{IE=yQ1t*obq`SEjAE7TAh0|dKZP&YC zHKVc9iiN`<3b*}etcsCv=s!ZM|G>S(J+z=fdgwmFk)qTW^Hdjc-41c-V2MFWzUhmC z3|o!)ASG1ZnErcNJ^S0oUF?eNgW2!K+Iz_~Y`qd3+sxneG8y_Oj?nGhg@N)2xARZ4 zD+S|a$2X@fR)u8?nzjw6@tN5>`$&6Z$+&+P`n=xK3S(b8hw|_%XY02|)VCdoAA-+d$0@B-VY%h}K}4e2p!*-X4`K}{>r>Et$y(jO z1M`E!lH&i0-Pienr~jzDWBX#C@HoS(tlhHoCZ`$Z-C zgZxe@-oyc`AA-C~*?v@e}sufo0)d1CDn=MOTx54w>IbHaEGjmZF$nuF5= z{O?;W6w*2aZh+ScjqpLt6(&qzN4VmU=_aZ(@d^FJ*uED5hO4)2by}yK(O3f0Bf%Ib z@f?X$@-8gToIePi%PIV_CJc*xW3aSzkq-%)dEYTwdhXXs_#x#7Ib#^FMm~U;XYaz_ zhOI-d4!VKhb4XEt*IiBRqHfe`@X`iW{)1M;8b;0^>>(dxigA%YaEwcY*`flMWgdSw z@GvO8|E%`l~6f9cd}bLO%Qh>b!JLB=yme^iO+yf+Tcl8+yvh<-!GgsJkF7m zANV=en{~sep;=?sBF-PQ9yzrB(C$FrmFc+RxTp3D-irUMqWvN++$j#W=cLgqp?{UB zrJAaz)m?l@ z8}HWnB)> zkJ0!XD-ie_j_nj!;FF%CIwYJB*x=CoOoqS-*%IqwxOXv}5O;%Y(=a9tc7Ka89HxCp z_eQu`qK7*AghOF7bXI|Nh?4`ham|3A0Tlxsc+MYWcpk=;6W|u9z1mrFy}4SA?6Y1! zpR~r_-3HlZ-)IKMo1YyTll%U*c^n#cvQs93(davRqjMelzV5A#H#R0sL)B%P7hV`) z*c!?ZX_3i-&&HA8<2p3<_8xzGFIiH4|3Gi#{K0>X|KRVlfjy8@&L8~O_z(V-d~p8Y zu!s5DxMpLx496yEe9rH8&6wYd(^6YrFT0DgnZ>E(q3=X?lfY|9L)a@*G=^vgfpY>& zCEv*-M2A_-sf~JLGJhoruYEXw@DGB;cjXb_5#SNv5%~9ufX{w1=MQrJAaSFBE%eB5 z3wQwIO%BTeylogSas@u0qyi_93U@YhSC@Jx@Lw8mnAeNj_6GcLew+Y=HFN(##1nXz z2JB0MuO4s~mvA-c{b}$EBCW%}!JG+q{!ueYQS#zADvIMAeuq17A2BATtl$F(E@e*z zCZw0DJ3{W@;kSY>)XW$Odlh=S7%O38DX)|uAKZU%dFiU#QrcOJCp>t7Gccp$9x>Mt zNAf;;@dUq?#2w`PK^(tg;jprbUY`sZH5#W36Uu$)+( zRTJ^{poe_TixjbM?{O||zhP@S%XulRtz@^}w7TFy_9pJdvK!Pk0>i5t+pLtAyC ze4wonub8W|&NNZYoN}E=;{|cJvq3pcRd19H(n+q#%Ulu{nI_DL*PT08@VMve+|$9y zpC7ZLJ%765{3(gEr;{p$CT`$?=$xKCSsL%tCbX=Nor4yNu5di7I_B!qbqeX={)60q zkn;zb$2l(F;5k-40Nj5N+$FMrjDWKcj|rd)C~~K#wA%)sVLTpyV|Q;qgrsv1gZ|w- z^d9D2dW?y0r-El^;q`!R-@|P$G(V)()EWc3LBZvnJ`McGT&C@chX?P&5$oF;m=nr$ z!8^E63}5r#sjVUo!tV?BALRT&;@|-@1O*QTyvscj(c`w!B+&4zdm)NiQf zgfOfXQ-(<^iFhpR-WU7fKB!^9GuLN3Ef7JM1TJ-Gj1buFVjF-{%jrQ+f-t{vr&&BZ597<`YxWhH(D%k{TJaR0&TIQ>;4 zhWc*w9BWh1F8yemSX|jTK<7bKU$F;A-dLcoL1T7w5>dQa9%vi;()1Fl>?<3$F+9U6po%(|6?vzY+Q9gZFJU27X-Nn8$TJ0Cp^*&bB zW1Op}<;QkAKa4QXbk{_jDX6&gzwU|NM6fvD`%K`LL2_r04 zq(Mn~ssFgpuEznO?QO{OrEg7B02_Z&D|UantOTfa#>s#^63Px zwAjBuDi<07mm~<#r=+eW_a7vDTwb3`Z4Dn-;c~R3?rc&^{dpk-^JU@#>-NqcnYXB? zUzN7wZq6#!gOk?N@7wkM{QSsq%pwPHL^#<7uL%{Y;X_g(gpd6%t;!&ZPD#Ercbj zPPrhyZ#sx(@gSN2FGQas#N4OSN^(5!M6=Wt=Begs&tg0Z``X1?7GovMyVSUxms9g5 zZZoSB9EIT-H_o`5T`1Cv+QM z_1pF)i0|!TO^Do+8GCIzlhPn7q5yomTdKEjv6HHZHTg@BFCyLFk_M-Uu{w_vjwhDK*MHl04SJ3F-W!>zo&Z-)dk zX8JX$QlKLhq_^l{dffF%K6PL5e;?;a%lG{J=Io#`3GP35i;LSWZ-%DY3(SwEA5K3! zVbrjdEVa#HdD+FW*=UA(I|*@au=9bq!R$P#&Xo#R!x=OC*e>e+3m19?|0_qoO$Lo| zbN|6OFAYT3$@I1dtde-%Xop_QN}jfAlMs8XpuGwy{^%Mo5FJkuFS07v-p&3g?7!kN zKfTB|cm#L^cm#L^cm)1p1gbG>&L8CbLCzoi!f$>Il5qb)?mx)+gBRisbN*od05-3v z_iUOf<8#D#O%go9IDe4)4|4wCCfhtGpW@*$ZU#+oUdaPgUq0$H;0|rhALRanoIlvV zWNu?-w(reL^4P$?Qh4NY3+D;A$(%pP{Re>y(me>K>jMJ;K1)7dwE=m!)R|@j&A+7i z%HU#D9u+hXQ$l4tfPK!o0NkacuE@Q4}SL`tvALdieAN+DbWhfoVv+>bibw*$~e{~-4t1TM_^gTI_E+<)+wfbdNo0UiM!0Um+>UlE}BiZqT{d+EAk zyKd0j5E?oqPYNsyY`*kx>;4b`CDVhijhp+6F<*AI)}f=ey1nJJnHVjnzn>?w!=gLi zMO$g#PG(fi=ssoZ=lbH%>8=jv(dO7$YUfU39OK}yJp~J;Y0TL7vG1lY#%~~OHii`zH3=p|MQU6l%02d>((HZyy$iWhid*bkM-q zZ%-*We~|MB{T~O@dyVr4Ie(Dz2RVNb`n}L@=KR5Qkd9eZ%Sl?aXBn)^X!%w1be6kw zHOk5cbRc(y1dlnbgx;V>T9D2*mYSR6VfD<*QIItrqj0aM{YNi%b}L!fU|b8AX@joS zLtMX!H&JVxI`=)W?NvEgLECqxM;oOvKh)sAc$}trZ#ELneo_dl#0iHDpLE%3wMZ4( zz;C(#pj+DTTnxZZa!a?o6w+x|c_^;o(HCh(`@=@RsJ*uub?jrMT6?OP=j$_X%~D6{ zjfD7!ctZaco(JeVnWtn0?PU1ewnSj%cz-RkR;^iUd*=MXllp0#4nC{%t*1vzM?Xz% zeLlKsbIu>+{6Wqilm$B)3Rw!f!%Pn2rwpH7X?(s*WBbARgSg+Ndl1eagx)SlkW?W3 z3GuyWt~2r)o;VdlbCW`s6@fzkfW`$3X!TRvP|;st^}Q_&?S6O1`GYJrKH2!ua0qp; z`lPiDUml`xU=6j3DfPdgaqHKZx7fcue-QsybK6m#+R1{pER$>eS~6K#a7nS;&7Jrd z)@xBX9meoXybD${3hy20p^Dg+qOmGQ!l54t&fp$eBCDo@=cZ$&zL=+;3?cK%H?jH> z$eQaoT=AXI6!w4e?s{Xj?CH_sS=6Y;)3ig}x;_ z0qN9xmFZobGp{&mq^QvU@Sdaa+kXN(;Q#m>2t(43rPvhuiTo_9!t!y2-eyQ4Ox1Yw z#2fG?@OXV1kEHgIdDhTL--5KJHT$sUdi+rwlgH|^dR}hVB8@#6?FSWnApH+aGxfw` zMBan+$|2F__`vG-vz0%45F56Yc_R48KNpr4d@a5V`mCgt3of@_mJjGjCyr;vPPD&k z@;-G#2b$AfQJxTQYUnT1XVK2Ns53k_=3bUW|Maf_5m+~L4 Y@}IBef4!gR{Wn|tpKi7M-`Dd00N}u82><{9 literal 0 HcmV?d00001