Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

411551025 lab3 lab4 lab5 lab6 lab7 #233

Open
wants to merge 8 commits into
base: 411551025
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion lab2/bootloader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ int main() {
"ret;");

return 0;
}
}
3 changes: 2 additions & 1 deletion lab2/src/initramfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ void initramfs_cat(const char *target) {
strncpy(pathname, fptr + sizeof(cpio_t), namesize);
if (!strcmp(target, pathname)) {
// Print its content
char data[filesize];
char data[filesize + 1];
strncpy(data, fptr + headsize, filesize);
data[filesize] = '\0';
uart_puts(data);
uart_putc('\n');
return;
Expand Down
6 changes: 6 additions & 0 deletions lab3/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.vscode
build
rootfs
temp
*.img
*.dtb
36 changes: 36 additions & 0 deletions lab3/Makefile
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
19 changes: 19 additions & 0 deletions lab3/bootloader/Makefile
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
61 changes: 61 additions & 0 deletions lab3/bootloader/boot.c
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;
}
49 changes: 49 additions & 0 deletions lab3/bootloader/boot.h
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
16 changes: 16 additions & 0 deletions lab3/bootloader/linker.ld
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;
42 changes: 42 additions & 0 deletions lab3/bootloader/main.c
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;
}
27 changes: 27 additions & 0 deletions lab3/bootloader/sender.sh
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
40 changes: 40 additions & 0 deletions lab3/bootloader/start.S
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
25 changes: 25 additions & 0 deletions lab3/include/command.h
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();
18 changes: 18 additions & 0 deletions lab3/include/devtree.h
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 *));
Loading