First commit

This commit is contained in:
Daniil Gentili 2022-01-29 21:48:37 +01:00
commit 01af0bade1
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
11 changed files with 233 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.o
*.img
build

37
Makefile Normal file
View File

@ -0,0 +1,37 @@
ARMGNU ?= aarch64-linux-gnu
COPS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude -mgeneral-regs-only
ASMOPS = -Iinclude
BUILD_DIR = build
SRC_DIR = src
all: kernel8.img
install: all
udisksctl mount -b /dev/mmcblk0p1
cp kernel8.img /run/media/daniil/*/
umount /run/media/daniil/*
sync
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

6
include/mini_uart.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
void uart_init(void);
void uart_send(char c);
char uart_recv();
void uart_send_string(const char *str);

4
include/mm.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
// Lower memory limit at 4mb, kernel stack grows down back to 0 but we don't need much, 4mb is enough.
#define LOW_MEMORY (4 << 20)

22
include/reg.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#define BUS_OFFSET 0x3F000000
#define AUX_MU_IER_REG (0x7E215044 - BUS_OFFSET)
#define GPFSEL1 (0x7E200004 - BUS_OFFSET)
#define GPPUD (0x7E200094 - BUS_OFFSET)
#define GPPUDCLK0 (0x7E200098 - BUS_OFFSET)
#define AUX_ENABLES (0x7E215004 - BUS_OFFSET)
#define AUX_MU_CNTL_REG (0x7E215060 - BUS_OFFSET)
#define AUX_MU_IO_REG (0x7E215040 - BUS_OFFSET)
#define AUX_MU_IER_REG (0x7E215044 - BUS_OFFSET)
#define AUX_MU_IIR_REG (0x7E215048 - BUS_OFFSET)
#define AUX_MU_LCR_REG (0x7E21504c - BUS_OFFSET)
#define AUX_MU_MCR_REG (0x7E215050 - BUS_OFFSET)
#define AUX_MU_LSR_REG (0x7E215054 - BUS_OFFSET)
#define AUX_MU_BAUD_REG (0x7E215068 - BUS_OFFSET)
#define UART_BASE (0x7E201000-BUS_OFFSET)
#define ST_CLO (0x7e003004 - BUS_OFFSET)

6
include/utils.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
extern void put32(unsigned long reg, unsigned int value);
extern unsigned int get32(unsigned long reg);
extern void delay(unsigned long duration);

20
src/boot.S Normal file
View File

@ -0,0 +1,20 @@
#include "mm.h"
.section ".text.boot"
.globl _start
_start:
mrs x0, mpidr_el1 // Copy processor affinity register into x0
and x0, x0, #0xFF // Affinity 0 @ 0:7 is the core ID
cbnz x0, halt // Halt if core != 0
adr x0, bss_begin // Argument 1: bss_begin
adr x1, bss_end
sub x1, x1, x0 // Argument 2: bss_end-bss_begin
bl memzero // memzero(bss_begin, bss_end-bss_begin)
mov sp, #LOW_MEMORY // Initialize the kernel stack pointer to +4mb, growing downwards
bl kernel_main // kernel_main()
halt:
b halt

13
src/kernel.c Normal file
View File

@ -0,0 +1,13 @@
#include "mini_uart.h"
#include "reg.h"
#include "utils.h"
void kernel_main(void)
{
uart_init();
uart_send_string("Hello, world!\r\n");
while (1) {
uart_send(uart_recv());
}
}

11
src/linker.ld Normal file
View File

@ -0,0 +1,11 @@
SECTIONS
{
.text.boot : { *(.text.boot) }
.text : { *(.text) }
.rodata : { *(.rodata) }
.data : { *(.data) }
. = ALIGN(0x8);
bss_begin = .;
.bss : { *(.bss*) }
bss_end = .;
}

89
src/mini_uart.c Normal file
View File

@ -0,0 +1,89 @@
#include "mini_uart.h"
#include "reg.h"
#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_ICR (UART_BASE+0x44)
// UART clock baud rate divisor register
// Why is this undocumented??
#define CM_UARTDIV (0x7e1010f4-BUS_OFFSET)
// UART control register
// Why is this undocumented??
#define CM_UARTCTL 0x7e1010f0
// cucumber moment
#define CM_PASSWORD 0x5a000000
#define CM_SRC_OSC 1
#define CM_UARTCTL_FRAC_SET 0x00000200
#define CM_UARTCTL_ENAB_SET 0x00000010
void uart_init(void)
{
unsigned int selector;
selector = get32(GPFSEL1);
selector &= ~(7<<12); // clean gpio14
selector |= 4<<12; // set alt1 for gpio14
selector &= ~(7<<15); // clean gpio15
selector |= 4<<15; // set alt1 for gpio 15
put32(GPFSEL1,selector);
put32(UART_CR, 0);
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 its 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,270); //Set baud rate to 115200
put32(AUX_MU_CNTL_REG,3); //Finally, enable transmitter and receiver*/
put32(CM_UARTDIV, CM_PASSWORD | 0x6666);
put32(CM_UARTDIV, CM_PASSWORD | CM_SRC_OSC | CM_UARTCTL_FRAC_SET | CM_UARTCTL_ENAB_SET);
put32(UART_ICR, 0x7FF);
put32(UART_IBRD, 1);
put32(UART_FBRD, 40);
put32(UART_LCRH, 0x70);
put32(UART_CR, 0x301);
}
void uart_send(char c)
{
//while(!(get32(AUX_MU_LSR_REG) & 0x20));
//put32(AUX_MU_IO_REG, c);
while(get32(UART_FR) & 0x20);
put32(UART_DR, c);
}
char uart_recv()
{
//while (!(get32(AUX_MU_LSR_REG) & 0x1));
//return get32(AUX_MU_IO_REG) & 0xFF;
while(get32(UART_FR) & 0x10);
return put32(UART_DR) & 0xFF;
}
void uart_send_string(const char *str)
{
for (int i = 0; str[i] != '\0'; i++) {
uart_send(str[i]);
}
}

22
src/utils.S Normal file
View File

@ -0,0 +1,22 @@
.globl put32
put32:
str w1,[x0]
ret
.globl get32
get32:
ldr w0,[x0]
ret
.globl delay
delay:
subs x0, x0, #1
bne delay
ret
.globl memzero
memzero:
str xzr, [x0], #8
subs x1, x1, #8
b.gt memzero
ret