Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Add half-baked aarch64 support #73

Merged
merged 10 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/build-os.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ jobs:

- name: Build duckOS (Release)
run: |
cd cmake-build
cmake .. -DCMAKE_TOOLCHAIN_FILE=cmake-build/CMakeToolchain.txt -DCMAKE_BUILD_TYPE=Release
cd build/i686
cmake ../.. -DCMAKE_TOOLCHAIN_FILE=build/i686/CMakeToolchain.txt -DCMAKE_BUILD_TYPE=Release
make install

- name: Make image
run: |
cd cmake-build
cd build/i686
make image

- name: Upload image
uses: actions/upload-artifact@v3
with:
name: Disk Image
path: cmake-build/duckOS.img
path: build/i686/duckOS.img

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ _deps

# CMake
cmake-build*/
build/

#
# DUCKOS-SPECIFIC
Expand Down
10 changes: 8 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ SET_PROPERTY(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "root")
# Options
SET(ADD_KERNEL_DEBUG_SYMBOLS OFF CACHE BOOL "Add symbols to the kernel -g and -ggdb for debugging")

IF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686")
SET(KERNEL_EXECUTABLE_NAME duckk32)
ELSEIF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")
SET(KERNEL_EXECUTABLE_NAME duckk64)
ENDIF()

function(MAKE_LIBRARY LIBNAME)
# Install dynamic library
ADD_LIBRARY(${LIBNAME} SHARED ${SOURCES})
Expand Down Expand Up @@ -70,7 +76,7 @@ ADD_SUBDIRECTORY(services/)
ADD_SUBDIRECTORY(programs/)

ADD_CUSTOM_TARGET(image
COMMAND ${CMAKE_COMMAND} -E env "SOURCE_DIR=${CMAKE_SOURCE_DIR}" ${CMAKE_SOURCE_DIR}/scripts/image.sh $(IMAGE_DEV)
COMMAND ${CMAKE_COMMAND} -E env "SOURCE_DIR=${CMAKE_SOURCE_DIR}" "ARCH=${CMAKE_SYSTEM_PROCESSOR}" ${CMAKE_SOURCE_DIR}/scripts/image.sh $(IMAGE_DEV)
BYPRODUCTS ${CMAKE_BINARY_DIR}/duckOS.img
USES_TERMINAL
)
Expand All @@ -81,7 +87,7 @@ ADD_CUSTOM_TARGET(base-system
)

ADD_CUSTOM_TARGET(qemu
COMMAND ${CMAKE_SOURCE_DIR}/scripts/qemu.sh
COMMAND ${CMAKE_COMMAND} -E env "KERNEL_NAME=${KERNEL_EXECUTABLE_NAME}" "ARCH=${CMAKE_SYSTEM_PROCESSOR}" ${CMAKE_SOURCE_DIR}/scripts/qemu.sh
USES_TERMINAL
)

Expand Down
25 changes: 20 additions & 5 deletions INSTRUCTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
- You must also install [macFUSE](https://osxfuse.github.io) and `fuse-ext2`
- The latest version of FUSE-ext2 can be built by running `toolchain/build-ext2-fuse.sh`. Alternatively, an older binary version is available [here](https://github.com/gpz500/fuse-ext2/releases)
- If you are on an Apple Silicon Mac, you may need to set the `CPATH=/opt/homebrew/include` and `LIBRARY_PATH=/opt/homebrew/lib` environment variables to get the toolchain to build.

## Building the toolchain
1. Open the `toolchain` directory in your terminal and run `build-toolchain.sh`. (You will need an internet connection as it downloads the needed binutils/gcc releases from the GNU ftp site.)
- This will default to i386. If you'd like to build for a different architecture, specify it with the `ARCH` environment variable.
- Supported targets are `i386` and `aarch64`.
2. Make a cup of coffee or tea and wait. It will take a while to compile.
3. Once it's done, the toolchain will be in `toolchain/tools`, and the sysroot in `cmake-build/root`.
3. Once it's done, the toolchain will be in `toolchain/tools`, and the sysroot in `build/[arch]/root`.

### Editing the toolchain
If you'd like to edit the c library, you can run `build-toolchain.sh libc` to recompile libc and libstdc++. If you just want to compile libc and not libstdc++, you can run `make libc` in the `cmake-build` folder.
If you'd like to edit the c library, you can run `build-toolchain.sh libc` to recompile libc and libstdc++. If you just want to compile libc and not libstdc++, you can run `make libc` in the `build/[arch]` folder.

If you'd like to edit gcc or binutils, you can run the `edit-toolchain.sh` script to download patch binutils and gcc and setup a git repository for each one. Then, use the `gen-patches.sh` script to generate patch files for each one.

Expand All @@ -44,11 +47,11 @@ To build something from the `edit` directory, pass the `edited-[thing]` to the `

## Configuring cmake
1. Make sure you've built the toolchain first.
2. Go to the `cmake-build` directory.
3. From that directory, run `cmake .. -DCMAKE_TOOLCHAIN_FILE=cmake-build/CMakeToolchain.txt`.
2. Go to the `build/[arch]` directory.
3. From that directory, run `cmake ../.. -DCMAKE_TOOLCHAIN_FILE=build/[arch]/CMakeToolchain.txt`.

## Building and running duckOS
1. In the `cmake-build` directory, run `make install` to build the kernel & programs.
1. In the `build/[arch]` directory, run `make install` to build the kernel & programs.
2. Run `make image` to make the disk image.
4. Run `make qemu` to run qemu with the image you just made.
5. Enjoy!
Expand All @@ -57,3 +60,15 @@ To build something from the `edit` directory, pass the `edited-[thing]` to the `
To run kernel unit tests, run `make install` and `make image` as usual, and then use `make tests` to run tests. Instead of running init, the kernel will run unit tests after booting.

Alternatively, supply the `kernel-tests` kernel argument to run tests.

## Raspberry Pi
*Note: aarch64 support is WIP, and even less likely to work properly on real hardware than in qemu. duckOS currently supports the Raspberry Pi 3B.*

To run duckOS on a Raspberry Pi, make the kernel as usual and then run `make rpi-kernel` to create a flat binary for the Raspberry Pi bootloader. Copy the resulting `kernel8.img` to a FAT32-formatted SD card along with the appropriate [firmware](https://github.com/raspberrypi/firmware) (just as you would have the boot partition in a raspbian install), and then add a `config.txt` file with the following contents:

```
disable_commandline_tags=1
kernel=kernel8.img
arm_64bit=1
kernel_address=0x80000
```
106 changes: 75 additions & 31 deletions kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
set(CMAKE_CXX_STANDARD 20)

ENABLE_LANGUAGE(ASM_NASM)
SET_SOURCE_FILES_PROPERTIES(asm/startup.s asm/tasking.s asm/int.s asm/syscall.s asm/gdt.s asm/timing.s PROPERTIES LANGUAGE ASM_NASM)
SET_SOURCE_FILES_PROPERTIES(arch/i386/asm/startup.s arch/i386/asm/tasking.s arch/i386/asm/int.s arch/i386/asm/syscall.s arch/i386/asm/gdt.s arch/i386/asm/timing.s PROPERTIES LANGUAGE ASM_NASM)

SET(CMAKE_CXX_FLAGS "-ffreestanding -nostdlib -fno-rtti -fno-exceptions -Wno-write-strings -fbuiltin -nostdlib -nostdinc -nostdinc++ -std=c++2a")

Expand All @@ -24,16 +24,7 @@ SET(CMAKE_ASM_NASM_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}/ -f elf")
SET(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")

SET(KERNEL_SRCS
asm/startup.s
asm/tasking.s
asm/int.s
asm/syscall.s
asm/gdt.s
asm/timing.s
kmain.cpp
time/CMOS.cpp
time/PIT.cpp
time/RTC.cpp
time/TimeManager.cpp
time/TimeKeeper.cpp
time/Time.cpp
Expand All @@ -43,13 +34,8 @@ SET(KERNEL_SRCS
tasking/ELF.cpp
tasking/TaskManager.cpp
pci/PCI.cpp
memory/gdt.cpp
memory/liballoc.cpp
memory/MemoryManager.cpp
interrupt/interrupt.cpp
interrupt/idt.cpp
interrupt/irq.cpp
interrupt/isr.cpp
pci/PCI.cpp
device/Device.cpp
device/BlockDevice.cpp
Expand Down Expand Up @@ -79,7 +65,6 @@ SET(KERNEL_SRCS
device/MouseDevice.cpp
interrupt/IRQHandler.cpp
memory/PageDirectory.cpp
memory/PageTable.cpp
tasking/Process.cpp
tasking/Thread.cpp
tasking/Lock.cpp
Expand All @@ -95,7 +80,6 @@ SET(KERNEL_SRCS
tasking/FileBlockers.cpp
tasking/Tracer.cpp
device/VGADevice.cpp
device/BochsVGADevice.cpp
device/MultibootVGADevice.cpp
memory/Stack.h
memory/PhysicalRegion.cpp
Expand All @@ -109,7 +93,6 @@ SET(KERNEL_SRCS
memory/Memory.cpp
memory/KBuffer.cpp
memory/Bytes.cpp
device/PATADevice.cpp
CommandLine.cpp
tasking/Signal.cpp
filesystem/DirectoryEntry.cpp
Expand Down Expand Up @@ -138,7 +121,6 @@ SET(KERNEL_SRCS
kstd/cstring.cpp
kstd/kstdlib.cpp
kstd/string.cpp
device/AC97Device.cpp
tests/KernelTest.cpp
tests/kstd/TestMap.cpp
tests/TestMemory.cpp
Expand Down Expand Up @@ -178,7 +160,6 @@ SET(KERNEL_SRCS
syscall/waitpid.cpp
syscall/uname.cpp
VMWare.cpp
Processor.cpp
StackWalker.cpp
net/NetworkAdapter.cpp
net/E1000Adapter.cpp
Expand All @@ -188,7 +169,71 @@ SET(KERNEL_SRCS
net/UDPSocket.cpp
net/TCPSocket.cpp
net/Router.cpp
api/strerror.c)
api/strerror.c
constructors.cpp)

IF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686")
SET(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/kernel/arch/i386/kernel.ld)
SET(KERNEL_SRCS
${KERNEL_SRCS}

arch/i386/Processor.cpp
arch/i386/idt.cpp
arch/i386/irq.cpp
arch/i386/isr.cpp
arch/i386/tasking.cpp
arch/i386/gdt.cpp
arch/i386/kstdio.cpp
arch/i386/startup.cpp
arch/i386/PageTable.cpp
arch/i386/PageDirectory.cpp
arch/i386/MemoryManager.cpp

arch/i386/asm/startup.s
arch/i386/asm/tasking.s
arch/i386/asm/int.s
arch/i386/asm/syscall.s
arch/i386/asm/gdt.s
arch/i386/asm/timing.s

arch/i386/device/Device.cpp
arch/i386/device/PATADevice.cpp
arch/i386/device/BochsVGADevice.cpp
arch/i386/device/AC97Device.cpp

arch/i386/time/CMOS.cpp
arch/i386/time/PIT.cpp
arch/i386/time/RTC.cpp)
ELSEIF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")
SET(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/kernel/arch/aarch64/kernel.ld)
SET(KERNEL_SRCS
${KERNEL_SRCS}

arch/aarch64/Processor.cpp
arch/aarch64/ARMTimer.cpp
arch/aarch64/tasking.cpp
arch/aarch64/startup.cpp
arch/aarch64/kstdio.cpp
arch/aarch64/MMU.cpp
arch/aarch64/PageDirectory.cpp
arch/aarch64/MemoryManager.cpp
arch/aarch64/Device.cpp

arch/aarch64/asm/startup.S
arch/aarch64/asm/exception.S

arch/aarch64/rpi/MiniUART.cpp
arch/aarch64/rpi/GPIO.cpp
arch/aarch64/rpi/Mailbox.cpp
arch/aarch64/rpi/Framebuffer.cpp
arch/aarch64/rpi/DeviceInfo.cpp
arch/aarch64/rpi/MMIO.cpp)

ADD_CUSTOM_TARGET(rpi-kernel
COMMAND ${CMAKE_OBJCOPY} ${KERNEL_EXECUTABLE_NAME} -O binary ${CMAKE_BINARY_DIR}/kernel8.img
USES_TERMINAL
)
ENDIF()

add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated/duckos_version.h"
Expand All @@ -198,16 +243,15 @@ add_custom_command(
)
add_custom_target(generate_version_file DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/generated/duckos_version.h")

ADD_EXECUTABLE(duckk32 ${KERNEL_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/generated/duckos_version.h)
ADD_DEPENDENCIES(duckk32 generate_version_file)
TARGET_COMPILE_DEFINITIONS(duckk32 PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>" DUCKOS_KERNEL "$<$<BOOL:${ADD_KERNEL_DEBUG_SYMBOLS}>:DUCKOS_KERNEL_DEBUG_SYMBOLS>")
ADD_EXECUTABLE(${KERNEL_EXECUTABLE_NAME} ${KERNEL_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/generated/duckos_version.h)
ADD_DEPENDENCIES(${KERNEL_EXECUTABLE_NAME} generate_version_file)
TARGET_COMPILE_DEFINITIONS(${KERNEL_EXECUTABLE_NAME} PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>" DUCKOS_KERNEL "$<$<BOOL:${ADD_KERNEL_DEBUG_SYMBOLS}>:DUCKOS_KERNEL_DEBUG_SYMBOLS>")

SET(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/kernel/kernel.ld)
SET_TARGET_PROPERTIES(duckk32 PROPERTIES LINK_DEPENDS ${LINKER_SCRIPT})
TARGET_LINK_LIBRARIES(duckk32 gcc)
TARGET_LINK_OPTIONS(duckk32 PRIVATE LINKER:-T ${LINKER_SCRIPT} -nostdlib)
SET_TARGET_PROPERTIES(${KERNEL_EXECUTABLE_NAME} PROPERTIES LINK_DEPENDS ${LINKER_SCRIPT})
TARGET_LINK_LIBRARIES(${KERNEL_EXECUTABLE_NAME} gcc)
TARGET_LINK_OPTIONS(${KERNEL_EXECUTABLE_NAME} PRIVATE LINKER:-T ${LINKER_SCRIPT} -nostdlib)

TARGET_INCLUDE_DIRECTORIES(duckk32 PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/generated)
TARGET_INCLUDE_DIRECTORIES(${KERNEL_EXECUTABLE_NAME} PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/generated)

# Install headers
FILE(GLOB_RECURSE KHEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h")
Expand All @@ -217,8 +261,8 @@ foreach(HEADER ${KHEADERS})
endforeach()

# Install kernel
INSTALL(TARGETS duckk32 RUNTIME DESTINATION boot)
INSTALL(TARGETS ${KERNEL_EXECUTABLE_NAME} RUNTIME DESTINATION boot)

# Make kernel map
ADD_CUSTOM_COMMAND(TARGET duckk32 COMMAND ${CMAKE_SOURCE_DIR}/scripts/kernel-map.sh)
ADD_CUSTOM_COMMAND(TARGET ${KERNEL_EXECUTABLE_NAME} COMMAND ${CMAKE_SOURCE_DIR}/scripts/kernel-map.sh ${KERNEL_EXECUTABLE_NAME})
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/kernel.map DESTINATION boot)
3 changes: 1 addition & 2 deletions kernel/CommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
Copyright (c) Byteduck 2016-2020. All rights reserved.
*/

#include <kernel/memory/PageDirectory.h>
#include <kernel/kstd/KLog.h>
#include "CommandLine.h"
#include "kernel/memory/MemoryManager.h"
Expand All @@ -28,7 +27,7 @@ CommandLine::CommandLine(const struct multiboot_info& header) {
if(!_inst)
_inst = this;
if(header.flags & MULTIBOOT_INFO_CMDLINE) {
cmdline = (char*) (header.cmdline + HIGHER_HALF);
cmdline = (char*) ((size_t) header.cmdline + HIGHER_HALF);

KLog::info("CommandLine", "Command line options: '{}'", cmdline);

Expand Down
16 changes: 13 additions & 3 deletions kernel/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
*/

#include "IO.h"
#include "kstd/kstdio.h"
#include "memory/MemoryManager.h"
#include "kernel/kstd/kstdio.h"
#include "kernel/memory/MemoryManager.h"

#if defined(__i386__)
void IO::wait() {
asm volatile ( "jmp 1f\n\t"
"1:jmp 2f\n\t"
Expand Down Expand Up @@ -56,6 +57,11 @@ uint32_t IO::inl(uint16_t port){
asm volatile ("inl %1, %0" : "=a" (ret) : "dN" (port));
return ret;
}
#elif defined(__aarch64__)
void IO::wait() {
// TODO: aarch64
}
#endif

IO::Window::Window(PCI::Address addr, uint8_t bar) {
auto bar_val = PCI::read_dword(addr, bar);
Expand All @@ -75,9 +81,13 @@ IO::Window::Window(PCI::Address addr, uint8_t bar) {
PCI::write_dword(addr, bar, 0xFFFFFFFF);
m_size = ~(PCI::read_dword(addr, bar) & (~0xfull)) + 1;
PCI::write_dword(addr, bar, bar_val);
m_vm_region = MM.alloc_mapped_region(m_addr, m_size);
m_vm_region = MM.map_device_region(m_addr, m_size);
} else {
#if defined(__i386__)
m_type = IOSpace;
m_addr = bar_val & ~0x3u;
#else
m_type = Invalid;
#endif
}
}
Loading
Loading