forked from oscapstone/osc2023
-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
39 changed files
with
1,819 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,4 +39,4 @@ int main() { | |
"ret;"); | ||
|
||
return 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.vscode | ||
build | ||
rootfs | ||
temp | ||
*.img | ||
*.dtb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
ARMGNU ?= aarch64-linux-gnu | ||
|
||
CFLAGS = -Iinclude -nostdlib -nostartfiles -ffreestanding -mgeneral-regs-only -Wall -g | ||
ASMFLAGS = -Iinclude | ||
QEMUFLAGS = -M raspi3b -display none -serial null -serial stdio | ||
|
||
SRC_DIR = src | ||
BUILD_DIR = build | ||
|
||
all: clean kernel8.img | ||
|
||
clean: | ||
rm -rf $(BUILD_DIR) *.img | ||
|
||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | ||
mkdir -p $(@D) | ||
$(ARMGNU)-gcc $(CFLAGS) -c $< -o $@ | ||
|
||
$(BUILD_DIR)/_%.o: %.S | ||
$(ARMGNU)-gcc $(ASMFLAGS) -c $< -o $@ | ||
|
||
SRC_FILES = $(wildcard $(SRC_DIR)/*.c) | ||
ASM_FILES = $(wildcard *.S) | ||
OBJ_FILES = $(SRC_FILES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) | ||
OBJ_FILES += $(ASM_FILES:%.S=$(BUILD_DIR)/_%.o) | ||
|
||
kernel8.img: linker.ld $(OBJ_FILES) | ||
$(ARMGNU)-ld -T linker.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES) | ||
$(ARMGNU)-objcopy -O binary $(BUILD_DIR)/kernel8.elf kernel8.img | ||
|
||
qemu: all kernel8.img initramfs.cpio bcm2710-rpi-3-b-plus.dtb | ||
clear | ||
qemu-system-aarch64 $(QEMUFLAGS) -kernel kernel8.img -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb | ||
|
||
debug: all kernel8.img initramfs.cpio bcm2710-rpi-3-b-plus.dtb | ||
qemu-system-aarch64 $(QEMUFLAGS) -kernel kernel8.img -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -S -s -d int |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
ARMGNU ?= aarch64-linux-gnu | ||
CFLAGS = -nostdlib -nostartfiles -ffreestanding -mgeneral-regs-only -Wall -g | ||
QEMUFLAGS = -M raspi3b -display none -serial null -serial pty | ||
|
||
all: clean bootloader.img | ||
|
||
clean: | ||
rm -rf build *.img | ||
|
||
bootloader.img: | ||
mkdir -p build | ||
$(ARMGNU)-gcc $(CFLAGS) -c main.c -o build/main.o | ||
$(ARMGNU)-gcc $(CFLAGS) -c start.S -o build/start.o | ||
$(ARMGNU)-gcc $(CFLAGS) -c boot.c -o build/boot.o | ||
$(ARMGNU)-ld -T linker.ld -o build/bootloader.elf build/main.o build/start.o build/boot.o | ||
$(ARMGNU)-objcopy -O binary build/bootloader.elf bootloader.img | ||
|
||
qemu: clean bootloader.img | ||
qemu-system-aarch64 $(QEMUFLAGS) -kernel bootloader.img -initrd ../initramfs.cpio -dtb ../bcm2710-rpi-3-b-plus.dtb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#include "boot.h" | ||
|
||
void uart_init() { | ||
// Configure GPIO pins | ||
register unsigned int r = *GPFSEL1; | ||
r &= ~((7 << 12) | (7 << 15)); | ||
r |= (2 << 12) | (2 << 15); | ||
*GPFSEL1 = r; | ||
|
||
*GPPUD = 0; | ||
for (int i = 0; i < 150; i++) asm volatile("nop"); | ||
*GPPUDCLK0 = (1 << 14) | (1 << 15); | ||
for (int i = 0; i < 150; i++) asm volatile("nop"); | ||
*GPPUD = 0; | ||
*GPPUDCLK0 = 0; | ||
|
||
*AUX_ENABLE |= 1; | ||
*AUX_MU_CNTL = 0; | ||
*AUX_MU_IER = 0; | ||
*AUX_MU_LCR = 3; | ||
*AUX_MU_MCR = 0; | ||
*AUX_MU_BAUD = 270; | ||
*AUX_MU_IIR = 6; | ||
*AUX_MU_CNTL = 3; | ||
} | ||
|
||
char uart_recv() { | ||
while (!(*AUX_MU_LSR & 0x01)) asm volatile("nop"); | ||
return (char)(*AUX_MU_IO); | ||
} | ||
|
||
void uart_putc(char c) { | ||
if (c == '\n') uart_putc('\r'); | ||
while (!(*AUX_MU_LSR & 0x20)) asm volatile("nop"); | ||
*AUX_MU_IO = c; | ||
} | ||
|
||
void uart_puts(const char *s) { | ||
while (*s) uart_putc(*s++); | ||
} | ||
|
||
int atoi(const char *s) { | ||
int result = 0; | ||
int sign = 1; | ||
int i = 0; | ||
|
||
while (s[i] == ' ') i++; | ||
|
||
if (s[i] == '-') { | ||
sign = -1; | ||
i++; | ||
} else if (s[i] == '+') | ||
i++; | ||
|
||
while (s[i] >= '0' && s[i] <= '9') { | ||
result = result * 10 + (s[i] - '0'); | ||
i++; | ||
} | ||
|
||
return sign * result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#ifndef BOOT_H | ||
#define BOOT_H | ||
|
||
/* ==================== GPIO ==================== */ | ||
#define MMIO_BASE 0x3F000000 | ||
|
||
#define GPFSEL0 ((volatile unsigned int *)(MMIO_BASE + 0x00200000)) | ||
#define GPFSEL1 ((volatile unsigned int *)(MMIO_BASE + 0x00200004)) | ||
#define GPFSEL2 ((volatile unsigned int *)(MMIO_BASE + 0x00200008)) | ||
#define GPFSEL3 ((volatile unsigned int *)(MMIO_BASE + 0x0020000C)) | ||
#define GPFSEL4 ((volatile unsigned int *)(MMIO_BASE + 0x00200010)) | ||
#define GPFSEL5 ((volatile unsigned int *)(MMIO_BASE + 0x00200014)) | ||
#define GPSET0 ((volatile unsigned int *)(MMIO_BASE + 0x0020001C)) | ||
#define GPSET1 ((volatile unsigned int *)(MMIO_BASE + 0x00200020)) | ||
#define GPCLR0 ((volatile unsigned int *)(MMIO_BASE + 0x00200028)) | ||
#define GPCLR1 ((volatile unsigned int *)(MMIO_BASE + 0x0020002C)) | ||
#define GPLEV0 ((volatile unsigned int *)(MMIO_BASE + 0x00200034)) | ||
#define GPLEV1 ((volatile unsigned int *)(MMIO_BASE + 0x00200038)) | ||
#define GPEDS0 ((volatile unsigned int *)(MMIO_BASE + 0x00200040)) | ||
#define GPEDS1 ((volatile unsigned int *)(MMIO_BASE + 0x00200044)) | ||
#define GPHEN0 ((volatile unsigned int *)(MMIO_BASE + 0x00200064)) | ||
#define GPHEN1 ((volatile unsigned int *)(MMIO_BASE + 0x00200068)) | ||
#define GPPUD ((volatile unsigned int *)(MMIO_BASE + 0x00200094)) | ||
#define GPPUDCLK0 ((volatile unsigned int *)(MMIO_BASE + 0x00200098)) | ||
#define GPPUDCLK1 ((volatile unsigned int *)(MMIO_BASE + 0x0020009C)) | ||
|
||
/* ==================== UART ==================== */ | ||
#define AUX_ENABLE ((volatile unsigned int *)(MMIO_BASE + 0x00215004)) | ||
#define AUX_MU_IO ((volatile unsigned int *)(MMIO_BASE + 0x00215040)) | ||
#define AUX_MU_IER ((volatile unsigned int *)(MMIO_BASE + 0x00215044)) | ||
#define AUX_MU_IIR ((volatile unsigned int *)(MMIO_BASE + 0x00215048)) | ||
#define AUX_MU_LCR ((volatile unsigned int *)(MMIO_BASE + 0x0021504C)) | ||
#define AUX_MU_MCR ((volatile unsigned int *)(MMIO_BASE + 0x00215050)) | ||
#define AUX_MU_LSR ((volatile unsigned int *)(MMIO_BASE + 0x00215054)) | ||
#define AUX_MU_MSR ((volatile unsigned int *)(MMIO_BASE + 0x00215058)) | ||
#define AUX_MU_SCRATCH ((volatile unsigned int *)(MMIO_BASE + 0x0021505C)) | ||
#define AUX_MU_CNTL ((volatile unsigned int *)(MMIO_BASE + 0x00215060)) | ||
#define AUX_MU_STAT ((volatile unsigned int *)(MMIO_BASE + 0x00215064)) | ||
#define AUX_MU_BAUD ((volatile unsigned int *)(MMIO_BASE + 0x00215068)) | ||
|
||
void uart_init(); | ||
char uart_recv(); | ||
void uart_putc(char c); | ||
void uart_puts(const char *s); | ||
|
||
/* ==================== UTILS ==================== */ | ||
int atoi(const char *s); | ||
|
||
#endif // BOOT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
SECTIONS | ||
{ | ||
. = 0x60000; | ||
__loader_start = .; | ||
.text : { *(.text.boot) *(.text) } | ||
.rodata : { *(.rodata) } | ||
.data : { *(.data) } | ||
.bss : { | ||
__bss_start = .; | ||
*(.bss) | ||
__bss_end = .; | ||
} | ||
__loader_end = .; | ||
} | ||
__bss_size = (__bss_end - __bss_start) >> 3; | ||
__loader_size = (__loader_end - __loader_start) >> 3; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "boot.h" | ||
|
||
int main() { | ||
uart_init(); | ||
uart_puts("\033[2J\033[H"); | ||
uart_puts( | ||
"UART Bootloader\n" | ||
"Waiting for kernel...\n"); | ||
|
||
// Get kernel image size | ||
char buf[16] = {0}; | ||
for (int i = 0; i < 16; i++) { | ||
buf[i] = uart_recv(); | ||
if (buf[i] == '\n') { | ||
buf[i] = '\0'; | ||
break; | ||
} | ||
} | ||
|
||
// Load kernel image | ||
uart_puts("Kernel size: "); | ||
uart_puts(buf); | ||
uart_puts(" bytes.\n"); | ||
uart_puts("Loading the kernel image...\n"); | ||
|
||
unsigned int size = atoi(buf); | ||
char *kernel = (char *)0x80000; | ||
while (size--) *kernel++ = uart_recv(); | ||
|
||
// Restore registers x0 x1 x2 x3 | ||
// Jump to the new kernel | ||
asm volatile( | ||
"" | ||
"mov x0, x10;" | ||
"mov x1, x11;" | ||
"mov x2, x12;" | ||
"mov x3, x13;" | ||
"mov x30, 0x80000;" | ||
"ret;"); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#!/bin/bash | ||
|
||
# This script sends the kernel image to Rpi3 through UART | ||
|
||
DEST_PATH="/dev/ttyUSB0" | ||
KERNEL_PATH="../kernel8.img" | ||
|
||
# Check the root permission | ||
if [ "$(id -u)" != "0" ]; then | ||
echo "This script must be run as root" | ||
exit 1 | ||
fi | ||
|
||
if [ $1 ] | ||
then | ||
DEST_PATH="$1" | ||
fi | ||
|
||
# Get the size of the kernel image file and send it to Rpi3 | ||
# wc -c: count bytes of a file | ||
# sleep: wait n seconds | ||
wc -c < $KERNEL_PATH > $DEST_PATH | sleep 1 | ||
|
||
# Send the kernel image | ||
# pv: redirect file input to specified tty | ||
# add --rate-limit <n> option to limit the speed | ||
pv $KERNEL_PATH > $DEST_PATH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
.section ".text.boot" | ||
|
||
.global _start | ||
|
||
_start: | ||
/* save registers x0 x1 x2 x3 */ | ||
mov x10, x0 /* dtb_base address */ | ||
mov x11, x1 | ||
mov x12, x2 | ||
mov x12, x3 | ||
|
||
/* relocate bootloader */ | ||
ldr x1, =0x80000 | ||
ldr x2, =__loader_start // 0x60000 | ||
ldr w3, =__loader_size | ||
|
||
relocate: | ||
ldr x4, [x1], #8 | ||
str x4, [x2], #8 | ||
sub w3, w3, #1 | ||
cbnz w3, relocate | ||
|
||
/* set stack pointer */ | ||
ldr x1, =_start | ||
mov sp, x1 | ||
|
||
/* clear bss section */ | ||
ldr x1, =__bss_start | ||
ldr w2, =__bss_size | ||
|
||
bss_reset: | ||
cbz w2, run_main | ||
str xzr, [x1], #8 | ||
sub w2, w2, #1 | ||
cbnz w2, bss_reset | ||
|
||
run_main: | ||
/* branch to main function */ | ||
bl main-0x20000 | ||
b run_main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#pragma once | ||
|
||
#define MAX_BUF_SIZE 1024 | ||
#define END_OF_COMMAND_LIST "NULL" | ||
|
||
struct command { | ||
const char *name; | ||
const char *help; | ||
void (*func)(void); | ||
}; | ||
|
||
extern struct command commands[]; | ||
|
||
// Commands | ||
void cmd_help(); | ||
void cmd_hello(); | ||
void cmd_reboot(); | ||
void cmd_cancel(); | ||
void cmd_info(); | ||
void cmd_ls(); | ||
void cmd_cat(); | ||
void cmd_run(); | ||
void cmd_clear(); | ||
void cmd_timer(); | ||
void cmd_lab(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
|
||
struct fdt_header { | ||
uint32_t magic; | ||
uint32_t totalsize; | ||
uint32_t off_dt_struct; | ||
uint32_t off_dt_strings; | ||
uint32_t off_mem_rsvmap; | ||
uint32_t version; | ||
uint32_t last_comp_version; | ||
uint32_t boot_cpuid_phys; | ||
uint32_t size_dt_strings; | ||
uint32_t size_dt_struct; | ||
}; | ||
|
||
void fdt_traverse(void (*callback)(void *, char *)); |
Oops, something went wrong.