Skip to content

Commit 2a28de8

Browse files
authored
Merge pull request #1 from Po-Shun/LAB1
LAB1 finish
2 parents d812f92 + 1079310 commit 2a28de8

File tree

13 files changed

+434
-0
lines changed

13 files changed

+434
-0
lines changed

Makefile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
ARMPATH = /Users/stafen/Documents/osc/toolchain/arm-gnu-toolchain-12.2.rel1-darwin-x86_64-aarch64-none-elf/bin
2+
ARMGCC ?= $(ARMPATH)/aarch64-none-elf-gcc
3+
ARMLD ?= $(ARMPATH)/aarch64-none-elf-ld
4+
ARMOBJCOPY ?= $(ARMPATH)/aarch64-none-elf-objcopy
5+
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles -Iinclude
6+
ASMOPS = -Iinclude
7+
BUILD_DIR=out
8+
SRC_DIR=src
9+
10+
all: kernel8.img
11+
12+
clean:
13+
rm -rf $(BUILD_DIR) *.img
14+
15+
$(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c
16+
mkdir -p $(@D)
17+
$(ARMGCC) $(CFLAGS) -c $< -o $@
18+
19+
$(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S
20+
$(ARMGCC) $(CFLAGS) -c $< -o $@
21+
22+
C_FILES = $(wildcard $(SRC_DIR)/*.c)
23+
ASM_FILES = $(wildcard $(SRC_DIR)/*.S)
24+
OBJ_FILES = $(C_FILES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%_c.o)
25+
OBJ_FILES += $(ASM_FILES:$(SRC_DIR)/%.S=$(BUILD_DIR)/%_s.o)
26+
27+
kernel8.img: $(SRC_DIR)/linker.ld $(OBJ_FILES)
28+
$(ARMLD) -T $(SRC_DIR)/linker.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES)
29+
$(ARMOBJCOPY) $(BUILD_DIR)/kernel8.elf -O binary kernel8.img
30+
31+
run:
32+
qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio
33+
34+
deploy:
35+
rm /Volumes/NO\ NAME/kernel8.img
36+
cp kernel8.img /Volumes/NO\ NAME

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# OSC2023
2+
3+
| Github Account | Student ID | Name |
4+
|----------------|------------|---------------|
5+
| Po-Shun | 0716089 | 王柏舜 |
6+
7+
## Requirements
8+
9+
* a cross-compiler for aarch64
10+
* qemu-system-arm
11+
12+
## Build
13+
14+
```
15+
make all
16+
```
17+
## qemu
18+
```
19+
make run
20+
```
21+
22+
## Test With QEMU
23+
24+
```
25+
make run
26+
```

include/command.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
enum command{
2+
CMD_HELP,
3+
CMD_HELLO,
4+
CMD_REBOOT,
5+
CMD_INVAILD = -1
6+
};

include/gpio.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#define MMIO_BASE 0x3F000000
2+
3+
#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
4+
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
5+
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
6+
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
7+
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
8+
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
9+
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
10+
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
11+
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
12+
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
13+
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
14+
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
15+
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
16+
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
17+
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
18+
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
19+
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
20+
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))

include/mailbox.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#define MMIO_BASE 0x3f000000
2+
#define MAILBOX_BASE MMIO_BASE + 0xb880
3+
4+
#define GET_BOARD_REVISION 0x00010002
5+
#define GET_ARM_MEMORY 0x00010005
6+
#define REQUEST_CODE 0x00000000
7+
#define REQUEST_SUCCEED 0x80000000
8+
#define REQUEST_FAILED 0x80000001
9+
#define TAG_REQUEST_CODE 0x00000000
10+
#define END_TAG 0x00000000
11+
12+
#define VIDEOCORE_MAILBOX (MMIO_BASE + 0x0000B880)
13+
#define MAILBOX_READ ((volatile unsigned int*)(VIDEOCORE_MAILBOX + 0x0))
14+
#define MAILBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MAILBOX + 0x10))
15+
#define MAILBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MAILBOX + 0x14))
16+
#define MAILBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MAILBOX + 0x18))
17+
#define MAILBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MAILBOX + 0x1C))
18+
#define MAILBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MAILBOX + 0x20))
19+
#define MAILBOX_RESPONSE 0x80000000
20+
#define MAILBOX_FULL 0x80000000
21+
#define MAILBOX_EMPTY 0x40000000
22+
23+
24+
#define CHANNEL_8 8
25+
26+
void get_board_revision(unsigned int* revision);
27+
28+
void get_arm_memory(unsigned int* base, unsigned int* size);

include/reboot.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#define PM_PASSWORD 0x5a000000
2+
#define PM_RSTC 0x3F10001c
3+
#define PM_WDOG 0x3F100024
4+
5+
void reset(int tick);

include/uart.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
void uart_init();
2+
void uart_send(unsigned int c);
3+
char uart_getc();
4+
void uart_puts(char *s);
5+
void uart_hex(unsigned int d);

src/boot.S

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
.section ".text.boot"
2+
.global _start
3+
4+
_start:
5+
// read cpu id, stop slave cores
6+
mrs x1, mpidr_el1
7+
// # means constant 11(binary) = 3
8+
and x1, x1, #3
9+
// f for froward(down) and b for backward(up)
10+
cbz x1, 2f
11+
// cpu id > 0, stop
12+
1:
13+
wfe
14+
b 1b
15+
2: // cpu id == 0
16+
17+
// stack operation is "Full Descending" mode. Need set the top of the stack to the top of the stack space
18+
ldr x1, =_start
19+
mov sp, x1
20+
21+
// clear bss
22+
ldr x1, =__bss_start
23+
ldr w2, =__bss_size
24+
3: cbz w2, 4f
25+
// xzr -> 64 bits zero reg , store 0 to x1 address then x1 = x1 + 8
26+
str xzr, [x1], #8
27+
sub w2, w2, #1
28+
cbnz w2, 3b
29+
30+
// jump to C code, should not return
31+
4: bl main
32+
// for failsafe, halt this core too
33+
b 1b

src/linker.ld

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
SECTIONS
2+
{
3+
. = 0x80000;
4+
.text.boot : { *(.text.boot) }
5+
.text : { *(.text .text.* .gnu.linkonce.t*) }
6+
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
7+
.data : { *(.data .data.* .gnu.linkonce.d*) }
8+
.bss (NOLOAD) : {
9+
. = ALIGN(16);
10+
__bss_start = .;
11+
*(.bss .bss.*)
12+
*(COMMON)
13+
__bss_end = .;
14+
}
15+
_end = .;
16+
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
17+
}
18+
__bss_size = (__bss_end - __bss_start) >>3;

src/maibox.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include "mailbox.h"
2+
#include "uart.h"
3+
4+
// the LSB 4 bits is for channl -> 0xf == 16 in decimal, set the address of buffer be mutiple of 16 leave the last four bits to be zeros.
5+
volatile unsigned int __attribute__((aligned(16))) mailbox[8];
6+
7+
8+
/*
9+
Mail box message flow:
10+
1.Combine the message address (upper 28 bits) with channel number (lower 4 bits)
11+
12+
2.Check if Mailbox 0 status register’s full flag is set.
13+
14+
3.If not, then you can write to Mailbox 1 Read/Write register.
15+
16+
4.Check if Mailbox 0 status register’s empty flag is set.
17+
18+
5.If not, then you can read from Mailbox 0 Read/Write register.
19+
20+
6.Check if the value is the same as you wrote in step 1.
21+
*/
22+
int mailbox_call(){
23+
unsigned int addr =(((unsigned int)((unsigned long)&mailbox) & ~0xF) | (CHANNEL_8 & 0xF));
24+
while(1){
25+
if(*MAILBOX_STATUS != MAILBOX_FULL) break;
26+
}
27+
*MAILBOX_WRITE= addr;
28+
while(1){
29+
while(1){
30+
if(*MAILBOX_STATUS != MAILBOX_EMPTY) break;
31+
}
32+
33+
if(addr == *MAILBOX_READ) return 1;
34+
}
35+
36+
return 0;
37+
}
38+
39+
40+
void get_board_revision(unsigned int* revision){
41+
mailbox[0] = 7 * 4;
42+
mailbox[1] = REQUEST_CODE;
43+
mailbox[2] = GET_BOARD_REVISION;
44+
mailbox[3] = 4;
45+
mailbox[4] = TAG_REQUEST_CODE;
46+
mailbox[5] = 0;
47+
mailbox[6] = END_TAG;
48+
49+
mailbox_call();
50+
51+
*revision = mailbox[5];
52+
}
53+
54+
void get_arm_memory(unsigned int* base, unsigned int* size){
55+
mailbox[0] = 8 * 4;
56+
mailbox[1] = REQUEST_CODE;
57+
mailbox[2] = GET_ARM_MEMORY;
58+
mailbox[3] = 8;
59+
mailbox[4] = TAG_REQUEST_CODE;
60+
mailbox[5] = 0;
61+
mailbox[6] = 0;
62+
mailbox[7] = END_TAG;
63+
64+
mailbox_call();
65+
66+
*base = mailbox[5];
67+
*size = mailbox[6];
68+
}
69+
70+

0 commit comments

Comments
 (0)