Compare commits
No commits in common. "08ffb6ee9483581dc18be5d0f9f55720f9d5ecd4" and "c95e490a219d92376b41a8042e3cd3dab81caa88" have entirely different histories.
08ffb6ee94
...
c95e490a21
90
Makefile
90
Makefile
|
@ -1,90 +0,0 @@
|
||||||
# environment
|
|
||||||
|
|
||||||
AARCH64_TOOLCHAIN ?= aarch64-linux-gnu
|
|
||||||
|
|
||||||
|
|
||||||
# Shortcuts
|
|
||||||
|
|
||||||
CC=clang --target=aarch64-none-elf -mcpu=cortex-a57
|
|
||||||
LD=ld.lld
|
|
||||||
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 = aarch64/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) -nostdlib $^ -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 \
|
|
||||||
-M virt \
|
|
||||||
-cpu cortex-a57 \
|
|
||||||
-nographic \
|
|
||||||
-smp 4 \
|
|
||||||
-m 4096 \
|
|
||||||
-kernel build/kernel.elf \
|
|
||||||
-serial stdio \
|
|
||||||
-monitor none \
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -Rf ./$(BUILD_DIR)/*
|
|
||||||
|
|
||||||
run: kernel
|
|
||||||
$(QEMU_CMD)
|
|
||||||
|
|
||||||
|
|
||||||
debug: kernel
|
|
||||||
$(QEMU_CMD) -S -gdb tcp::1234 & \
|
|
||||||
gdb-multiarch -q \
|
|
||||||
-ex 'file build/kernel.elf' \
|
|
||||||
-ex 'target remote localhost:1234'
|
|
||||||
kill %1
|
|
|
@ -1,18 +0,0 @@
|
||||||
.globl _start
|
|
||||||
|
|
||||||
_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 k_main
|
|
||||||
|
|
||||||
idle:
|
|
||||||
b idle
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
ENTRY(_start)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
/* For some reason qemu UART doesn't work with smaller address */
|
|
||||||
. = 0x40000000;
|
|
||||||
|
|
||||||
.boot . : { boot.o(.text) }
|
|
||||||
.text : { *(.text) }
|
|
||||||
.data : { *(.data) }
|
|
||||||
.bss : { *(.bss COMMON) }
|
|
||||||
|
|
||||||
. = ALIGN(8);
|
|
||||||
. = . + 0x1000;
|
|
||||||
stack_ptr = . ;
|
|
||||||
}
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
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/*
|
|
@ -0,0 +1,12 @@
|
||||||
|
ENTRY(_core_init)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x40000000;
|
||||||
|
.text : { *(.text) }
|
||||||
|
.data : { *(.text) }
|
||||||
|
.bss : { *(.bss COMMON) }
|
||||||
|
. = ALIGN(10);
|
||||||
|
. = . + 0x1000;
|
||||||
|
stack_ptr = . ;
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
# file : uart.s
|
||||||
|
# project : Löwe OS
|
||||||
|
# authors : Elias Löwe <elias@lowenware.com>
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
34
sys/main.c
34
sys/main.c
|
@ -1,34 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2019 by Löwenware Ltd
|
|
||||||
* Please, refer LICENSE file for legal information
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file main.c
|
|
||||||
* @author Ilja Kartašov <ik@lowenware.com>
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
* @see https://lowenware.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uart.h"
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
k_main(void);
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
k_main(void)
|
|
||||||
{
|
|
||||||
uart_init();
|
|
||||||
|
|
||||||
uart_puts((unsigned char *) "Lowe OS\n");
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
__asm__("WFE");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
41
sys/uart.c
41
sys/uart.c
|
@ -1,41 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2019 by Löwenware Ltd
|
|
||||||
* Please, refer LICENSE file for legal information
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file uart.c
|
|
||||||
* @author Ilja Kartašov <ik@lowenware.com>
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
* @see https://lowenware.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uart.h"
|
|
||||||
|
|
||||||
volatile unsigned int *UART0 = (unsigned int *)UART_BASE;
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
uart_init(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
uart_putc(unsigned char c)
|
|
||||||
{
|
|
||||||
*UART0 = (unsigned int) c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
uart_puts(const unsigned char *s)
|
|
||||||
{
|
|
||||||
while(*s) {
|
|
||||||
*UART0 = (unsigned int) *(s++);
|
|
||||||
}
|
|
||||||
}
|
|
33
sys/uart.h
33
sys/uart.h
|
@ -1,33 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2019 by Löwenware Ltd
|
|
||||||
* Please, refer LICENSE file for legal information
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file uart.h
|
|
||||||
* @author Ilja Kartašov <ik@lowenware.com>
|
|
||||||
* @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);
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
uart_puts(const unsigned char *s);
|
|
||||||
|
|
||||||
#endif /* !UART_H */
|
|
93
sys/uart.s
93
sys/uart.s
|
@ -1,93 +0,0 @@
|
||||||
// file : uart.s
|
|
||||||
// project : Löwe OS
|
|
||||||
// authors : Elias Löwe <elias@lowenware.com>
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
Loading…
Reference in New Issue