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

310551097 lab7 #182

Open
wants to merge 17 commits into
base: 310551097
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
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
61 changes: 61 additions & 0 deletions lab6/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# debug use CFLAGS='-g3' ASMFLAGS='-g3'
# Modify from
# https://github.com/s-matyukevich/raspberry-pi-os/blob/master/src/lesson01/Makefile
ARMGNU ?= aarch64-linux-gnu

COPS = $(CFLAGS) -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude #-ggdb #-D__FS_DEBUG #-D__DEBUG #-D__DEBUG_MM #-D__DEBUG_MM_ALLOC #-D__DEBUG_MM_SCHED
ASMOPS = $(ASMFLAGS) -Iinclude

BUILD_DIR = build
SRC_DIR = src

all : kernel8.img bootloader/bootloader.img

debug: COPS += -DDEBUG
debug: ASMOPS += -DDEBUG
debug: all

clean :
rm -rf $(BUILD_DIR) *.img
make -C bootloader clean

$(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c
mkdir -p $(@D)
$(ARMGNU)-gcc $(COPS) -MMD -c $< -o $@

$(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S
$(ARMGNU)-gcc $(ASMOPS) -MMD -c $< -o $@

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)

kernel8.img: linker.ld $(OBJ_FILES)
$(ARMGNU)-ld -g -T linker.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES)
$(ARMGNU)-objcopy -g $(BUILD_DIR)/kernel8.elf -O binary kernel8.img

run:
qemu-system-aarch64 -M raspi3 -kernel kernel8.img -display none -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb

run_display:
qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb

run_display_debug:
qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial stdio -s -S -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb

run_debug:
qemu-system-aarch64 -M raspi3 -kernel kernel8.img -display none -serial null -serial stdio -s -S -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb

connect_raspi:
sudo screen /dev/ttyUSB0 115200

bootloader/bootloader.img:
make -C bootloader

filesystem:
cd rootfs;find . | cpio -o -H newc > ../initramfs.cpio

Binary file added lab6/bcm2710-rpi-3-b-plus.dtb
Binary file not shown.
50 changes: 50 additions & 0 deletions lab6/bootloader/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# debug use CFLAGS='-g' ASMFLAGS='-g'
# Modify from
# https://github.com/s-matyukevich/raspberry-pi-os/blob/master/src/lesson01/Makefile
ARMGNU ?= aarch64-linux-gnu

COPS = $(CFLAGS) -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude #-ggdb #-D__FS_DEBUG #-D__DEBUG #-D__DEBUG_MM #-D__DEBUG_MM_ALLOC #-D__DEBUG_MM_SCHED
ASMOPS = $(ASMFLAGS) -Iinclude

BUILD_DIR = build
SRC_DIR = src

all : bootloader.img

clean :
rm -rf $(BUILD_DIR) *.img

$(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c
mkdir -p $(@D)
$(ARMGNU)-gcc $(COPS) -MMD -c $< -o $@

$(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S
$(ARMGNU)-gcc $(ASMOPS) -MMD -c $< -o $@

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)

bootloader.img: linker.ld $(OBJ_FILES)
$(ARMGNU)-ld -g -T linker.ld -o $(BUILD_DIR)/bootloader.elf $(OBJ_FILES)
$(ARMGNU)-objcopy -g $(BUILD_DIR)/bootloader.elf -O binary bootloader.img

run:
qemu-system-aarch64 -M raspi3 -kernel bootloader.img -display none -serial null -serial stdio

run_pty:
qemu-system-aarch64 -M raspi3 -kernel bootloader.img -display none -serial null -serial pty -initrd ../initramfs.cpio -dtb ../bcm2710-rpi-3-b-plus.dtb

run_debug:
qemu-system-aarch64 -M raspi3 -kernel bootloader.img -display none -serial null -serial stdio -dtb ../bcm2710-rpi-3-b-plus.dtb -s -S

run_debug_pty:
qemu-system-aarch64 -M raspi3 -kernel bootloader.img -display none -serial null -serial pty -s -S

connect_raspi:
sudo screen /dev/ttyUSB0 115200

25 changes: 25 additions & 0 deletions lab6/bootloader/include/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef GPIO_H
#define GPIO_H

#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 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))

#endif
26 changes: 26 additions & 0 deletions lab6/bootloader/include/mbox.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* a properly aligned buffer */
/* use this buffer(global variable) directly and the mbox_call will use it after call*/
/* mbox format https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */
/* mbox address need to be aligned to 16 bytes */
extern volatile unsigned int mbox[36];

#define MBOX_REQUEST 0

/* channels */
#define MBOX_CH_POWER 0
#define MBOX_CH_FB 1
#define MBOX_CH_VUART 2
#define MBOX_CH_VCHIQ 3
#define MBOX_CH_LEDS 4
#define MBOX_CH_BTNS 5
#define MBOX_CH_TOUCH 6
#define MBOX_CH_COUNT 7
#define MBOX_CH_PROP 8

/* tags */
#define GET_BOARD_REVISION 0x10002
#define MBOX_TAG_GETSERIAL 0x10004
#define GET_ARM_MEMORY 0x10005
#define MBOX_TAG_LAST 0

int mbox_call(unsigned char ch);
8 changes: 8 additions & 0 deletions lab6/bootloader/include/shell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef SHELL_H
#define SHELL_H

void shell();
void do_cmd(char* cmd);
void print_system_messages();

#endif
9 changes: 9 additions & 0 deletions lab6/bootloader/include/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef STRING_H
#define STRING_H

int strcmp (const char * s1, const char * s2 );
char* strcat (char *dest, const char *src);
unsigned long long strlen(const char *str);
char* strcpy (char *dest, const char *src);
char* memcpy (void *dest, const void *src, unsigned long long len);
#endif
14 changes: 14 additions & 0 deletions lab6/bootloader/include/system.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef SYSTEM_H
#define SYSTEM_H

extern char* _dtb;

int get_board_revision(unsigned int* board_revision);
int get_arm_memory_info(unsigned int* base_addr,unsigned int* size);
void set(long addr, unsigned int value);
void reboot();
void reset(int tick);
void cancel_reset();
void load_kernel();

#endif
16 changes: 16 additions & 0 deletions lab6/bootloader/include/uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef UART_H
#define UART_H

#define MAX_BUF_SIZE 0x100

void uart_init();
void uart_putc(char c);
char uart_getc();
int uart_puts(char *s);
char* uart_gets(char *buf);
int uart_printf(char *s);
void uart_hex(unsigned int d);
void disable_uart();
char uart_getc_pure();

#endif
22 changes: 22 additions & 0 deletions lab6/bootloader/linker.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
SECTIONS
{
. = 0x70000;
_code_relocate_place = .;
/*bootloader on 0x80000, kernel on 0x80000 need to self relocate bootloader to other place*/
. = 0x80000;
PROVIDE(_start = .);
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
PROVIDE(_data = .);
.data : { *(.data .data.* .gnu.linkonce.d*) }
.bss (NOLOAD) : {
. = ALIGN(16);
__bss_start = .;
*(.bss .bss.*)
*(COMMON)
__bss_end = .;
}
_end = .;
}
__bss_size = (__bss_end - __bss_start)>>3;
__code_size = (_end - _start);
44 changes: 44 additions & 0 deletions lab6/bootloader/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "uart.h"
#include "mbox.h"
#include "shell.h"
#include "string.h"
#include "system.h"

extern char* _code_relocate_place;
extern unsigned long long __code_size;
extern unsigned long long _start;
extern char* _dtb;

void code_relocate(char * addr);

int relocate=1;

void main(char* arg)
{
_dtb = arg;
char* reloc_place = (char*)&_code_relocate_place;

if(relocate) // only do relocate once
{
relocate = 0;
code_relocate(reloc_place);
}

// set up serial console
uart_init();

shell();
}

// relocate code and jump to there
void code_relocate(char * addr)
{
unsigned long long size = (unsigned long long)&__code_size;
char* start = (char *)&_start;
for(unsigned long long i=0;i<size;i++)
{
addr[i] = start[i];
}

((void (*)(char*))addr)(_dtb); //jump to new place
}
37 changes: 37 additions & 0 deletions lab6/bootloader/src/mbox.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "gpio.h"

/* mailbox message buffer */
volatile unsigned int __attribute__((aligned(16))) mbox[36];

#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
#define MBOX_RESPONSE 0x80000000 // mbox[1] = 0x80000000 -> request successful
#define MBOX_FULL 0x80000000
#define MBOX_EMPTY 0x40000000

/**
* Make a mailbox call. Returns 0 on failure, non-zero on success
*/
int mbox_call(unsigned char ch) // Mailbox 0 define several channels, but we only use channel 8 (CPU->GPU) for communication.
{
unsigned int r = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
/* wait until we can write to the mailbox */
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
/* write the address of our message to the mailbox with channel identifier */
*MBOX_WRITE = r;
/* now wait for the response */
while(1) {
/* is there a response? */
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
/* is it a response to our message? */
if(r == *MBOX_READ)
/* is it a valid successful response? */
return mbox[1]==MBOX_RESPONSE;
}
return 0;
}
63 changes: 63 additions & 0 deletions lab6/bootloader/src/shell.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include "uart.h"
#include "string.h"
#include "shell.h"
#include "mbox.h"
#include "system.h"

void shell()
{
char cmd[MAX_BUF_SIZE];
print_system_messages();
uart_puts("Welcome, this is bootloader. Try to load kernel with uart with protocol in system.c(load_kernel)");
while(1)
{
uart_printf("# ");
uart_gets(cmd);
do_cmd(cmd);
}
}

void do_cmd(char* cmd)
{
if(strcmp(cmd,"help")==0)
{
uart_puts("help : print this help menu");
uart_puts("hello : print Hello World!");
uart_puts("reboot : reboot the device");
uart_puts("load_kernel : load kernel code from uart to 0x80000 and jump to it!");
}
else if(strcmp(cmd,"hello")==0)
{
uart_puts("Hello World!");
}
else if(strcmp(cmd,"reboot")==0)
{
reboot();
}else if(strcmp(cmd,"load_kernel")==0)
{
load_kernel();
}else
{
uart_puts("Unknown command!");
}
}

void print_system_messages()
{
unsigned int board_revision;
get_board_revision(&board_revision);
uart_printf("Board revision is : 0x");
uart_hex(board_revision);
uart_puts("");

unsigned int arm_mem_base_addr;
unsigned int arm_mem_size;

get_arm_memory_info(&arm_mem_base_addr,&arm_mem_size);
uart_printf("ARM memory base address in bytes : 0x");
uart_hex(arm_mem_base_addr);
uart_puts("");
uart_printf("ARM memory size in bytes : 0x");
uart_hex(arm_mem_size);
uart_puts("");
}
Loading