diff --git a/lab5/src/lib/kernel/exception.c b/lab5/src/lib/kernel/exception.c index 928ba84b9..3e5e6ad90 100644 --- a/lab5/src/lib/kernel/exception.c +++ b/lab5/src/lib/kernel/exception.c @@ -82,6 +82,7 @@ void irq_handler_c(trapframe_t *tf) schedule(); } + // only do signal handler when return to user mode (0b0000) if ((tf->spsr_el1 & 0b1100) == 0) { check_signal(tf); } @@ -147,15 +148,12 @@ void el0_sync_router(trapframe_t *tf) kill(tf, (int)tf->regs[0]); break; case 8: - // uart_printf("syscall_no: %d\n", syscall_no); signal_register(tf->regs[0], (void (*)())tf->regs[1]); break; case 9: - // uart_printf("syscall_no: %d\n", syscall_no); signal_kill(tf->regs[0], tf->regs[1]); break; case 50: - // uart_printf("syscall_no: %d\n", syscall_no); signal_return(tf); break; default: @@ -188,6 +186,7 @@ void el0_irq_router(trapframe_t *tf) schedule(); } + // only do signal handler when return to user mode (0b0000) if ((tf->spsr_el1 & 0b1100) == 0) { check_signal(tf); } diff --git a/lab5/src/lib/kernel/sched.c b/lab5/src/lib/kernel/sched.c index 68f8f4039..9c53b4f86 100644 --- a/lab5/src/lib/kernel/sched.c +++ b/lab5/src/lib/kernel/sched.c @@ -69,7 +69,7 @@ thread_t *thread_create(void *start, int priority) r->used = 1; r->ustack_ptr = (char *)kmalloc(USTACK_SIZE); r->kstack_ptr = (char *)kmalloc(KSTACK_SIZE); - r->cpu_context.lr = (unsigned long)start; + r->cpu_context.lr = (unsigned long)start; // current thread's return address r->cpu_context.sp = (unsigned long)(r->ustack_ptr + USTACK_SIZE); r->cpu_context.fp = (unsigned long)(r->ustack_ptr + USTACK_SIZE); @@ -190,11 +190,13 @@ int exec_thread(char *data, unsigned int datasize) void run_user_process() { - asm("msr tpidr_el1, %0\n\t" - "msr elr_el1, %1\n\t" - "msr spsr_el1, xzr\n\t" + asm("msr tpidr_el1, %0\n\t" // Hold the "kernel(el1)" thread structure information + "msr elr_el1, %1\n\t" // When el0 -> el1, store return address for el1 -> el0 + "msr spsr_el1, xzr\n\t" // Enable interrupt in EL0 -> Used for thread scheduler "msr sp_el0, %2\n\t" "mov sp, %3\n\t" "eret\n\t" ::"r"(¤t->cpu_context), - "r"((unsigned long)current->data), "r"(current->cpu_context.sp), "r"(current->kstack_ptr + KSTACK_SIZE)); + "r"((unsigned long)current->data), "r"(current->cpu_context.sp), + "r"(current->kstack_ptr + KSTACK_SIZE)); // sp is reference for the same el process. For example, el2 cannot use + // sp_el2, it has to use sp to find its own stack. } \ No newline at end of file diff --git a/lab5/src/lib/kernel/syscall.c b/lab5/src/lib/kernel/syscall.c index a67580dc4..2f1a2527f 100644 --- a/lab5/src/lib/kernel/syscall.c +++ b/lab5/src/lib/kernel/syscall.c @@ -161,6 +161,7 @@ void signal_return(trapframe_t *tf) { unsigned long signal_ustack; // to get the start address of the user stack if (tf->sp_el0 % USTACK_SIZE != 0) { + // if the stack uses stack, return to the start of the stack signal_ustack = tf->sp_el0 - (tf->sp_el0 % USTACK_SIZE); } else { diff --git a/lab6/.gitignore b/lab6/.gitignore new file mode 100644 index 000000000..d558147b0 --- /dev/null +++ b/lab6/.gitignore @@ -0,0 +1,3 @@ +.vscode +build/ +img/ \ No newline at end of file diff --git a/lab6/Makefile b/lab6/Makefile new file mode 100644 index 000000000..b64a14140 --- /dev/null +++ b/lab6/Makefile @@ -0,0 +1,57 @@ +CC = aarch64-linux-gnu +CFLAGS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude -mgeneral-regs-only + +SRC_DIR = src +INCLUDE_DIR = include +KERNEL_DIR = kernel +LIB_DIR = lib +BOOT_DIR = bootloader +BUILD_DIR = build +IMG_DIR = img + +OBJECTS = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)) +OBJECTS += $(patsubst $(SRC_DIR)/%.S, $(BUILD_DIR)/%_s.o, $(wildcard $(SRC_DIR)/*.S)) + +HEADERS = $(wildcard $(INCLUDE_DIR)/*.h) + +ELF_NAME = kernel8.elf +IMG_NAME = kernel8.img +BOOT_ELF_NAME = bootloader.elf +BOOT_IMG_NAME = bootloader.img +CPIO_FILE = initramfs.cpio + +all: clean $(OBJECTS) $(HEADERS) + $(CC)-ld -T $(SRC_DIR)/linker.ld -o $(BUILD_DIR)/$(ELF_NAME) $(OBJECTS) + $(CC)-objcopy -O binary $(BUILD_DIR)/$(ELF_NAME) $(IMG_DIR)/$(IMG_NAME) + +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c + @mkdir -p $(BUILD_DIR) + @mkdir -p $(IMG_DIR) + $(CC)-gcc $(CFLAGS) -c $< -o $@ + +$(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S + $(CC)-gcc $(CFLAGS) -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) $(IMG_DIR) + +dump: + qemu-system-aarch64 -M raspi3b -kernel $(IMG_DIR)/$(IMG_NAME) -initrd $(CPIO_FILE) -display none -d in_asm -dtb bcm2710-rpi-3-b-plus.dtb + +run: all + qemu-system-aarch64 -M raspi3b -kernel $(IMG_DIR)/$(IMG_NAME) -initrd $(CPIO_FILE) -display none -serial null -serial stdio -s -dtb bcm2710-rpi-3-b-plus.dtb + +tty: + qemu-system-aarch64 -M raspi3b -kernel $(IMG_DIR)/$(BOOT_IMG_NAME) -initrd $(CPIO_FILE) -display none -serial null -serial pty + +upload: + sudo python3 upload.py + +cpio: + cd rootfs && find . | cpio -o -H newc > ../$(CPIO_FILE) + +screen: + sudo screen /dev/ttyUSB0 115200 + +userprog: + cd user_program && make clean && make diff --git a/lab6/bcm2710-rpi-3-b-plus.dtb b/lab6/bcm2710-rpi-3-b-plus.dtb new file mode 100644 index 000000000..38395a23f Binary files /dev/null and b/lab6/bcm2710-rpi-3-b-plus.dtb differ diff --git a/lab6/bootloader/bcm2710-rpi-3-b-plus.dtb b/lab6/bootloader/bcm2710-rpi-3-b-plus.dtb new file mode 100644 index 000000000..38395a23f Binary files /dev/null and b/lab6/bootloader/bcm2710-rpi-3-b-plus.dtb differ diff --git a/lab6/bootloader/bootloader.img b/lab6/bootloader/bootloader.img new file mode 100755 index 000000000..714047f83 Binary files /dev/null and b/lab6/bootloader/bootloader.img differ diff --git a/lab6/bootloader/config.txt b/lab6/bootloader/config.txt new file mode 100644 index 000000000..15654a481 --- /dev/null +++ b/lab6/bootloader/config.txt @@ -0,0 +1,3 @@ +kernel=bootloader.img +arm_64bit=1 +initramfs initramfs.cpio 0x8000000 diff --git a/lab6/bootloader/include/bcm2837/rpi_base.h b/lab6/bootloader/include/bcm2837/rpi_base.h new file mode 100644 index 000000000..e3259e8de --- /dev/null +++ b/lab6/bootloader/include/bcm2837/rpi_base.h @@ -0,0 +1,6 @@ +#ifndef _RPI_BASE_H_ +#define _RPI_BASE_H_ + +#define PERIPHERAL_BASE 0x3F000000 + +#endif /*_RPI_BASE_H_ */ diff --git a/lab6/bootloader/include/bcm2837/rpi_gpio.h b/lab6/bootloader/include/bcm2837/rpi_gpio.h new file mode 100644 index 000000000..e5133708a --- /dev/null +++ b/lab6/bootloader/include/bcm2837/rpi_gpio.h @@ -0,0 +1,25 @@ +#ifndef _RPI_GPIO_H_ +#define _RPI_GPIO_H_ + +#include "bcm2837/rpi_base.h" + +#define GPFSEL0 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200000)) +#define GPFSEL1 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200004)) +#define GPFSEL2 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200008)) +#define GPFSEL3 ((volatile unsigned int*)(PERIPHERAL_BASE+0x0020000C)) +#define GPFSEL4 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200010)) +#define GPFSEL5 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200014)) +#define GPSET0 ((volatile unsigned int*)(PERIPHERAL_BASE+0x0020001C)) +#define GPSET1 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200020)) +#define GPCLR0 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200028)) +#define GPLEV0 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200034)) +#define GPLEV1 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200038)) +#define GPEDS0 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200040)) +#define GPEDS1 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200044)) +#define GPHEN0 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200064)) +#define GPHEN1 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200068)) +#define GPPUD ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200094)) +#define GPPUDCLK0 ((volatile unsigned int*)(PERIPHERAL_BASE+0x00200098)) +#define GPPUDCLK1 ((volatile unsigned int*)(PERIPHERAL_BASE+0x0020009C)) + +#endif /*_RPI_GPIO_H_*/ diff --git a/lab6/bootloader/include/bcm2837/rpi_uart1.h b/lab6/bootloader/include/bcm2837/rpi_uart1.h new file mode 100644 index 000000000..959130656 --- /dev/null +++ b/lab6/bootloader/include/bcm2837/rpi_uart1.h @@ -0,0 +1,19 @@ +#ifndef _RPI_UART1_H_ +#define _RPI_UART1_H_ + +#include "bcm2837/rpi_base.h" + +#define AUX_ENABLES ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215004)) +#define AUX_MU_IO_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215040)) +#define AUX_MU_IER_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215044)) +#define AUX_MU_IIR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215048)) +#define AUX_MU_LCR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x0021504C)) +#define AUX_MU_MCR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215050)) +#define AUX_MU_LSR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215054)) +#define AUX_MU_MSR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215058)) +#define AUX_MU_SCRATCH ((volatile unsigned int*)(PERIPHERAL_BASE+0x0021505C)) +#define AUX_MU_CNTL_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215060)) +#define AUX_MU_STAT_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215064)) +#define AUX_MU_BAUD_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215068)) + +#endif /*_RPI_UART1_H_ */ diff --git a/lab6/bootloader/include/power.h b/lab6/bootloader/include/power.h new file mode 100644 index 000000000..baf990974 --- /dev/null +++ b/lab6/bootloader/include/power.h @@ -0,0 +1,8 @@ +#ifndef _POWER_H_ +#define _POWER_H_ + +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC 0x3F10001c +#define PM_WDOG 0x3F100024 + +#endif /*_POWER_H_*/ diff --git a/lab6/bootloader/include/shell.h b/lab6/bootloader/include/shell.h new file mode 100644 index 000000000..702f5eb14 --- /dev/null +++ b/lab6/bootloader/include/shell.h @@ -0,0 +1,23 @@ +#ifndef _SHELL_H_ +#define _SHELL_H_ + +#define CLI_MAX_CMD 3 +#define CMD_MAX_LEN 32 +#define MSG_MAX_LEN 128 + +typedef struct CLI_CMDS +{ + char command[CMD_MAX_LEN]; + char help[MSG_MAX_LEN]; +} CLI_CMDS; + +void cli_cmd_clear(char*, int); +void cli_cmd_read(char*); +void cli_cmd_exec(char*); +void cli_print_banner(); + +void do_cmd_help(); +void do_cmd_loadimg(); +void do_cmd_reboot(); + +#endif /* _SHELL_H_ */ diff --git a/lab6/bootloader/include/uart1.h b/lab6/bootloader/include/uart1.h new file mode 100644 index 000000000..329d25c81 --- /dev/null +++ b/lab6/bootloader/include/uart1.h @@ -0,0 +1,11 @@ +#ifndef _UART1_H_ +#define _UART1_H_ + +void uart_init(); +char uart_getc(); +char uart_recv(); +void uart_send(unsigned int c); +int uart_puts(char* fmt, ...); +void uart_2hex(unsigned int d); + +#endif /*_UART1_H_*/ diff --git a/lab6/bootloader/include/utils.h b/lab6/bootloader/include/utils.h new file mode 100644 index 000000000..e65ece675 --- /dev/null +++ b/lab6/bootloader/include/utils.h @@ -0,0 +1,11 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#define VSPRINT_MAX_BUF_SIZE 128 + +unsigned int sprintf(char *dst, char* fmt, ...); +unsigned int vsprintf(char *dst,char* fmt, __builtin_va_list args); + +int strcmp(const char*, const char*); + +#endif /* _UTILS_H_ */ diff --git a/lab6/bootloader/makefile b/lab6/bootloader/makefile new file mode 100644 index 000000000..b81bad692 --- /dev/null +++ b/lab6/bootloader/makefile @@ -0,0 +1,42 @@ +ARMGNU ?= aarch64-linux-gnu + +CFLAGS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude -mgeneral-regs-only +ASMFLAGS = -Iinclude + +BUILD_DIR = build +SRC_DIR = src +#--------------------------------------------------------------------------------------- + +C_FILES = $(wildcard $(SRC_DIR)/*.c) +ASM_FILES = $(wildcard $(SRC_DIR)/*.S) +OBJ_FILES = $(C_FILES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%_c.o) +OBJ_FILES += $(ASM_FILES:$(SRC_DIR)/%.S=$(BUILD_DIR)/%_s.o) + +DEP_FILES = $(OBJ_FILES:%.o=%.d) +-include $(DEP_FILES) + +$(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c + @mkdir -p $(@D) + $(ARMGNU)-gcc $(CFLAGS) -MMD -c $< -o $@ + +$(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S + $(ARMGNU)-gcc $(ASMFLAGS) -MMD -c $< -o $@ + +bootloader.img: $(SRC_DIR)/link.ld $(OBJ_FILES) + $(ARMGNU)-ld -T $(SRC_DIR)/link.ld -o $(BUILD_DIR)/bootloader.elf $(OBJ_FILES) + $(ARMGNU)-objcopy $(BUILD_DIR)/bootloader.elf -O binary bootloader.img + +all: bootloader.img + +clean: + rm -rf $(BUILD_DIR) *.img + +run_std: + qemu-system-aarch64 -M raspi3b -kernel bootloader.img -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb + +run_pty: + qemu-system-aarch64 -M raspi3b -kernel bootloader.img -serial null -serial pty -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb + +debug: + qemu-system-aarch64 -M raspi3b -kernel bootloader.img -display none -S -s + diff --git a/lab6/bootloader/src/boot.S b/lab6/bootloader/src/boot.S new file mode 100644 index 000000000..c872f56a7 --- /dev/null +++ b/lab6/bootloader/src/boot.S @@ -0,0 +1,52 @@ +/* ARMv8 Assembly Instruction */ +/** + +mov x0, x1 + sets: x0 = x1 +ldr x0, + load 32bits from to x0 +ldr w0, + load 64bits from to w0 +cbz x0,