forked from s-matyukevich/raspberry-pi-os
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request s-matyukevich#223 from szediwy/master
Solved lesson 01 exercise 3 for Raspberry Pi 4B
- Loading branch information
Showing
16 changed files
with
381 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
ARMGNU ?= aarch64-linux-gnu | ||
|
||
COPS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude -mgeneral-regs-only | ||
ASMOPS = -Iinclude | ||
|
||
BUILD_DIR = build | ||
SRC_DIR = src | ||
|
||
.PHONY: clean | ||
|
||
all : kernel8.img | ||
|
||
clean : | ||
rm -rf $(BUILD_DIR) *.img | ||
@echo "clean: [SUCCESS]" | ||
|
||
$(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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ( void ); | ||
char uart_recv ( void ); | ||
void uart_send ( char c ); | ||
void uart_send_string(char* str); | ||
|
||
#endif /*_MINI_UART_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef _P_BASE_H | ||
#define _P_BASE_H | ||
|
||
// #define PBASE 0x3F000000 | ||
// So a peripheral described in this document as being at legacy address 0x7Enn_nnnn is available in the 35-bit address | ||
// space at 0x4_7Enn_nnnn, and visible to the ARM at 0x0_FEnn_nnnn if Low Peripheral mode is enabled. | ||
// 0x7E000000 (legacy) -> 0x4_7E00_0000 (35-bit) -> 0x0_FE00_0000 (low peripheral) | ||
#define PBASE 0xFE000000 | ||
|
||
#endif /*_P_BASE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#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) | ||
#define GPIO_PUP_PDN_CNTRL_REG0 (PBASE+0x002000E4) | ||
#define UART0_DR (PBASE+0x00201000) | ||
#define UART0_FR (PBASE+0x00201018) | ||
#define UART0_IBRD (PBASE+0x00201024) | ||
#define UART0_FBRD (PBASE+0x00201028) | ||
#define UART0_LCRH (PBASE+0x0020102C) | ||
#define UART0_CR (PBASE+0x00201030) | ||
#define UART0_IMSC (PBASE+0x00201038) | ||
|
||
#endif /*_P_GPIO_H */ |
19 changes: 19 additions & 0 deletions
19
exercises/lesson01/3/szediwy/include/peripherals/mini_uart.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
#include "mm.h" | ||
|
||
.section ".text.boot" | ||
|
||
.globl _start | ||
_start: | ||
mrs x0, mpidr_el1 | ||
and x0, x0, #0x3 | ||
cbz x0, init_bss | ||
/* If processor id is not 0 then pending lock processor | ||
* (wait for `sev` instruction) | ||
*/ | ||
wfe | ||
b master | ||
|
||
proc_hang: | ||
b proc_hang | ||
|
||
init_bss: | ||
adr x0, bss_begin | ||
adr x1, bss_end | ||
sub x1, x1, x0 | ||
bl memzero | ||
|
||
sev | ||
|
||
/***********************************************************************/ | ||
/* Enable the other cores | ||
link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm64/booting.rst?h=v5.3#n255 | ||
The boot loader is expected to enter the kernel on each CPU in the | ||
following manner: | ||
- The primary CPU must jump directly to the first instruction of the | ||
kernel image. The device tree blob passed by this CPU must contain | ||
an 'enable-method' property for each cpu node. The supported | ||
enable-methods are described below. | ||
It is expected that the bootloader will generate these device tree | ||
properties and insert them into the blob prior to kernel entry. | ||
- CPUs with a "spin-table" enable-method must have a 'cpu-release-addr' | ||
property in their cpu node. This property identifies a | ||
naturally-aligned 64-bit zero-initalised memory location. | ||
These CPUs should spin outside of the kernel in a reserved area of | ||
memory (communicated to the kernel by a /memreserve/ region in the | ||
device tree) polling their cpu-release-addr location, which must be | ||
contained in the reserved region. A wfe instruction may be inserted | ||
to reduce the overhead of the busy-loop and a sev will be issued by | ||
the primary CPU. When a read of the location pointed to by the | ||
cpu-release-addr returns a non-zero value, the CPU must jump to this | ||
value. The value will be written as a single 64-bit little-endian | ||
value, so CPUs must convert the read value to their native endianness | ||
before jumping to it. | ||
- CPUs with a "psci" enable method should remain outside of | ||
the kernel (i.e. outside of the regions of memory described to the | ||
kernel in the memory node, or in a reserved area of memory described | ||
to the kernel by a /memreserve/ region in the device tree). The | ||
kernel will issue CPU_ON calls as described in ARM document number ARM | ||
DEN 0022A ("Power State Coordination Interface System Software on ARM | ||
processors") to bring CPUs into the kernel. | ||
The device tree should contain a 'psci' node, as described in | ||
Documentation/devicetree/bindings/arm/psci.yaml. | ||
- Secondary CPU general-purpose register settings | ||
x0 = 0 (reserved for future use) | ||
x1 = 0 (reserved for future use) | ||
x2 = 0 (reserved for future use) | ||
x3 = 0 (reserved for future use) | ||
*/ | ||
|
||
/* cpu0: cpu@0 { | ||
device_type = "cpu"; | ||
compatible = "arm,cortex-a72"; | ||
reg = <0>; | ||
enable-method = "spin-table"; | ||
cpu-release-addr = <0x0 0x000000d8>; | ||
}; | ||
cpu1: cpu@1 { | ||
device_type = "cpu"; | ||
compatible = "arm,cortex-a72"; | ||
reg = <1>; | ||
enable-method = "spin-table"; | ||
cpu-release-addr = <0x0 0x000000e0>; | ||
}; | ||
cpu2: cpu@2 { | ||
device_type = "cpu"; | ||
compatible = "arm,cortex-a72"; | ||
reg = <2>; | ||
enable-method = "spin-table"; | ||
cpu-release-addr = <0x0 0x000000e8>; | ||
}; | ||
cpu3: cpu@3 { | ||
device_type = "cpu"; | ||
compatible = "arm,cortex-a72"; | ||
reg = <3>; | ||
enable-method = "spin-table"; | ||
cpu-release-addr = <0x0 0x000000f0>; | ||
}; */ | ||
/****************************************************/ | ||
mov x0, #0 | ||
adr x0, master | ||
|
||
mov x1, #0xe0 | ||
str x0, [x1] | ||
mov x1, #0xe8 | ||
str x0, [x1] | ||
mov x1, #0xf0 | ||
str x0, [x1] | ||
|
||
master: | ||
mrs x0, mpidr_el1 | ||
and x0, x0, #0x3 | ||
|
||
mov x1, #SECTION_SIZE | ||
mul x1, x1, x0 | ||
add x1, x1, #LOW_MEMORY | ||
mov sp, x1 | ||
|
||
bl kernel_main | ||
b proc_hang |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
arm_64bit=1 | ||
enable_uart=1 | ||
uart_2ndstage=1 | ||
disable_commandline_tags=1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#include "mini_uart.h" | ||
|
||
void kernel_main(unsigned long processor_index) | ||
{ | ||
static unsigned int current_processor_index = 0; | ||
|
||
if (processor_index == 0) { | ||
uart_init(); | ||
} | ||
|
||
while (processor_index != current_processor_index) | ||
; | ||
|
||
uart_send_string("Hello from processor "); | ||
uart_send(processor_index + '0'); | ||
uart_send_string("!\r\n"); | ||
|
||
current_processor_index++; | ||
|
||
if (processor_index == 0) { | ||
// if current_processor_index == 4 then all processors send message | ||
while (current_processor_index != 4) | ||
; | ||
for (;;) { | ||
uart_send(uart_recv()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 = .; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#include "utils.h" | ||
#include "peripherals/mini_uart.h" | ||
#include "peripherals/gpio.h" | ||
|
||
void uart_send(char c) | ||
{ | ||
while (get32(UART0_FR) & (1 << 5)) | ||
{ | ||
} | ||
put32(UART0_DR, c); | ||
} | ||
|
||
char uart_recv(void) | ||
{ | ||
while (get32(UART0_FR) & (1 << 4)) | ||
{ | ||
} | ||
return (get32(UART0_DR) & 0xFF); | ||
} | ||
|
||
void uart_send_string(char *str) | ||
{ | ||
for (int i = 0; str[i] != '\0'; i++) | ||
{ | ||
uart_send((char)str[i]); | ||
} | ||
} | ||
|
||
void uart_init(void) | ||
{ | ||
|
||
unsigned int selector; | ||
|
||
selector = get32(GPFSEL1); | ||
selector &= ~(7 << 12); // clean gpio14 | ||
selector |= 4 << 12; // set alt5 for gpio14 | ||
selector &= ~(7 << 15); // clean gpio15 | ||
selector |= 4 << 15; // set alt5 for gpio15 | ||
put32(GPFSEL1, selector); | ||
|
||
unsigned int pullRegister; | ||
pullRegister = get32(GPIO_PUP_PDN_CNTRL_REG0); | ||
pullRegister &= ~(3 << 30); | ||
pullRegister &= ~(3 << 28); | ||
put32(GPIO_PUP_PDN_CNTRL_REG0, pullRegister); | ||
|
||
//first disable uart | ||
put32(UART0_CR, 0); | ||
put32(UART0_IMSC, 0); | ||
|
||
//from ../adkaster/src/uart.c | ||
// Assume 48MHz UART Reference Clock (Standard) | ||
// Calculate UART clock divider per datasheet | ||
// BAUDDIV = (FUARTCLK/(16 Baud rate)) | ||
// Note: We get 6 bits of fraction for the baud div | ||
// 48000000/(16 * 115200) = 3000000/115200 = 26.0416666... | ||
// Integer part = 26 :) | ||
// From http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0183g/I54603.html | ||
// we want floor(0.04166666.. * 64 + 0.5) = 3 | ||
put32(UART0_IBRD, 26); | ||
put32(UART0_FBRD, 3); | ||
|
||
//little endian: 0111|0000 => 8 bits and enable fifos | ||
put32(UART0_LCRH, 7 << 4); | ||
//little endian: 0011|0000|0001 => enable: rx tx uart | ||
put32(UART0_CR, (1 << 9) | (1 << 8) | (1 << 0)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |