From f3c64c2f815eb4b1adef60d845f514436d3a52dd Mon Sep 17 00:00:00 2001 From: Benedict-CS Date: Thu, 2 May 2024 20:17:09 +0800 Subject: [PATCH] Lab2 --- Lab2/.vscode/launch.json | 26 ++++ Lab2/.vscode/settings.json | 9 ++ Lab2/Allocator/allocator.c | 42 ++++++ Lab2/Allocator/header/allocator.h | 3 + Lab2/Bootloader/config.txt | 4 + Lab2/Bootloader/linker.ld | 23 +++ Lab2/Bootloader/main.c | 47 ++++++ Lab2/Bootloader/relocate.s | 19 +++ Lab2/Bootloader/send.py | 32 +++++ Lab2/Bootloader/start.s | 32 +++++ Lab2/CPIO/cpio.c | 67 +++++++++ Lab2/CPIO/header/cpio.h | 22 +++ Lab2/Devicetree/devicetree.c | 81 +++++++++++ Lab2/Devicetree/header/devicetree.h | 32 +++++ Lab2/Main/linker.ld | 19 +++ Lab2/Main/main.c | 14 ++ Lab2/Main/start.s | 32 +++++ Lab2/Makefile | 54 +++++++ Lab2/Other/Archive/Makefile | 5 + .../Archive/bcm2710-rpi-3-b-plus (copy).dtb | Bin 0 -> 34228 bytes Lab2/Other/Archive/bcm2710-rpi-3-b-plus.dtb | Bin 0 -> 268 bytes Lab2/Other/Archive/initramfs.cpio | Bin 0 -> 512 bytes Lab2/Other/Archive/rootfs/hello | 1 + Lab2/Other/Archive/rootfs/hi | 1 + Lab2/Shell/header/shell.h | 1 + Lab2/Shell/shell.c | 79 ++++++++++ Lab2/UART/header/mini_uart.h | 25 ++++ Lab2/UART/mini_uart.c | 75 ++++++++++ Lab2/Utils/header/utils.h | 15 ++ Lab2/Utils/utils.c | 135 ++++++++++++++++++ 30 files changed, 895 insertions(+) create mode 100644 Lab2/.vscode/launch.json create mode 100644 Lab2/.vscode/settings.json create mode 100644 Lab2/Allocator/allocator.c create mode 100644 Lab2/Allocator/header/allocator.h create mode 100644 Lab2/Bootloader/config.txt create mode 100644 Lab2/Bootloader/linker.ld create mode 100644 Lab2/Bootloader/main.c create mode 100644 Lab2/Bootloader/relocate.s create mode 100644 Lab2/Bootloader/send.py create mode 100644 Lab2/Bootloader/start.s create mode 100644 Lab2/CPIO/cpio.c create mode 100644 Lab2/CPIO/header/cpio.h create mode 100644 Lab2/Devicetree/devicetree.c create mode 100644 Lab2/Devicetree/header/devicetree.h create mode 100644 Lab2/Main/linker.ld create mode 100644 Lab2/Main/main.c create mode 100644 Lab2/Main/start.s create mode 100644 Lab2/Makefile create mode 100644 Lab2/Other/Archive/Makefile create mode 100644 Lab2/Other/Archive/bcm2710-rpi-3-b-plus (copy).dtb create mode 100644 Lab2/Other/Archive/bcm2710-rpi-3-b-plus.dtb create mode 100644 Lab2/Other/Archive/initramfs.cpio create mode 100644 Lab2/Other/Archive/rootfs/hello create mode 100644 Lab2/Other/Archive/rootfs/hi create mode 100644 Lab2/Shell/header/shell.h create mode 100644 Lab2/Shell/shell.c create mode 100644 Lab2/UART/header/mini_uart.h create mode 100644 Lab2/UART/mini_uart.c create mode 100644 Lab2/Utils/header/utils.h create mode 100644 Lab2/Utils/utils.c diff --git a/Lab2/.vscode/launch.json b/Lab2/.vscode/launch.json new file mode 100644 index 000000000..a175faab1 --- /dev/null +++ b/Lab2/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "GDB debug - custom", + "type": "cppdbg", + "request": "launch", + "program": "~/Desktop/my_OSC/OSC/Lab2/bootloader.elf", + "args": [], + "stopAtEntry": true, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "miDebuggerPath": "gdb-multiarch", + "miDebuggerServerAddress": "127.0.0.1:1234" + } + ] +} \ No newline at end of file diff --git a/Lab2/.vscode/settings.json b/Lab2/.vscode/settings.json new file mode 100644 index 000000000..acfd9c763 --- /dev/null +++ b/Lab2/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "files.associations": { + "sched.h": "c", + "allocator.h": "c", + "type_traits": "c", + "stddef.h": "c", + "devicetree.h": "c" + } +} \ No newline at end of file diff --git a/Lab2/Allocator/allocator.c b/Lab2/Allocator/allocator.c new file mode 100644 index 000000000..0d2b8e283 --- /dev/null +++ b/Lab2/Allocator/allocator.c @@ -0,0 +1,42 @@ +#include "header/allocator.h" +#include "../header/mini_uart.h" +#include "../header/utils.h" + +#define MEM_START 0x10000000 + +unsigned long *malloc_cur = (unsigned long *)MEM_START; + +void *malloc(size_t size) +{ + align(&size,8); + unsigned long *malloc_ret = malloc_cur; + malloc_cur+=(unsigned int)size; + return malloc_ret; +} +/* + + Initial Memory Layout: ++-----------------------+ +| Address 0x10000000 | <--- malloc_cur starts here ++-----------------------+ + + Step 1: Call malloc(sizeof("Hello")) - Request 6 bytes, aligned to 8 bytes ++-----------------------+ 0x10000000 +| Reserved 8 bytes | <-- malloc_ret points here, now referred as 'a' +| (Uninitialized) | malloc_cur moved to 0x10000008 ++-----------------------+ 0x10000008 + + Step 2: Initialize Memory with "Hello" ++-----------------------+ 0x10000000 +| 'H' (a[0]) | +| 'e' (a[1]) | +| 'l' (a[2]) | +| 'l' (a[3]) | +| 'o' (a[4]) | +| '\0'(a[5]) | +| Padding (2 bytes) | <--- Memory alignment padding ++-----------------------+ 0x10000008 + + Continue Allocating... + + */ \ No newline at end of file diff --git a/Lab2/Allocator/header/allocator.h b/Lab2/Allocator/header/allocator.h new file mode 100644 index 000000000..c6aa2cb98 --- /dev/null +++ b/Lab2/Allocator/header/allocator.h @@ -0,0 +1,3 @@ +#include + +void* malloc(size_t size); diff --git a/Lab2/Bootloader/config.txt b/Lab2/Bootloader/config.txt new file mode 100644 index 000000000..8743bfe18 --- /dev/null +++ b/Lab2/Bootloader/config.txt @@ -0,0 +1,4 @@ +kernel=bootloader.img +arm_64bit=1 + +initramfs initramfs.cpio 0x20000000 \ No newline at end of file diff --git a/Lab2/Bootloader/linker.ld b/Lab2/Bootloader/linker.ld new file mode 100644 index 000000000..02e9e3bbe --- /dev/null +++ b/Lab2/Bootloader/linker.ld @@ -0,0 +1,23 @@ +SECTIONS +{ + . = 0x60000; + + text_begin = .; + .text.relo : { *(.text.relocate) } + + boot_entry = .; + .text.boot : { *(.text.boot) } + + .text : { *(.text) } + + .rodata : { *(.rodata) } + . = ALIGN(0x1000); + + .data : { *(.data) } + . = ALIGN(0x1000); + + bss_begin = .; + .bss (NOLOAD) : { *(.bss) } + . = ALIGN(0x1000); + bss_end = .; +} diff --git a/Lab2/Bootloader/main.c b/Lab2/Bootloader/main.c new file mode 100644 index 000000000..2bf74a57c --- /dev/null +++ b/Lab2/Bootloader/main.c @@ -0,0 +1,47 @@ +#include "../header/mini_uart.h" +#include "../header/utils.h" +#include + +#define BUFFER_MAX_SIZE 256 + +extern char *_dtb; + +void load_img() +{ + char *const kernel_addr = (char *)0x80000; + char buffer[BUFFER_MAX_SIZE]; + size_t index = 0; + + while (1) + { + buffer[index] = uart_recv(); + + if (buffer[index] == '\n') + break; + + index++; + } + + buffer[index + 1] = '\0'; + utils_newline2end(buffer); + uart_send('\r'); + + unsigned int img_size = utils_str2uint_dec(buffer); + + char *current = kernel_addr; + while (img_size--) + { + *current = uart_recv_raw(); + current++; + uart_send('.'); + } + + ((void (*)(char *))kernel_addr)(_dtb); +} + +void bootloader_main(void) +{ + uart_init(); + uart_send_string("Please sent the kernel image size:"); + load_img(); +} diff --git a/Lab2/Bootloader/relocate.s b/Lab2/Bootloader/relocate.s new file mode 100644 index 000000000..9a807fc59 --- /dev/null +++ b/Lab2/Bootloader/relocate.s @@ -0,0 +1,19 @@ +.section ".text.relocate" +.globl _start_relocate + +_start_relocate: + adr x10, . + ldr x12, =text_begin + adr x13, bss_end + +moving_relocate: + cmp x10, x13 + b.eq end_relocate + ldr x14, [x10], #8 + str x14, [x12], #8 + b moving_relocate + +end_relocate: + ldr x14, =boot_entry + br x14 + diff --git a/Lab2/Bootloader/send.py b/Lab2/Bootloader/send.py new file mode 100644 index 000000000..1fcd973a2 --- /dev/null +++ b/Lab2/Bootloader/send.py @@ -0,0 +1,32 @@ +import serial +import os +import time +from tqdm import tqdm + +def send_file(serial_port, file_path, baud_rate=115200, timeout=0.5, sleep_time=0.002): + + tty = serial.Serial(serial_port, baud_rate, timeout=timeout) + + file_size = os.path.getsize(file_path) + + tty.write(str(file_size).encode('utf-8')) + tty.write("\n".encode('utf-8')) + time.sleep(sleep_time) + + pbar = tqdm(total=file_size, unit="B", unit_scale=True, desc="Sending") + + start_time = time.time() + + with open(file_path, "rb") as fp: + for byte in iter(lambda: fp.read(1), b''): + tty.write(byte) + pbar.update(len(byte)) + time.sleep(sleep_time) + + pbar.close() + + total_time = time.time() - start_time + + print(f"Transfer completed in {total_time:.2f} seconds. Speed: {file_size / total_time:.2f} Bytes/s") + +send_file("/dev/ttyUSB0", "kernel8.img") diff --git a/Lab2/Bootloader/start.s b/Lab2/Bootloader/start.s new file mode 100644 index 000000000..ace90ac04 --- /dev/null +++ b/Lab2/Bootloader/start.s @@ -0,0 +1,32 @@ +.section ".text.boot" +.globl _start_boot + +_start_boot: + ldr x19, =_dtb + str x0, [x19] + + mrs x20, mpidr_el1 + and x20, x20,#0xFF + cbz x20, master + +hang: + b hang + +master: + adr x20, bss_begin + adr x21, bss_end + sub x21, x21, x20 + bl memzero + + mov sp, #0x3F000000 + bl bootloader_main + +memzero: + str xzr, [x20], #8 + subs x21, x21, #8 + b.gt memzero + ret + +.global _dtb +.section .data +_dtb: .dc.a 0x0 diff --git a/Lab2/CPIO/cpio.c b/Lab2/CPIO/cpio.c new file mode 100644 index 000000000..b49afbac0 --- /dev/null +++ b/Lab2/CPIO/cpio.c @@ -0,0 +1,67 @@ +#include "header/cpio.h" +#include "../header/mini_uart.h" +#include "../header/utils.h" + +void cpio_ls() +{ + char *addr = cpio_addr; + + while (utils_str_compare((char *)(addr + sizeof(cpio_header)), "TRAILER!!!") != 0) + { + cpio_header *header = (cpio_header *)addr; + unsigned long pathname_size = hex2dec(header->c_namesize); //path_size + unsigned long file_size = hex2dec(header->c_filesize); //file_size + + unsigned long headerPathname_size = sizeof(cpio_header) + pathname_size; //total_size + + align(&headerPathname_size,4); + align(&file_size,4); + + uart_send_string(addr + sizeof(cpio_header)); // print the file name + uart_send_string("\n"); + + addr += (headerPathname_size + file_size); + } +} + +char *findFile(char *name) +{ + char *addr = cpio_addr; + while (utils_str_compare((char *)(addr + sizeof(cpio_header)), "TRAILER!!!") != 0) + { + if ((utils_str_compare((char *)(addr + sizeof(cpio_header)), name) == 0)) + return addr; + + cpio_header *header = (cpio_header *)addr; + unsigned long pathname_size = hex2dec(header->c_namesize); + unsigned long file_size = hex2dec(header->c_filesize); + unsigned long headerPathname_size = sizeof(cpio_header) + pathname_size; + + align(&headerPathname_size,4); + align(&file_size,4); + addr += (headerPathname_size + file_size); + } +} + +void cpio_cat(char *filename) +{ + char *target = findFile(filename); + + if (target) + { + cpio_header *header = (cpio_header *)target; + unsigned long pathname_size = hex2dec(header->c_namesize); + unsigned long file_size = hex2dec(header->c_filesize); + unsigned long headerPathname_size = sizeof(cpio_header) + pathname_size; + + align(&headerPathname_size,4); + align(&file_size,4); + + char *file_content = target + headerPathname_size; + + uart_send_string(file_content); + uart_send_string("\n"); + } + else + uart_send_string("Not found the file\n"); +} diff --git a/Lab2/CPIO/header/cpio.h b/Lab2/CPIO/header/cpio.h new file mode 100644 index 000000000..bd0d1c443 --- /dev/null +++ b/Lab2/CPIO/header/cpio.h @@ -0,0 +1,22 @@ +typedef struct cpio_header +{ + char c_magic[6]; + char c_ino[8]; + char c_mode[8]; + char c_uid[8]; + char c_gid[8]; + char c_nlink[8]; + char c_mtime[8]; + char c_filesize[8]; + char c_devmajor[8]; + char c_devminor[8]; + char c_rdevmajor[8]; + char c_rdevminor[8]; + char c_namesize[8]; + char c_check[8]; +}cpio_header; + +extern char * cpio_addr; +void cpio_ls(); +void cpio_cat(char *filename); +char * findFile(char *name); \ No newline at end of file diff --git a/Lab2/Devicetree/devicetree.c b/Lab2/Devicetree/devicetree.c new file mode 100644 index 000000000..d910da578 --- /dev/null +++ b/Lab2/Devicetree/devicetree.c @@ -0,0 +1,81 @@ +#include "../header/devicetree.h" +#include "../header/mini_uart.h" +#include "../header/utils.h" + +int space = 0; +char * cpio_addr; + +int parse_struct(fdt_callback cb, uintptr_t cur_ptr, uintptr_t strings_ptr, uint32_t totalsize) +{ + uintptr_t end_ptr = cur_ptr + totalsize; + + while (cur_ptr < end_ptr) + { + uint32_t token = get_le2be_uint((char *)cur_ptr); + cur_ptr += 4; + switch (token) + { + case FDT_BEGIN_NODE: + // uart_send_string(" FDT_BEGIN_NODE\n"); + cb(token, (char *)cur_ptr, NULL, 0); + cur_ptr += align_up(utils_strlen((char *)cur_ptr), 4); + break; + case FDT_END_NODE: + // uart_send_string(" FDT_END_NODE\n"); + cb(token, NULL, NULL, 0); + break; + case FDT_PROP:{ + // uart_send_string(" FDT_PROP\n"); + uint32_t len = get_le2be_uint((char *)cur_ptr); + cur_ptr += 4; + uint32_t nameoff = get_le2be_uint((char *)cur_ptr); + cur_ptr += 4; + cb(token, (char *)(strings_ptr + nameoff), (void *)cur_ptr, len); + + cur_ptr += align_up(len, 4);; + break; + } + case FDT_NOP: + // uart_send_string("In FDT_NOP\n"); + cb(token, NULL, NULL, 0); + break; + case FDT_END: + // uart_send_string(" FDT_END\n"); + cb(token, NULL, NULL, 0); + return 0; + default:; + return -1; + } + } +} + + +void get_initramfs_addr(int type, const char *name, const void *data, uint32_t size) +{ + if(type==FDT_PROP&&!utils_str_compare(name,"linux,initrd-start")){ + cpio_addr=(char *)(uintptr_t)get_le2be_uint(data); + uart_send_string("--> initramfs_addr at "); + uart_hex((uintptr_t)get_le2be_uint(data)); + uart_send('\n'); + } +} + +int fdt_traverse(fdt_callback cb, void* _dtb) +{ + uintptr_t dtb_ptr = (uintptr_t)_dtb; + // uart_send_string("\ndtb loading at:"); + // uart_hex(dtb_ptr); + // uart_send('\n'); + // uart_send('\n'); + fdt_header *header = (fdt_header *)dtb_ptr; + + if (get_le2be_uint(&(header->magic)) != 0xd00dfeed) + { + uart_send_string("header magic != 0xd00dfeed\n"); + return -1; + } + uint32_t totalsize = get_le2be_uint(&(header->totalsize)); + uintptr_t struct_ptr = dtb_ptr + get_le2be_uint(&(header->off_dt_struct)); + uintptr_t strings_ptr = dtb_ptr + get_le2be_uint(&(header->off_dt_strings)); + parse_struct(cb, struct_ptr, strings_ptr, totalsize); +} \ No newline at end of file diff --git a/Lab2/Devicetree/header/devicetree.h b/Lab2/Devicetree/header/devicetree.h new file mode 100644 index 000000000..6f661f0c8 --- /dev/null +++ b/Lab2/Devicetree/header/devicetree.h @@ -0,0 +1,32 @@ +#include +#include +/* + structure block: located at a 4-byte aligned offset from the beginning of the devicetree blob + token is a big-endian 32-bit integer, alligned on 32bit(padding 0) +*/ + +#define FDT_BEGIN_NODE 0x00000001 +#define FDT_END_NODE 0x00000002 +#define FDT_PROP 0x00000003 +#define FDT_NOP 0x00000004 +#define FDT_END 0x00000009 + +typedef struct fdt_header +{ + uint32_t magic; // contain the value 0xd00dfeed (big-endian). + uint32_t totalsize; // in byte + uint32_t off_dt_struct; // the offset in bytes of the structure block from the beginning of the header + 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; // the length in bytes of the strings block section + uint32_t size_dt_struct; +} fdt_header; + +typedef void (*fdt_callback)(int type, const char *name, const void *data, uint32_t size); +void print_dtb(int type, const char *name, const void *data, uint32_t size) ; +// void get_initramfs_addr(int type, const char *name, const void *data) ; +void get_initramfs_addr(int type, const char *name, const void *data, uint32_t size) ; +int fdt_traverse(fdt_callback cb, void* dtb_ptr); \ No newline at end of file diff --git a/Lab2/Main/linker.ld b/Lab2/Main/linker.ld new file mode 100644 index 000000000..dcbb0e3f7 --- /dev/null +++ b/Lab2/Main/linker.ld @@ -0,0 +1,19 @@ +SECTIONS +{ + . = 0x80000; + + .text.kernel : { *(.text.kernel) } + + .text : { *(.text) } + + .rodata : { *(.rodata) } + . = ALIGN(0x1000); + + .data : { *(.data) } + . = ALIGN(0x1000); + + bss_begin = .; + .bss (NOLOAD) : { *(.bss) } + . = ALIGN(0x1000); + bss_end = .; +} \ No newline at end of file diff --git a/Lab2/Main/main.c b/Lab2/Main/main.c new file mode 100644 index 000000000..cc7b55507 --- /dev/null +++ b/Lab2/Main/main.c @@ -0,0 +1,14 @@ +#include "../header/mini_uart.h" +#include "../header/shell.h" +#include "../header/devicetree.h" + +extern void *_dtb_ptr; + +void kernel_main(void) +{ + uart_send_string("Hello, world!\n"); + + fdt_traverse(get_initramfs_addr, _dtb_ptr); + + shell(); +} \ No newline at end of file diff --git a/Lab2/Main/start.s b/Lab2/Main/start.s new file mode 100644 index 000000000..d59f40b5c --- /dev/null +++ b/Lab2/Main/start.s @@ -0,0 +1,32 @@ +.section ".text.kernel" +.globl _start + +_start: + ldr x1, =_dtb_ptr + str x0, [x1] + + mrs x20, mpidr_el1 + and x20, x20,#0xFF // Check processor id + cbz x20, master // Hang for all non-primary CPU + +hang: + b hang + +master: + adr x20, bss_begin + adr x21, bss_end + sub x21, x21, x20 + bl memzero + + mov sp, #0x400000 + bl kernel_main + +memzero: + str xzr, [x20], #8 + subs x21, x21, #8 + b.gt memzero + ret + +.global _dtb_ptr +.section .data +_dtb_ptr: .dc.a 0x0 diff --git a/Lab2/Makefile b/Lab2/Makefile new file mode 100644 index 000000000..edd5900cd --- /dev/null +++ b/Lab2/Makefile @@ -0,0 +1,54 @@ +CC := aarch64-linux-gnu-gcc +LD := aarch64-linux-gnu-ld +OBJCOPY := aarch64-linux-gnu-objcopy +CFLAGS := -Wall -Wextra -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles +CFLAGS += -IMain -IUART/header -IShell/header -IUtils/header -ICPIO/header -IDevicetree/header -IAllocator/header +CFLAGS += -I/usr/lib/gcc-cross/aarch64-linux-gnu/11/include + +K8 := kernel8 +KERNEL_LINKER := Main/linker.ld +KERNEL_SRC_S := $(wildcard Main/*.s) +KERNEL_SRC_C := $(wildcard Main/*.c UART/*.c Shell/*.c Utils/*.c CPIO/*.c Devicetree/*.c Allocator/*.c) +KERNEL_OBJS := $(KERNEL_SRC_C:.c=.o) $(KERNEL_SRC_S:.s=.o) Main/main.o + +BL := bootloader +BOOTLOADER_LINKER := Bootloader/linker.ld +BOOTLOADER_SRC_S := $(shell find Bootloader/ -name '*.s') +BOOTLOADER_SRC_C := $(wildcard Bootloader/*.c UART/*.c Utils/*.c) +BOOTLOADER_OBJS := $(BOOTLOADER_SRC_C:.c=.o) $(BOOTLOADER_SRC_S:.s=.o) + +all: $(K8).img $(BL).img + +$(K8).img: $(KERNEL_OBJS) + $(LD) -T $(KERNEL_LINKER) -o $(K8).elf $^ + $(OBJCOPY) -O binary $(K8).elf $@ + +$(BL).img: $(BOOTLOADER_OBJS) + $(LD) -T $(BOOTLOADER_LINKER) -o $(BL).elf $^ + $(OBJCOPY) -O binary $(BL).elf $@ + +%.o: %.s + $(CC) $(CFLAGS) -c $< -o $@ + +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +sd: $(BL).img + cp $(K8).img /media/ben/4DFF-0A36 + sync + +qemu: + qemu-system-aarch64 -M raspi3b -serial null -serial stdio -display none -initrd Other/Archive/initramfs.cpio -dtb Other/Archive/bcm2710-rpi-3-b-plus.dtb -kernel $(K8).img + +bl: + qemu-system-aarch64 -M raspi3b -serial null -serial stdio -serial pty -display none -kernel $(BL).img -S -s + +rpi3: + screen /dev/ttyUSB0 115200 + +py: + python3 Bootloader/send.py + +clean: + rm -f $(wildcard */*.o) $(wildcard *.o) $(K8).elf $(K8).img $(BL).elf $(BL).img + diff --git a/Lab2/Other/Archive/Makefile b/Lab2/Other/Archive/Makefile new file mode 100644 index 000000000..ee0619f6f --- /dev/null +++ b/Lab2/Other/Archive/Makefile @@ -0,0 +1,5 @@ +all: + cd rootfs&&find . | cpio -o -H newc > ../initramfs.cpio + +clean: + -rm *.cpio \ No newline at end of file diff --git a/Lab2/Other/Archive/bcm2710-rpi-3-b-plus (copy).dtb b/Lab2/Other/Archive/bcm2710-rpi-3-b-plus (copy).dtb new file mode 100644 index 0000000000000000000000000000000000000000..c83b0817e2eb5295a3dfe6aafe3aa55d93e9785d GIT binary patch literal 34228 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 a%84l{MXANby2+_IImHah#hF#9P&NQE*ew14 literal 0 HcmV?d00001 diff --git a/Lab2/Other/Archive/initramfs.cpio b/Lab2/Other/Archive/initramfs.cpio new file mode 100644 index 0000000000000000000000000000000000000000..6b67d564f436cf2aafd409e9e0277f5221416ea6 GIT binary patch literal 512 zcmbV}K?=hl5JkO;7bt%;RkJiiX`!poD-==)^!~e!CPqS`md;|nGxPC{2n!1WwCSB2 z!O>C73LRXkcLkI&%6e#@`!%gTcGlM6q)K%XOsl+*`i_P!&p&yTczqbNk3Hp{7H{8U zehQ8Y=L0wX#EmrMy@2zkEw0&om> + +#define BUFFER_MAX_SIZE 256 +#define COMMNAD_LENGTH_MAX 20 + +extern void *_dtb_ptr; + +void read_command(char *buffer) +{ + size_t index = 0; + while (1) + { + buffer[index] = uart_recv(); + uart_send(buffer[index]); + if (buffer[index] == '\n') + { + break; + } + index++; + } + buffer[index + 1] = '\0'; + utils_newline2end(buffer); + uart_send('\r'); +} + +void help() +{ + uart_send_string("help : print this help menu\n"); + uart_send_string("ls : list the all file\n"); + uart_send_string("cat : print the file content\n"); + uart_send_string("malloc : a simple memory allocator\n"); + uart_send_string("dtb : get the address of initramfs \n"); +} + +void parse_command(char *buffer) +{ + if (buffer[0] == '\0') + return; + else if (utils_str_compare(buffer, "help") == 0) + help(); + else if (utils_str_compare(buffer, "ls") == 0) + cpio_ls(); + else if (utils_str_compare(buffer, "cat") == 0) + { + uart_send_string("Filename: "); + char buffer[BUFFER_MAX_SIZE]; + read_command(buffer); + cpio_cat(buffer); + } + else if (utils_str_compare(buffer, "malloc") == 0) + { + char *a = malloc(sizeof("Hello")); + + a[0] = 'H', a[1] = 'e', a[2] = 'l', a[3] = 'l', a[4] = 'o' ,a[5] = '\0'; + uart_send_string(a); + uart_send('\n'); + } + else if (utils_str_compare(buffer, "dtb") == 0) + fdt_traverse(get_initramfs_addr,_dtb_ptr); + else + uart_send_string("commnad not found\r\n"); +} + +void shell() +{ + while (1) + { + char buffer[BUFFER_MAX_SIZE]; + uart_send_string("$ "); + read_command(buffer); + parse_command(buffer); + } +} diff --git a/Lab2/UART/header/mini_uart.h b/Lab2/UART/header/mini_uart.h new file mode 100644 index 000000000..e3bbf90da --- /dev/null +++ b/Lab2/UART/header/mini_uart.h @@ -0,0 +1,25 @@ +#define MMIO_BASE 0x3F000000 // Base address for memory-mapped I/O + +// GPIO Function Select Registers. +#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004)) +#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094)) +#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098)) + +// Mini UART (AUX) Peripheral Registers. +#define AUX_ENABLE ((volatile unsigned int *)(MMIO_BASE + 0x00215004)) +#define AUX_MU_IO_REG ((volatile unsigned int *)(MMIO_BASE + 0x00215040)) +#define AUX_MU_IER_REG ((volatile unsigned int *)(MMIO_BASE + 0x00215044)) +#define AUX_MU_LCR_REG ((volatile unsigned int *)(MMIO_BASE + 0x0021504C)) +#define AUX_MU_MCR_REG ((volatile unsigned int *)(MMIO_BASE + 0x00215050)) +#define AUX_MU_LSR_REG ((volatile unsigned int *)(MMIO_BASE + 0x00215054)) +#define AUX_MU_CNTL_REG ((volatile unsigned int *)(MMIO_BASE + 0x00215060)) +#define AUX_MU_BAUD_REG ((volatile unsigned int *)(MMIO_BASE + 0x00215068)) +#define AUX_MU_IIR_REG ((volatile unsigned int *)(MMIO_BASE + 0x00215048)) + +void uart_init(); +void uart_send_string(const char* str); +void uart_send(char c); +char uart_recv(); +char uart_recv_raw(); +void uart_hex(unsigned int d); +unsigned int uart_printf(char *fmt, ...); \ No newline at end of file diff --git a/Lab2/UART/mini_uart.c b/Lab2/UART/mini_uart.c new file mode 100644 index 000000000..1be3804cb --- /dev/null +++ b/Lab2/UART/mini_uart.c @@ -0,0 +1,75 @@ +#include "header/mini_uart.h" +#include "../header/utils.h" + + +void delay(unsigned int clock) +{ + while (clock--) + { + asm volatile("nop"); + } +} + + +void uart_init() +{ + unsigned int selector; + + selector = *GPFSEL1; + selector &= ~(7 << 12); // clean gpio14 + selector |= 2 << 12; // set alt5 for gpio14 + selector &= ~(7 << 15); // clean gpio15 + selector |= 2 << 15; // set alt5 for gpio 15 + *GPFSEL1 = selector; + + *GPPUD = 0; // set the required control signal (i.e. Pull-up or Pull-Down ) + delay(150); // provides the required set-up time for the control signal + *GPPUDCLK0 = (1 << 14) | (1 << 15); + delay(150); + *GPPUDCLK0 = 0; + + *AUX_ENABLE = 1; // Enable mini uart (this also enables access to its registers) + *AUX_MU_CNTL_REG = 0; // Disable auto flow control and disable receiver and transmitter (for now) + *AUX_MU_IER_REG = 0; // Disable receive and transmit interrupts + *AUX_MU_LCR_REG = 3; // Enable 8 bit mode + *AUX_MU_MCR_REG = 0; // Set RTS line to be always high + *AUX_MU_BAUD_REG = 270; // Set baud rate to 115200 + *AUX_MU_IIR_REG = 6; + *AUX_MU_CNTL_REG = 3; // Finally, enable transmitter and receiver +} + +void uart_send(const char c) +{ + if (c == '\n') + uart_send('\r'); + + while (!(*(AUX_MU_LSR_REG)&0x20)){} + + *AUX_MU_IO_REG = c; +} +char uart_recv() +{ + + while (!(*(AUX_MU_LSR_REG)&0x01)){} + + char temp = *(AUX_MU_IO_REG)&0xFF; + return temp == '\r' ? '\n' : temp; +} + +char uart_recv_raw() +{ + while (!(*(AUX_MU_LSR_REG)&0x01)){} + + char temp = *(AUX_MU_IO_REG)&0xFF; + return temp; +} + +void uart_send_string(const char *str) +{ + while (*str) + { + uart_send(*str++); + } +} + + diff --git a/Lab2/Utils/header/utils.h b/Lab2/Utils/header/utils.h new file mode 100644 index 000000000..0c66ee163 --- /dev/null +++ b/Lab2/Utils/header/utils.h @@ -0,0 +1,15 @@ +#include +#include + +int utils_str_compare(const char *a,const char *b); +void utils_newline2end(char *str); +unsigned int utils_str2uint_dec(const char *str); +unsigned long hex2dec(char *s); +void align(void *size, size_t s); +size_t utils_strlen(const char *s); +uint32_t get_le2be_uint(const void *p); +void uart_hex(unsigned int d); +uint32_t align_up(uint32_t size, int alignment); +void send_space(int count); +void utils_int2str_dec(int num, char *str); +uint32_t get_be32(const uint8_t *p) ; \ No newline at end of file diff --git a/Lab2/Utils/utils.c b/Lab2/Utils/utils.c new file mode 100644 index 000000000..0ba18e99b --- /dev/null +++ b/Lab2/Utils/utils.c @@ -0,0 +1,135 @@ +#include "header/utils.h" +#include "../header/mini_uart.h" +#include +#include + +int utils_str_compare(const char *a,const char *b) +{ + char aa, bb; + do + { + aa = (char)*a++; + bb = (char)*b++; + if (aa == '\0' || bb == '\0') + { + return aa - bb; + } + } while (aa == bb); + return aa - bb; +} + +void utils_newline2end(char *str) +{ + while (*str != '\0') + { + if (*str == '\n') + { + *str = '\0'; + return; + } + ++str; + } +} + + + +void utils_int2str_dec(int num, char *str) +{ + // num=7114 digit=4 + int digit = -1, temp = num; + while (temp > 0) + { + temp /= 10; + digit++; + } + for (int i = digit; i >= 0; i--) + { + int t = 1; + for (int j = 0; j < i; j++) + { + t *= 10; + } + *str = '0' + num / t; + num = num % t; + str++; + } + *str = '\0'; +} + +unsigned int utils_str2uint_dec(const char *str) +{ + unsigned int value = 0u; + + while (*str) + { + value = value * 10u + (*str - '0'); + ++str; + } + return value; +} + +unsigned long hex2dec(char *s) +{ + unsigned long r = 0; + for (int i = 0; i < 8; ++i) + { + if (s[i] >= '0' && s[i] <= '9') + r = r * 16 + s[i] - '0'; + else + r = r * 16 + s[i] - 'a' + 10; + } + + return r; +} + +// Transfer little endian to big endian +uint32_t get_be32(const uint8_t *p) { + return (uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]; +} + +void uart_hex(uint32_t d) { + uart_send_string("0x"); + for (int c = 28; c >= 0; c -= 4) { + int n = (d >> c) & 0xF; + n += n > 9 ? 'A' - 10 : '0'; + uart_send(n); + } +} + +uint32_t get_le2be_uint(const void *p) +{ + // transfer little endian to big endian + const unsigned char *bytes = p; + uint32_t res = bytes[3]; + res |= bytes[2] << 8; + res |= bytes[1] << 16; + res |= bytes[0] << 24; + return res; +} + +void send_space(int count) { + for (int i = 0; i < count; i++) { + uart_send(' '); + } +} + +size_t utils_strlen(const char *s) { + size_t i = 0; + while (s[i]) i++; + return i+1; +} + +void align(void *size, size_t s) // aligned to 4 byte +{ +/* + The pathname is followed by NUL bytes so that the total size of the fixed header plus pathname is a multiple of 4. + Likewise, the file data is padded to a multiple of 4 bytes. +*/ + unsigned long *x = (unsigned long *)size; + if ((*x) & (s-1)) + (*x) += s - ((*x) & (s-1)); +} + +uint32_t align_up(uint32_t size, int alignment) { + return (size + alignment - 1) & -alignment; +}