Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions lab5/src/lib/kernel/exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
}
Expand Down
12 changes: 7 additions & 5 deletions lab5/src/lib/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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"(&current->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.
}
1 change: 1 addition & 0 deletions lab5/src/lib/kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions lab6/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vscode
build/
img/
57 changes: 57 additions & 0 deletions lab6/Makefile
Original file line number Diff line number Diff line change
@@ -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
Binary file added lab6/bcm2710-rpi-3-b-plus.dtb
Binary file not shown.
Binary file added lab6/bootloader/bcm2710-rpi-3-b-plus.dtb
Binary file not shown.
Binary file added lab6/bootloader/bootloader.img
Binary file not shown.
3 changes: 3 additions & 0 deletions lab6/bootloader/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kernel=bootloader.img
arm_64bit=1
initramfs initramfs.cpio 0x8000000
6 changes: 6 additions & 0 deletions lab6/bootloader/include/bcm2837/rpi_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _RPI_BASE_H_
#define _RPI_BASE_H_

#define PERIPHERAL_BASE 0x3F000000

#endif /*_RPI_BASE_H_ */
25 changes: 25 additions & 0 deletions lab6/bootloader/include/bcm2837/rpi_gpio.h
Original file line number Diff line number Diff line change
@@ -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_*/
19 changes: 19 additions & 0 deletions lab6/bootloader/include/bcm2837/rpi_uart1.h
Original file line number Diff line number Diff line change
@@ -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_ */
8 changes: 8 additions & 0 deletions lab6/bootloader/include/power.h
Original file line number Diff line number Diff line change
@@ -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_*/
23 changes: 23 additions & 0 deletions lab6/bootloader/include/shell.h
Original file line number Diff line number Diff line change
@@ -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_ */
11 changes: 11 additions & 0 deletions lab6/bootloader/include/uart1.h
Original file line number Diff line number Diff line change
@@ -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_*/
11 changes: 11 additions & 0 deletions lab6/bootloader/include/utils.h
Original file line number Diff line number Diff line change
@@ -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_ */
42 changes: 42 additions & 0 deletions lab6/bootloader/makefile
Original file line number Diff line number Diff line change
@@ -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

52 changes: 52 additions & 0 deletions lab6/bootloader/src/boot.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* ARMv8 Assembly Instruction */
/**

mov x0, x1
sets: x0 = x1
ldr x0, <addr>
load 32bits from <addr> to x0
ldr w0, <addr>
load 64bits from <addr> to w0
cbz x0, <label>
if x0 == 0, jump to <label>
cbnz x0, <label>
if x0 != 0, jump to <label>
str x0 [x1] #8
store x0 in addr<x1> then x1=x1+8
b <label>
jump to <label>
bl <label>
jump to <label> and copies bl's next instruction into link register
wfe
Wait for event, core in low-power state (power on, clk off)

**/

// x0 is used for dtb physical address
.section ".text.boot"

.global _start

_start:
setup_stack:
ldr x1, =_stack_top
mov sp, x1

setup_bss:
ldr x1, =_bss_top
ldr w2, =_bss_size

init_bss:
cbz w2, run_main
str xzr, [x1], #8
sub w2, w2, #1
cbnz w2, init_bss

run_main:
ldr x1, =_dtb
str x0, [x1], #8
bl main

proc_hang:
wfe
b proc_hang
30 changes: 30 additions & 0 deletions lab6/bootloader/src/link.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
_heap_stack_size = 1M;
# heap_size 0x100000

SECTIONS
{
. = 0x80000;
_start = .;
.text : { *(.text.boot) *(.text) }
.rodata : { *(.rodata) }
.data : { *(.data) }
.bss : {
_bss_top = .;
*(.bss)
}
_bss_size = SIZEOF(.bss) >> 3;
.heap : {
. = ALIGN(8);
_heap_top = .;
}
. = . + _heap_stack_size;
.stack : {
. = ALIGN(8);
_stack_top = .;
}
_end = .;

. = 0x3000000;
_bootloader_relocated_addr = 0x3000000;
}
__code_size = (_end - _start);
Loading