diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..15aea07 --- /dev/null +++ b/Makefile @@ -0,0 +1,86 @@ +# environment + +AARCH64_TOOLCHAIN ?= aarch64-linux-gnu + + +# Shortcuts + +CC=clang --target=aarch64-none-elf -mcpu=cortex-a57 +# CC=$(AARCH64_TOOLCHAIN)-gcc +LD=$(AARCH64_TOOLCHAIN)-ld +OBJCOPY=$(AARCH64_TOOLCHAIN)-objcopy --target elf64-littleaarch64 + +CFLAGS += -O0 +CFLAGS += -g +CFLAGS += -nostdlib +CFLAGS += -march=armv8-a +#CFLAGS += -std=c99 +#CFLAGS += -pedantic +#CFLAGS += -Wall +#CFLAGS += -Wmissing-prototypes +#CFLAGS += -Wstrict-prototypes +#CFLAGS += -Wold-style-definition + +BUILD_DIR=build + + +# Files + +KERNEL_MEMMAP = sys/memmap + +KERNEL_SOURCES = \ + aarch64/boot.s \ + sys/main.c \ + sys/uart.c \ + +KERNEL_LIST := $(wildcard $(KERNEL_SOURCES)) +KERNEL_OBJS := $(addsuffix .o, $(addprefix $(BUILD_DIR)/, ${KERNEL_LIST})) + +all: kernel + + +# compilation + +kernel: $(BUILD_DIR)/kernel.elf # $(BUILD_DIR)/kernel.sym + +$(BUILD_DIR)/kernel.elf: $(KERNEL_OBJS) + $(info linking target: $@) + $(LD) -T$(KERNEL_MEMMAP) $^ -o $@ + $(info done: $@) + +$(BUILD_DIR)/kernel.bin: $(BUILD_DIR)/kernel.elf + $(OBJCOPY) -O binary $< $@ + +$(BUILD_DIR)/kernel.sym: $(BUILD_DIR)/kernel.elf + $(OBJCOPY) --only-keep-debug $< $@ + $(OBJCOPY) --strip-debug $@ + +$(BUILD_DIR)/%.o: % + $(info compiling file: $<) + @mkdir -p $(dir ./$(BUILD_DIR)/$<) + $(CC) $(CFLAGS) -c $< -o $@ + + +.PHONY: clean run + +# helpers +QEMU_CMD = \ + qemu-system-aarch64 \ + -cpu cortex-a57 \ + -machine type=virt \ + -nographic \ + -smp 4 \ + -m 4098 \ + -kernel build/kernel.elf \ + -serial stdio \ + -monitor none + +clean: + rm -Rf ./$(BUILD_DIR)/* + +run: kernel + $(QEMU_CMD) + + +debug: kernel + $(QEMU_CMD) -gdb tcp::1234 -S diff --git a/aarch64/boot.S b/aarch64/boot.S new file mode 100644 index 0000000..8a0fb75 --- /dev/null +++ b/aarch64/boot.S @@ -0,0 +1,22 @@ + .global _boot + .extern k_main + + +_boot: + mrs x0, mpidr_el1 // Check CPU ID + mov x1, 0xC1000000 + bic x0, x0, x1 + cbz x0, set_stack + b idle + +set_stack: + ldr x30, =0x40001000 + mov sp, x30 + bl start + +start: + mov x0, x30 + bl k_main + +idle: b idle + diff --git a/aarch64/boot.s b/aarch64/boot.s new file mode 100644 index 0000000..9406bfe --- /dev/null +++ b/aarch64/boot.s @@ -0,0 +1,25 @@ + .text + + .globl _start + .extern k_main + .extern stack_ptr + +_start: + mrs x0, mpidr_el1 // Check CPU ID + mov x1, 0xC1000000 + bic x0, x0, x1 + cbz x0, set_stack + b idle + +set_stack: + ldr x30, stack_ptr // defined in sys/memmap + mov sp, x30 + bl start + +start: + mov x0, x30 + bl k_main + +idle: + b idle + diff --git a/kernel/arm64/Makefile b/kernel/arm64/Makefile deleted file mode 100644 index 0d06677..0000000 --- a/kernel/arm64/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -ASM=clang -TARGET=aarch64-none-elf -CPU=cortex-a57 -LD=ld.lld -OBJCOPY=objcopy --target elf64-littleaarch64 - -all: build/core.bin build/core.elf - -# compilation ----------------------------------------------------------------- - -build/core.o: core/core.s - $(ASM) -c -triple --target=$(TARGET) -mcpu=$(CPU) -O0 -g $< -o $@ - -build/uart.o: core/uart.s - $(ASM) -c --target=$(TARGET) -mcpu=$(CPU) -O0 -g $< -o $@ - -# ELF ------------------------------------------------------------------------- - -build/core.elf: build/core.o build/uart.o - $(LD) -Tcore/core.ld $^ -o $@ - -# BIN ------------------------------------------------------------------------- - -build/core.bin: build/core.elf - $(OBJCOPY) -O binary $< $@ - -build/core.sym: build/core.elf - $(OBJCOPY) --only-keep-debug $< $@ - $(OBJCOPY) --strip-debug build/core.elf - -# Clean ----------------------------------------------------------------------- - -clean: - rm -f build/* diff --git a/kernel/arm64/core.ld b/kernel/arm64/core.ld deleted file mode 100644 index e59786f..0000000 --- a/kernel/arm64/core.ld +++ /dev/null @@ -1,12 +0,0 @@ -ENTRY(_core_init) - -SECTIONS -{ - . = 0x40000000; - .text : { *(.text) } - .data : { *(.text) } - .bss : { *(.bss COMMON) } - . = ALIGN(10); - . = . + 0x1000; - stack_ptr = . ; -} diff --git a/kernel/arm64/uart.s b/kernel/arm64/uart.s deleted file mode 100644 index 1bceca7..0000000 --- a/kernel/arm64/uart.s +++ /dev/null @@ -1,93 +0,0 @@ -# file : uart.s -# project : Löwe OS -# authors : Elias Löwe - -# address of UART for virt device in qemu - -# ----------------------------------------------------------------------------- - - .global _uart_putc # print single character uart - .global _uart_putx # print integer in HEX format to uart - .global _uart_puts # print null-terminated string to uart - -# ----------------------------------------------------------------------------- - - .text - -# helper to avoid extra data moving -# @x1 character print -uart_putc: - STP x2, lr, [sp, -16]! - - MOV x2, 0x09000000 # set UART address - STRB w1, [x2] # put character out - - LDP x2, lr, [sp], 16 - RET - -# ----------------------------------------------------------------------------- - - -# print character to uart -# @x0 character print -_uart_putc: - STR lr, [sp, -16]! - - MOV x1, x0 # set arguments - BL uart_putc # put character out - - LDR lr, [sp], 16 - RET - - -# ----------------------------------------------------------------------------- - -# @x0 integer to print -_uart_putx: - STP lr, x3, [sp, -32]! - STP x0, x1, [sp, 16] - - LDR x3, =60 # init bits counter 64-4 - -1: - LSR x1, x0, x3 # shift to digit - AND x1, x1, 0xF # keep only digit - CMP x1, 9 # compare it to 9 - BLS 2f # less or equal - ADD x1, x1, 0x37 # turn into ASCII HEX char - B 3f # continue to output - -2: - ADD x1, x1, 0x30 # turn into ASCII num char - -3: - BL uart_putc # output carachter - CBZ x3, 0f # if counter == 0 return - SUB x3, x3, 4 # otherwise subtract counter by 4 - B 1b # repeat - -0: - LDP lr, x3, [sp], 16 - LDP x0, x1, [sp], 16 - RET - -# ----------------------------------------------------------------------------- - -# @x0 pointer to string - -_uart_puts: - STR lr, [sp, -16]! - STP x0, x1, [sp, -16]! - -1: - LDRB w1, [x0], 1 # load byte of string from address in x0 - CBZ w1, 0f # return if zero - BL uart_putc # put charcter out - B 1b # loop - -0: - LDP x0, x1, [sp], 16 - LDR lr, [sp], 16 - RET - -# ----------------------------------------------------------------------------- diff --git a/kernel/arm64/core.s b/sys/core.s similarity index 100% rename from kernel/arm64/core.s rename to sys/core.s diff --git a/sys/main.c b/sys/main.c new file mode 100644 index 0000000..1fcf79d --- /dev/null +++ b/sys/main.c @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file main.c + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#include "uart.h" + + +void +k_main(void); + + +void +k_main(void) +{ + uart_init(); + + uart_putc('L'); + uart_putc('o'); + uart_putc('w'); + uart_putc('e'); + uart_putc('\n'); + + for (;;) { + } +} + diff --git a/sys/memmap b/sys/memmap new file mode 100644 index 0000000..eb6c0cf --- /dev/null +++ b/sys/memmap @@ -0,0 +1,12 @@ + ENTRY(_start) + + SECTIONS + { + . = 0x40000000; + .text : { *(.text) } + .data : { *(.data) } + .bss : { *(.bss COMMON) } + . = ALIGN(8); + . = . + 0x1000; + stack_ptr = . ; + } diff --git a/sys/uart.c b/sys/uart.c new file mode 100644 index 0000000..67b69bf --- /dev/null +++ b/sys/uart.c @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file uart.c + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#include "uart.h" + +unsigned int *uart_base = (unsigned int *)UART_BASE; + + +void +uart_init(void) +{ + +} + +void +uart_putc(unsigned char c) +{ + *uart_base = c; + if(c == '\n') + *uart_base = '\r'; +} diff --git a/sys/uart.h b/sys/uart.h new file mode 100644 index 0000000..4954fee --- /dev/null +++ b/sys/uart.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file uart.h + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#ifndef UART_H_8AFC47F9_2953_42C1_A5C1_1AE5A1F52CD0 +#define UART_H_8AFC47F9_2953_42C1_A5C1_1AE5A1F52CD0 + + +#define UART_BASE 0x09000000 + +void +uart_init(void); + +void +uart_putc(unsigned char c); + + + +#endif /* !UART_H */ diff --git a/sys/uart.s b/sys/uart.s new file mode 100644 index 0000000..a5bece1 --- /dev/null +++ b/sys/uart.s @@ -0,0 +1,93 @@ +// file : uart.s +// project : Löwe OS +// authors : Elias Löwe + +// address of UART for virt device in qemu + +// ----------------------------------------------------------------------------- + + .global _uart_putc // print single character uart + .global _uart_putx // print integer in HEX format to uart + .global _uart_puts // print null-terminated string to uart + +// ----------------------------------------------------------------------------- + + .text + +// helper to avoid extra data moving +// @x1 character print +uart_putc: + STP x2, lr, [sp, -16]! + + MOV x2, 0x09000000 // set UART address + STRB w1, [x2] // put character out + + LDP x2, lr, [sp], 16 + RET + +// ----------------------------------------------------------------------------- + + +// print character to uart +// @x0 character print +_uart_putc: + STR lr, [sp, -16]! + + MOV x1, x0 // set arguments + BL uart_putc // put character out + + LDR lr, [sp], 16 + RET + + +// ----------------------------------------------------------------------------- + +// @x0 integer to print +_uart_putx: + STP lr, x3, [sp, -32]! + STP x0, x1, [sp, 16] + + LDR x3, =60 // init bits counter 64-4 + +1: + LSR x1, x0, x3 // shift to digit + AND x1, x1, 0xF // keep only digit + CMP x1, 9 // compare it to 9 + BLS 2f // less or equal + ADD x1, x1, 0x37 // turn into ASCII HEX char + B 3f // continue to output + +2: + ADD x1, x1, 0x30 // turn into ASCII num char + +3: + BL uart_putc // output carachter + CBZ x3, 0f // if counter == 0 return + SUB x3, x3, 4 // otherwise subtract counter by 4 + B 1b // repeat + +0: + LDP lr, x3, [sp], 16 + LDP x0, x1, [sp], 16 + RET + +// ----------------------------------------------------------------------------- + +// @x0 pointer to string + +_uart_puts: + STR lr, [sp, -16]! + STP x0, x1, [sp, -16]! + +1: + LDRB w1, [x0], 1 // load byte of string from address in x0 + CBZ w1, 0f // return if zero + BL uart_putc // put charcter out + B 1b // loop + +0: + LDP x0, x1, [sp], 16 + LDR lr, [sp], 16 + RET + +// -----------------------------------------------------------------------------