Skip to content

Commit

Permalink
Merge pull request s-matyukevich#189 from a-v-v/lesson01_exercises
Browse files Browse the repository at this point in the history
Exercises for lesson01
  • Loading branch information
s-matyukevich authored May 5, 2020
2 parents 3528600 + 837bbd6 commit 1e64c8f
Show file tree
Hide file tree
Showing 65 changed files with 958 additions and 0 deletions.
31 changes: 31 additions & 0 deletions exercises/lesson01/1/a-v-v/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ARMGNU ?= aarch64-linux-gnu

COPS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude -mgeneral-regs-only
ASMOPS = -Iinclude

BUILD_DIR = build
SRC_DIR = src

all : kernel8.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)

kernel8.img: $(SRC_DIR)/linker.ld $(OBJ_FILES)
$(ARMGNU)-ld -T $(SRC_DIR)/linker.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES)
$(ARMGNU)-objcopy $(BUILD_DIR)/kernel8.elf -O binary kernel8.img
1 change: 1 addition & 0 deletions exercises/lesson01/1/a-v-v/build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docker run --rm -v %cd%:/app -w /app smatyukevich/raspberry-pi-os-builder make %1
3 changes: 3 additions & 0 deletions exercises/lesson01/1/a-v-v/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker run --rm -v $(pwd):/app -w /app smatyukevich/raspberry-pi-os-builder make $1
9 changes: 9 additions & 0 deletions exercises/lesson01/1/a-v-v/include/mini_uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef _MINI_UART_H
#define _MINI_UART_H

void uart_init ( unsigned int baudrate );
char uart_recv ( void );
void uart_send ( char c );
void uart_send_string(char* str);

#endif /*_MINI_UART_H */
19 changes: 19 additions & 0 deletions exercises/lesson01/1/a-v-v/include/mm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef _MM_H
#define _MM_H

#define PAGE_SHIFT 12
#define TABLE_SHIFT 9
#define SECTION_SHIFT (PAGE_SHIFT + TABLE_SHIFT)

#define PAGE_SIZE (1 << PAGE_SHIFT)
#define SECTION_SIZE (1 << SECTION_SHIFT)

#define LOW_MEMORY (2 * SECTION_SIZE)

#ifndef __ASSEMBLER__

void memzero(unsigned long src, unsigned long n);

#endif

#endif /*_MM_H */
6 changes: 6 additions & 0 deletions exercises/lesson01/1/a-v-v/include/peripherals/base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _P_BASE_H
#define _P_BASE_H

#define PBASE 0x3F000000

#endif /*_P_BASE_H */
12 changes: 12 additions & 0 deletions exercises/lesson01/1/a-v-v/include/peripherals/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _P_GPIO_H
#define _P_GPIO_H

#include "peripherals/base.h"

#define GPFSEL1 (PBASE+0x00200004)
#define GPSET0 (PBASE+0x0020001C)
#define GPCLR0 (PBASE+0x00200028)
#define GPPUD (PBASE+0x00200094)
#define GPPUDCLK0 (PBASE+0x00200098)

#endif /*_P_GPIO_H */
19 changes: 19 additions & 0 deletions exercises/lesson01/1/a-v-v/include/peripherals/mini_uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef _P_MINI_UART_H
#define _P_MINI_UART_H

#include "peripherals/base.h"

#define AUX_ENABLES (PBASE+0x00215004)
#define AUX_MU_IO_REG (PBASE+0x00215040)
#define AUX_MU_IER_REG (PBASE+0x00215044)
#define AUX_MU_IIR_REG (PBASE+0x00215048)
#define AUX_MU_LCR_REG (PBASE+0x0021504C)
#define AUX_MU_MCR_REG (PBASE+0x00215050)
#define AUX_MU_LSR_REG (PBASE+0x00215054)
#define AUX_MU_MSR_REG (PBASE+0x00215058)
#define AUX_MU_SCRATCH (PBASE+0x0021505C)
#define AUX_MU_CNTL_REG (PBASE+0x00215060)
#define AUX_MU_STAT_REG (PBASE+0x00215064)
#define AUX_MU_BAUD_REG (PBASE+0x00215068)

#endif /*_P_MINI_UART_H */
8 changes: 8 additions & 0 deletions exercises/lesson01/1/a-v-v/include/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _BOOT_H
#define _BOOT_H

extern void delay ( unsigned long);
extern void put32 ( unsigned long, unsigned int );
extern unsigned int get32 ( unsigned long );

#endif /*_BOOT_H */
23 changes: 23 additions & 0 deletions exercises/lesson01/1/a-v-v/src/boot.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "mm.h"

.section ".text.boot"

.globl _start
_start:
mrs x0, mpidr_el1
and x0, x0,#0xFF // Check processor id
cbz x0, master // Hang for all non-primary CPU
b proc_hang

proc_hang:
b proc_hang

master:
adr x0, bss_begin
adr x1, bss_end
sub x1, x1, x0
bl memzero

mov sp, #LOW_MEMORY
bl kernel_main
b proc_hang // should never come here
2 changes: 2 additions & 0 deletions exercises/lesson01/1/a-v-v/src/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
kernel_old=1
disable_commandline_tags=1
12 changes: 12 additions & 0 deletions exercises/lesson01/1/a-v-v/src/kernel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "mini_uart.h"

void kernel_main(void)
{
const unsigned int baud_rate = 460800;
uart_init(baud_rate);
uart_send_string("Hello, world!\r\n");

while (1) {
uart_send(uart_recv());
}
}
11 changes: 11 additions & 0 deletions exercises/lesson01/1/a-v-v/src/linker.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
SECTIONS
{
.text.boot : { *(.text.boot) }
.text : { *(.text) }
.rodata : { *(.rodata) }
.data : { *(.data) }
. = ALIGN(0x8);
bss_begin = .;
.bss : { *(.bss*) }
bss_end = .;
}
56 changes: 56 additions & 0 deletions exercises/lesson01/1/a-v-v/src/mini_uart.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "utils.h"
#include "peripherals/mini_uart.h"
#include "peripherals/gpio.h"

void uart_send ( char c )
{
while(1) {
if(get32(AUX_MU_LSR_REG)&0x20)
break;
}
put32(AUX_MU_IO_REG,c);
}

char uart_recv ( void )
{
while(1) {
if(get32(AUX_MU_LSR_REG)&0x01)
break;
}
return(get32(AUX_MU_IO_REG)&0xFF);
}

void uart_send_string(char* str)
{
for (int i = 0; str[i] != '\0'; i ++) {
uart_send((char)str[i]);
}
}

void uart_init ( unsigned int baudrate )
{
unsigned int selector;
const unsigned int baudrate_reg = 31250000 / baudrate - 1;

selector = get32(GPFSEL1);
selector &= ~(7<<12); // clean gpio14
selector |= 2<<12; // set alt5 for gpio14
selector &= ~(7<<15); // clean gpio15
selector |= 2<<15; // set alt5 for gpio15
put32(GPFSEL1,selector);

put32(GPPUD,0);
delay(150);
put32(GPPUDCLK0,(1<<14)|(1<<15));
delay(150);
put32(GPPUDCLK0,0);

put32(AUX_ENABLES,1); //Enable mini uart (this also enables access to it registers)
put32(AUX_MU_CNTL_REG,0); //Disable auto flow control and disable receiver and transmitter (for now)
put32(AUX_MU_IER_REG,0); //Disable receive and transmit interrupts
put32(AUX_MU_LCR_REG,3); //Enable 8 bit mode
put32(AUX_MU_MCR_REG,0); //Set RTS line to be always high
put32(AUX_MU_BAUD_REG,baudrate_reg); //Set baud rate

put32(AUX_MU_CNTL_REG,3); //Finally, enable transmitter and receiver
}
6 changes: 6 additions & 0 deletions exercises/lesson01/1/a-v-v/src/mm.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.globl memzero
memzero:
str xzr, [x0], #8
subs x1, x1, #8
b.gt memzero
ret
15 changes: 15 additions & 0 deletions exercises/lesson01/1/a-v-v/src/utils.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.globl put32
put32:
str w1,[x0]
ret

.globl get32
get32:
ldr w0,[x0]
ret

.globl delay
delay:
subs x0, x0, #1
bne delay
ret
31 changes: 31 additions & 0 deletions exercises/lesson01/2/a-v-v/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ARMGNU ?= aarch64-linux-gnu

COPS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude -mgeneral-regs-only
ASMOPS = -Iinclude

BUILD_DIR = build
SRC_DIR = src

all : kernel8.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)

kernel8.img: $(SRC_DIR)/linker.ld $(OBJ_FILES)
$(ARMGNU)-ld -T $(SRC_DIR)/linker.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES)
$(ARMGNU)-objcopy $(BUILD_DIR)/kernel8.elf -O binary kernel8.img
1 change: 1 addition & 0 deletions exercises/lesson01/2/a-v-v/build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docker run --rm -v %cd%:/app -w /app smatyukevich/raspberry-pi-os-builder make %1
3 changes: 3 additions & 0 deletions exercises/lesson01/2/a-v-v/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

docker run --rm -v $(pwd):/app -w /app smatyukevich/raspberry-pi-os-builder make $1
19 changes: 19 additions & 0 deletions exercises/lesson01/2/a-v-v/include/mm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef _MM_H
#define _MM_H

#define PAGE_SHIFT 12
#define TABLE_SHIFT 9
#define SECTION_SHIFT (PAGE_SHIFT + TABLE_SHIFT)

#define PAGE_SIZE (1 << PAGE_SHIFT)
#define SECTION_SIZE (1 << SECTION_SHIFT)

#define LOW_MEMORY (2 * SECTION_SIZE)

#ifndef __ASSEMBLER__

void memzero(unsigned long src, unsigned long n);

#endif

#endif /*_MM_H */
6 changes: 6 additions & 0 deletions exercises/lesson01/2/a-v-v/include/peripherals/base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _P_BASE_H
#define _P_BASE_H

#define PBASE 0x3F000000

#endif /*_P_BASE_H */
12 changes: 12 additions & 0 deletions exercises/lesson01/2/a-v-v/include/peripherals/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _P_GPIO_H
#define _P_GPIO_H

#include "peripherals/base.h"

#define GPFSEL1 (PBASE+0x00200004)
#define GPSET0 (PBASE+0x0020001C)
#define GPCLR0 (PBASE+0x00200028)
#define GPPUD (PBASE+0x00200094)
#define GPPUDCLK0 (PBASE+0x00200098)

#endif /*_P_GPIO_H */
17 changes: 17 additions & 0 deletions exercises/lesson01/2/a-v-v/include/peripherals/uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef _P_UART_H
#define _P_UART_H

#include "peripherals/base.h"

#define UART_BASE (PBASE + 0x201000)

#define UART_DR (UART_BASE + 0x0)
#define UART_FR (UART_BASE + 0x18)
#define UART_IBRD (UART_BASE + 0x24)
#define UART_FBRD (UART_BASE + 0x28)
#define UART_LCRH (UART_BASE + 0x2c)
#define UART_CR (UART_BASE + 0x30)

#define UART_CLK_HZ 48000000

#endif /*_P_UART_H */
9 changes: 9 additions & 0 deletions exercises/lesson01/2/a-v-v/include/uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef _UART_H
#define _UART_H

void uart_init ( void );
char uart_recv ( void );
void uart_send ( char c );
void uart_send_string(char* str);

#endif /*_UART_H */
8 changes: 8 additions & 0 deletions exercises/lesson01/2/a-v-v/include/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _BOOT_H
#define _BOOT_H

extern void delay ( unsigned long);
extern void put32 ( unsigned long, unsigned int );
extern unsigned int get32 ( unsigned long );

#endif /*_BOOT_H */
23 changes: 23 additions & 0 deletions exercises/lesson01/2/a-v-v/src/boot.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "mm.h"

.section ".text.boot"

.globl _start
_start:
mrs x0, mpidr_el1
and x0, x0,#0xFF // Check processor id
cbz x0, master // Hang for all non-primary CPU
b proc_hang

proc_hang:
b proc_hang

master:
adr x0, bss_begin
adr x1, bss_end
sub x1, x1, x0
bl memzero

mov sp, #LOW_MEMORY
bl kernel_main
b proc_hang // should never come here
2 changes: 2 additions & 0 deletions exercises/lesson01/2/a-v-v/src/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
kernel_old=1
disable_commandline_tags=1
Loading

0 comments on commit 1e64c8f

Please sign in to comment.