Skip to content

Commit 3b3fc8d

Browse files
Merge pull request #121 from gcrisis/master
complete exercise 1,2,3 in lesson01
2 parents f6e491d + f194969 commit 3b3fc8d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+737
-0
lines changed

exercises/lesson01/1/gcrisis/Makefile

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
ARMGNU ?= aarch64-linux-gnu
2+
3+
COPS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude -mgeneral-regs-only
4+
ASMOPS = -Iinclude
5+
6+
BUILD_DIR = build
7+
SRC_DIR = src
8+
9+
all : kernel8.img
10+
11+
clean:
12+
rm -rf $(BUILD_DIR) *.img
13+
14+
$(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c
15+
mkdir -p $(@D)
16+
$(ARMGNU)-gcc $(COPS) -MMD -c $< -o $@
17+
18+
$(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S
19+
$(ARMGNU)-gcc $(ASMOPS) -MMD -c $< -o $@
20+
21+
C_FILES = $(wildcard $(SRC_DIR)/*.c)
22+
ASM_FILES = $(wildcard $(SRC_DIR)/*.S)
23+
OBJ_FILES = $(C_FILES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%_c.o)
24+
OBJ_FILES += $(ASM_FILES:$(SRC_DIR)/%.S=$(BUILD_DIR)/%_s.o)
25+
26+
DEP_FILES = $(OBJ_FILES:%.o=%.d)
27+
-include $(DEP_FILES)
28+
29+
kernel8.img: $(SRC_DIR)/linker.ld $(OBJ_FILES)
30+
$(ARMGNU)-ld -T $(SRC_DIR)/linker.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES)
31+
$(ARMGNU)-objcopy $(BUILD_DIR)/kernel8.elf -O binary kernel8.img
32+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef _MINI_UART_H
2+
#define _MINI_UART_H
3+
4+
void uart_init (int baudrate );
5+
char uart_recv ( void );
6+
void uart_send ( char c );
7+
void uart_send_string(char* str);
8+
9+
#endif /*_MINI_UART_H */
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef _MM_H
2+
#define _MM_H
3+
4+
#define PAGE_SHIFT 12
5+
#define TABLE_SHIFT 9
6+
#define SECTION_SHIFT (PAGE_SHIFT + TABLE_SHIFT)
7+
8+
#define PAGE_SIZE (1 << PAGE_SHIFT)
9+
#define SECTION_SIZE (1 << SECTION_SHIFT)
10+
11+
#define LOW_MEMORY (2 * SECTION_SIZE)
12+
13+
#ifndef __ASSEMBLER__
14+
15+
void memzero(unsigned long src, unsigned long n);
16+
17+
#endif
18+
19+
#endif /*_MM_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef _P_BASE_H
2+
#define _P_BASE_H
3+
4+
#define PBASE 0x3F000000
5+
6+
#endif /*_P_BASE_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef _P_GPIO_H
2+
#define _P_GPIO_H
3+
4+
#include "peripherals/base.h"
5+
6+
#define GPFSEL1 (PBASE+0x00200004)
7+
#define GPSET0 (PBASE+0x0020001C)
8+
#define GPCLR0 (PBASE+0x00200028)
9+
#define GPPUD (PBASE+0x00200094)
10+
#define GPPUDCLK0 (PBASE+0x00200098)
11+
12+
#endif /*_P_GPIO_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef _P_MINI_UART_H
2+
#define _P_MINI_UART_H
3+
4+
#include "peripherals/base.h"
5+
6+
#define AUX_ENABLES (PBASE+0x00215004)
7+
#define AUX_MU_IO_REG (PBASE+0x00215040)
8+
#define AUX_MU_IER_REG (PBASE+0x00215044)
9+
#define AUX_MU_IIR_REG (PBASE+0x00215048)
10+
#define AUX_MU_LCR_REG (PBASE+0x0021504C)
11+
#define AUX_MU_MCR_REG (PBASE+0x00215050)
12+
#define AUX_MU_LSR_REG (PBASE+0x00215054)
13+
#define AUX_MU_MSR_REG (PBASE+0x00215058)
14+
#define AUX_MU_SCRATCH (PBASE+0x0021505C)
15+
#define AUX_MU_CNTL_REG (PBASE+0x00215060)
16+
#define AUX_MU_STAT_REG (PBASE+0x00215064)
17+
#define AUX_MU_BAUD_REG (PBASE+0x00215068)
18+
19+
#endif /*_P_MINI_UART_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef _BOOT_H
2+
#define _BOOT_H
3+
4+
extern void delay ( unsigned long);
5+
extern void put32 ( unsigned long, unsigned int );
6+
extern unsigned int get32 ( unsigned long );
7+
8+
#endif /*_BOOT_H */
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "mm.h"
2+
3+
.section ".text.boot"
4+
5+
.globl _start
6+
_start:
7+
mrs x0, mpidr_el1
8+
and x0, x0,#0xFF // Check processor id
9+
cbz x0, master // Hang for all non-primary CPU
10+
b proc_hang
11+
12+
proc_hang:
13+
b proc_hang
14+
15+
master:
16+
adr x0, bss_begin
17+
adr x1, bss_end
18+
sub x1, x1, x0
19+
bl memzero
20+
21+
mov sp, #LOW_MEMORY
22+
bl kernel_main
23+
b proc_hang // should never come here
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
kernel_old=1
2+
disable_commandline_tags=1
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "mini_uart.h"
2+
3+
void kernel_main(void)
4+
{
5+
uart_init(9600);
6+
uart_send_string("Hello, world!\r\n");
7+
8+
while (1) {
9+
uart_send(uart_recv());
10+
}
11+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
SECTIONS
2+
{
3+
.text.boot : { *(.text.boot)}
4+
.text :{ *(.text)}
5+
.rodata : {*(.rodata) }
6+
.data : {*(.data) }
7+
. = ALIGN(0x8);
8+
bss_begin =.;
9+
.bss : {*(.bss*) }
10+
bss_end =.;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include "utils.h"
2+
#include "peripherals/mini_uart.h"
3+
#include "peripherals/gpio.h"
4+
5+
#define BAUD_REG_VAL(baud_rate) ((250000000/(baud_rate)/8-1)&0x0000ffff)
6+
7+
void uart_send ( char c )
8+
{
9+
while(1) {
10+
if(get32(AUX_MU_LSR_REG)&0x20)
11+
break;
12+
}
13+
put32(AUX_MU_IO_REG,c);
14+
}
15+
16+
char uart_recv ( void )
17+
{
18+
while(1) {
19+
if(get32(AUX_MU_LSR_REG)&0x01)
20+
break;
21+
}
22+
return(get32(AUX_MU_IO_REG)&0xFF);
23+
}
24+
25+
void uart_send_string(char* str)
26+
{
27+
for (int i = 0; str[i] != '\0'; i ++) {
28+
uart_send((char)str[i]);
29+
}
30+
}
31+
32+
void uart_init (int baudrate )
33+
{
34+
unsigned int selector;
35+
36+
selector = get32(GPFSEL1);
37+
selector &= ~(7<<12); // clean gpio14
38+
selector |= 2<<12; // set alt5 for gpio14
39+
selector &= ~(7<<15); // clean gpio15
40+
selector |= 2<<15; // set alt5 for gpio15
41+
put32(GPFSEL1,selector);
42+
43+
put32(GPPUD,0);
44+
delay(150);
45+
put32(GPPUDCLK0,(1<<14)|(1<<15));
46+
delay(150);
47+
put32(GPPUDCLK0,0);
48+
49+
put32(AUX_ENABLES,1); //Enable mini uart (this also enables access to it registers)
50+
put32(AUX_MU_CNTL_REG,0); //Disable auto flow control and disable receiver and transmitter (for now)
51+
put32(AUX_MU_IER_REG,0); //Disable receive and transmit interrupts
52+
put32(AUX_MU_LCR_REG,3); //Enable 8 bit mode
53+
put32(AUX_MU_MCR_REG,0); //Set RTS line to be always high
54+
put32(AUX_MU_BAUD_REG,(int)BAUD_REG_VAL(baudrate)); //Set baud rate to baudrate
55+
56+
put32(AUX_MU_CNTL_REG,3); //Finally, enable transmitter and receiver
57+
}

exercises/lesson01/1/gcrisis/src/mm.S

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.globl memzero
2+
memzero:
3+
str xzr, [x0], #8
4+
subs x1, x1, #8
5+
b.gt memzero
6+
ret
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.globl put32
2+
put32:
3+
str w1,[x0]
4+
ret
5+
6+
.globl get32
7+
get32:
8+
ldr w0,[x0]
9+
ret
10+
11+
.globl delay
12+
delay:
13+
subs x0, x0, #1
14+
bne delay
15+
ret

exercises/lesson01/2/gcrisis/Makefile

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
ARMGNU ?= aarch64-linux-gnu
2+
3+
COPS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude
4+
ASMOPS = -Iinclude
5+
6+
BUILD_DIR = build
7+
SRC_DIR = src
8+
9+
all : kernel8.img
10+
11+
clean:
12+
rm -rf $(BUILD_DIR) *.img
13+
14+
$(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c
15+
mkdir -p $(@D)
16+
$(ARMGNU)-gcc $(COPS) -MMD -c $< -o $@
17+
18+
$(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S
19+
$(ARMGNU)-gcc $(ASMOPS) -MMD -c $< -o $@
20+
21+
C_FILES = $(wildcard $(SRC_DIR)/*.c)
22+
ASM_FILES = $(wildcard $(SRC_DIR)/*.S)
23+
OBJ_FILES = $(C_FILES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%_c.o)
24+
OBJ_FILES += $(ASM_FILES:$(SRC_DIR)/%.S=$(BUILD_DIR)/%_s.o)
25+
26+
DEP_FILES = $(OBJ_FILES:%.o=%.d)
27+
-include $(DEP_FILES)
28+
29+
kernel8.img: $(SRC_DIR)/linker.ld $(OBJ_FILES)
30+
$(ARMGNU)-ld -T $(SRC_DIR)/linker.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES)
31+
$(ARMGNU)-objcopy $(BUILD_DIR)/kernel8.elf -O binary kernel8.img
32+
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef _MM_H
2+
#define _MM_H
3+
4+
#define PAGE_SHIFT 12
5+
#define TABLE_SHIFT 9
6+
#define SECTION_SHIFT (PAGE_SHIFT + TABLE_SHIFT)
7+
8+
#define PAGE_SIZE (1 << PAGE_SHIFT)
9+
#define SECTION_SIZE (1 << SECTION_SHIFT)
10+
11+
#define LOW_MEMORY (2 * SECTION_SIZE)
12+
13+
#ifndef __ASSEMBLER__
14+
15+
void memzero(unsigned long src, unsigned long n);
16+
17+
#endif
18+
19+
#endif /*_MM_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef _P_BASE_H
2+
#define _P_BASE_H
3+
4+
#define PBASE 0x3F000000
5+
6+
#endif /*_P_BASE_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef _P_GPIO_H
2+
#define _P_GPIO_H
3+
4+
#include "peripherals/base.h"
5+
6+
#define GPFSEL1 (PBASE+0x00200004)
7+
#define GPSET0 (PBASE+0x0020001C)
8+
#define GPCLR0 (PBASE+0x00200028)
9+
#define GPPUD (PBASE+0x00200094)
10+
#define GPPUDCLK0 (PBASE+0x00200098)
11+
12+
#endif /*_P_GPIO_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef _P_UART_H
2+
#define _P_UART_H
3+
4+
#include "peripherals/base.h"
5+
6+
#define UART_DR (PBASE+0x00201000)
7+
#define UART_RSRECR (PBASE+0x00201004)
8+
#define UART_FR (PBASE+0x00201018)
9+
#define UART_IBRD (PBASE+0x00201024)
10+
#define UART_FBRD (PBASE+0x00201028)
11+
#define UART_LCRH (PBASE+0x0020102C)
12+
#define UART_CR (PBASE+0x00201030)
13+
#define UART_IFLS (PBASE+0x00201034)
14+
#define UART_IMSC (PBASE+0x00201038)
15+
#define UART_RIS (PBASE+0x0020103C)
16+
#define UART_MIS (PBASE+0x00201040)
17+
#define UART_ICR (PBASE+0x00201044)
18+
#define UART_DMACR (PBASE+0x00201048)
19+
#define UART_ITCR (PBASE+0x00201080)
20+
#define UART_ITIP (PBASE+0x00201084)
21+
#define UART_ITOP (PBASE+0x00201088)
22+
#define UART_TDR (PBASE+0x0020108C)
23+
24+
#endif /*_P_UART_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef _UART_H
2+
#define _UART_H
3+
4+
void uart_init (int baudrate);
5+
char uart_recv ( void );
6+
void uart_send ( char c );
7+
void uart_send_string(char* str);
8+
9+
#endif /*_UART_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef _BOOT_H
2+
#define _BOOT_H
3+
4+
extern void delay ( unsigned long);
5+
extern void put32 ( unsigned long, unsigned int );
6+
extern unsigned int get32 ( unsigned long );
7+
8+
#endif /*_BOOT_H */
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "mm.h"
2+
3+
.section ".text.boot"
4+
5+
.globl _start
6+
_start:
7+
mrs x0, mpidr_el1
8+
and x0, x0,#0xFF // Check processor id
9+
cbz x0, master // Hang for all non-primary CPU
10+
b proc_hang
11+
12+
proc_hang:
13+
b proc_hang
14+
15+
master:
16+
adr x0, bss_begin
17+
adr x1, bss_end
18+
sub x1, x1, x0
19+
bl memzero
20+
21+
mov sp, #LOW_MEMORY
22+
bl kernel_main
23+
b proc_hang // should never come here
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
kernel_old=1
2+
disable_commandline_tags=1
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "uart.h"
2+
3+
void kernel_main(void)
4+
{
5+
uart_init(115200);
6+
uart_send_string("Hello, world!\r\n");
7+
8+
while (1) {
9+
uart_send(uart_recv());
10+
}
11+
}

0 commit comments

Comments
 (0)