Compare commits

..

No commits in common. "6d899aa6ce479fdd5aa11d0f8a426f89bfc1f140" and "1af3ca19abd24272318ab942122648ced162fcc9" have entirely different histories.

69 changed files with 153811 additions and 714 deletions

2
.gitignore vendored
View File

@ -2,4 +2,4 @@
.idea/ .idea/
build/ build/
base/ base/
script/fakeroot-context

View File

@ -1,5 +1,6 @@
#include <BAN/String.h> #include <BAN/String.h>
#include <BAN/New.h> #include <BAN/New.h>
#include <BAN/Variant.h>
namespace BAN namespace BAN
{ {
@ -31,7 +32,8 @@ namespace BAN
String& String::operator=(const String& other) String& String::operator=(const String& other)
{ {
clear(); clear();
MUST(ensure_capacity(other.size())); if (!other.fits_in_sso())
MUST(ensure_capacity(other.size()));
memcpy(data(), other.data(), other.size() + 1); memcpy(data(), other.data(), other.size() + 1);
m_size = other.size(); m_size = other.size();
return *this; return *this;
@ -41,18 +43,14 @@ namespace BAN
{ {
clear(); clear();
if (other.has_sso()) if (other.fits_in_sso())
memcpy(data(), other.data(), other.size() + 1); memcpy(data(), other.data(), other.size() + 1);
else else
{ m_storage = other.m_storage.get<GeneralStorage>();
m_storage.general_storage = other.m_storage.general_storage;
m_has_sso = false;
}
m_size = other.m_size; m_size = other.m_size;
other.m_size = 0; other.m_size = 0;
other.m_storage.sso_storage = SSOStorage(); other.m_storage = SSOStorage();
other.m_has_sso = true;
return *this; return *this;
} }
@ -60,7 +58,8 @@ namespace BAN
String& String::operator=(StringView other) String& String::operator=(StringView other)
{ {
clear(); clear();
MUST(ensure_capacity(other.size())); if (!fits_in_sso(other.size()))
MUST(ensure_capacity(other.size()));
memcpy(data(), other.data(), other.size()); memcpy(data(), other.data(), other.size());
m_size = other.size(); m_size = other.size();
data()[m_size] = '\0'; data()[m_size] = '\0';
@ -126,9 +125,8 @@ namespace BAN
{ {
if (!has_sso()) if (!has_sso())
{ {
deallocator(m_storage.general_storage.data); deallocator(m_storage.get<GeneralStorage>().data);
m_storage.sso_storage = SSOStorage(); m_storage = SSOStorage();
m_has_sso = true;
} }
m_size = 0; m_size = 0;
data()[m_size] = '\0'; data()[m_size] = '\0';
@ -168,6 +166,15 @@ namespace BAN
data()[m_size] = '\0'; data()[m_size] = '\0';
return {}; return {};
} }
// shrink general -> sso
if (!has_sso() && fits_in_sso(new_size))
{
char* data = m_storage.get<GeneralStorage>().data;
m_storage = SSOStorage();
memcpy(m_storage.get<SSOStorage>().storage, data, new_size);
deallocator(data);
}
m_size = new_size; m_size = new_size;
data()[m_size] = '\0'; data()[m_size] = '\0';
@ -187,21 +194,20 @@ namespace BAN
if (fits_in_sso()) if (fits_in_sso())
{ {
char* data = m_storage.general_storage.data; char* data = m_storage.get<GeneralStorage>().data;
m_storage.sso_storage = SSOStorage(); m_storage = SSOStorage();
m_has_sso = true; memcpy(m_storage.get<SSOStorage>().storage, data, m_size + 1);
memcpy(this->data(), data, m_size + 1);
deallocator(data); deallocator(data);
return {}; return {};
} }
GeneralStorage& storage = m_storage.general_storage; GeneralStorage& storage = m_storage.get<GeneralStorage>();
if (storage.capacity == m_size) if (storage.capacity == m_size)
return {}; return {};
char* new_data = (char*)allocator(m_size + 1); char* new_data = (char*)allocator(m_size + 1);
if (new_data == nullptr) if (new_data == nullptr)
return Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
memcpy(new_data, storage.data, m_size); memcpy(new_data, storage.data, m_size);
deallocator(storage.data); deallocator(storage.data);
@ -216,45 +222,40 @@ namespace BAN
{ {
if (has_sso()) if (has_sso())
return sso_capacity; return sso_capacity;
return m_storage.general_storage.capacity; return m_storage.get<GeneralStorage>().capacity;
} }
char* String::data() char* String::data()
{ {
if (has_sso()) if (has_sso())
return m_storage.sso_storage.data; return m_storage.get<SSOStorage>().storage;
return m_storage.general_storage.data; return m_storage.get<GeneralStorage>().data;
} }
const char* String::data() const const char* String::data() const
{ {
if (has_sso()) if (has_sso())
return m_storage.sso_storage.data; return m_storage.get<SSOStorage>().storage;
return m_storage.general_storage.data; return m_storage.get<GeneralStorage>().data;
} }
ErrorOr<void> String::ensure_capacity(size_type new_size) ErrorOr<void> String::ensure_capacity(size_type new_size)
{ {
if (m_size >= new_size) if (m_size >= new_size || fits_in_sso(new_size))
return {};
if (has_sso() && fits_in_sso(new_size))
return {}; return {};
char* new_data = (char*)allocator(new_size + 1); char* new_data = (char*)allocator(new_size + 1);
if (new_data == nullptr) if (new_data == nullptr)
return Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
memcpy(new_data, data(), m_size + 1); memcpy(new_data, data(), m_size + 1);
if (has_sso()) if (has_sso())
{ m_storage = GeneralStorage();
m_storage.general_storage = GeneralStorage();
m_has_sso = false;
}
else else
deallocator(m_storage.general_storage.data); deallocator(m_storage.get<GeneralStorage>().data);
auto& storage = m_storage.general_storage; auto& storage = m_storage.get<GeneralStorage>();
storage.capacity = new_size; storage.capacity = new_size;
storage.data = new_data; storage.data = new_data;
@ -263,7 +264,7 @@ namespace BAN
bool String::has_sso() const bool String::has_sso() const
{ {
return m_has_sso; return m_storage.has<SSOStorage>();
} }
} }

View File

@ -10,15 +10,17 @@ set(BAN_SOURCES
) )
add_custom_target(ban-headers add_custom_target(ban-headers
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/ COMMAND sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
DEPENDS sysroot DEPENDS sysroot
USES_TERMINAL
) )
add_library(ban ${BAN_SOURCES}) add_library(ban ${BAN_SOURCES})
add_dependencies(ban headers libc-install) add_dependencies(ban headers libc-install)
add_custom_target(ban-install add_custom_target(ban-install
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/libban.a ${BANAN_LIB}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/libban.a ${BANAN_LIB}/
DEPENDS ban DEPENDS ban
BYPRODUCTS ${BANAN_LIB}/libban.a BYPRODUCTS ${BANAN_LIB}/libban.a
USES_TERMINAL
) )

View File

@ -1,33 +1,11 @@
#pragma once #pragma once
#include <BAN/Traits.h>
#if defined(__is_kernel) #if defined(__is_kernel)
#include <kernel/Panic.h> #include <kernel/Panic.h>
#define ASSERT(cond) do { if (!(cond)) Kernel::panic("ASSERT("#cond") failed"); } while (false)
#define ASSERT(cond) \
do { \
if (!(cond)) \
Kernel::panic("ASSERT(" #cond ") failed"); \
} while (false)
#define __ASSERT_BIN_OP(lhs, rhs, name, op) \
do { \
auto&& _lhs = lhs; \
auto&& _rhs = rhs; \
if (!(_lhs op _rhs)) \
Kernel::panic(name "(" #lhs ", " #rhs ") ({} " #op " {}) failed", _lhs, _rhs); \
} while (false)
#define ASSERT_LT(lhs, rhs) __ASSERT_BIN_OP(lhs, rhs, "ASSERT_LT", <)
#define ASSERT_LTE(lhs, rhs) __ASSERT_BIN_OP(lhs, rhs, "ASSERT_LTE", <=)
#define ASSERT_GT(lhs, rhs) __ASSERT_BIN_OP(lhs, rhs, "ASSERT_GT", >)
#define ASSERT_GTE(lhs, rhs) __ASSERT_BIN_OP(lhs, rhs, "ASSERT_GTE", >=)
#define ASSERT_EQ(lhs, rhs) __ASSERT_BIN_OP(lhs, rhs, "ASSERT_EQ", ==)
#define ASSERT_NEQ(lhs, rhs) __ASSERT_BIN_OP(lhs, rhs, "ASSERT_NEQ", !=)
#define ASSERT_NOT_REACHED() Kernel::panic("ASSERT_NOT_REACHED() failed") #define ASSERT_NOT_REACHED() Kernel::panic("ASSERT_NOT_REACHED() failed")
#else #else
#include <assert.h> #include <assert.h>
#define ASSERT(cond) assert((cond) && "ASSERT("#cond") failed") #define ASSERT(cond) assert((cond) && "ASSERT("#cond") failed")
#define ASSERT_NOT_REACHED() do { assert(false && "ASSERT_NOT_REACHED() failed"); __builtin_unreachable(); } while (false) #define ASSERT_NOT_REACHED() do { assert(false && "ASSERT_NOT_REACHED() failed"); __builtin_unreachable(); } while (false)
#endif #endif

View File

@ -82,21 +82,17 @@ namespace BAN
private: private:
struct SSOStorage struct SSOStorage
{ {
char data[sso_capacity + 1] {}; char storage[sso_capacity + 1] {};
}; };
struct GeneralStorage struct GeneralStorage
{ {
size_type capacity { 0 }; size_type capacity { 0 };
char* data { nullptr }; char* data;
}; };
private: private:
union { Variant<SSOStorage, GeneralStorage> m_storage { SSOStorage() };
SSOStorage sso_storage; size_type m_size { 0 };
GeneralStorage general_storage;
} m_storage { .sso_storage = SSOStorage() };
size_type m_size : sizeof(size_type) * 8 - 1 { 0 };
size_type m_has_sso : 1 { true };
}; };
template<typename... Args> template<typename... Args>

View File

@ -10,6 +10,7 @@ add_compile_definitions(__enable_sse=0)
project(banan-os CXX C ASM) project(banan-os CXX C ASM)
set(BANAN_BASE_SYSROOT ${CMAKE_SOURCE_DIR}/base-sysroot.tar.gz) set(BANAN_BASE_SYSROOT ${CMAKE_SOURCE_DIR}/base-sysroot.tar.gz)
set(BANAN_SYSROOT ${CMAKE_BINARY_DIR}/sysroot)
set(BANAN_INCLUDE ${BANAN_SYSROOT}/usr/include) set(BANAN_INCLUDE ${BANAN_SYSROOT}/usr/include)
set(BANAN_LIB ${BANAN_SYSROOT}/usr/lib) set(BANAN_LIB ${BANAN_SYSROOT}/usr/lib)
set(BANAN_BIN ${BANAN_SYSROOT}/usr/bin) set(BANAN_BIN ${BANAN_SYSROOT}/usr/bin)
@ -23,7 +24,8 @@ add_subdirectory(userspace)
add_custom_target(sysroot add_custom_target(sysroot
COMMAND ${CMAKE_COMMAND} -E make_directory ${BANAN_SYSROOT} COMMAND ${CMAKE_COMMAND} -E make_directory ${BANAN_SYSROOT}
COMMAND cd ${BANAN_SYSROOT} && tar xf ${BANAN_BASE_SYSROOT} COMMAND cd ${BANAN_SYSROOT} && sudo tar xf ${BANAN_BASE_SYSROOT}
USES_TERMINAL
) )
add_custom_target(headers add_custom_target(headers
@ -34,7 +36,6 @@ add_custom_target(headers
) )
add_custom_target(install-sysroot add_custom_target(install-sysroot
COMMAND cd ${BANAN_SYSROOT} && tar cf ${BANAN_SYSROOT_TAR} *
DEPENDS kernel-install DEPENDS kernel-install
DEPENDS ban-install DEPENDS ban-install
DEPENDS libc-install DEPENDS libc-install

View File

@ -3,8 +3,9 @@ cmake_minimum_required(VERSION 3.26)
project(LibELF CXX) project(LibELF CXX)
add_custom_target(libelf-headers add_custom_target(libelf-headers
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/ COMMAND sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
DEPENDS sysroot DEPENDS sysroot
USES_TERMINAL
) )
add_custom_target(libelf-install add_custom_target(libelf-install

View File

@ -1,5 +1,4 @@
#include <BAN/ScopeGuard.h> #include <BAN/ScopeGuard.h>
#include <kernel/CriticalScope.h>
#include <kernel/Memory/Heap.h> #include <kernel/Memory/Heap.h>
#include <kernel/LockGuard.h> #include <kernel/LockGuard.h>
#include <LibELF/LoadableELF.h> #include <LibELF/LoadableELF.h>
@ -227,8 +226,7 @@ namespace LibELF
if (paddr == 0) if (paddr == 0)
return BAN::Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
// Temporarily map page as RW so kernel can write to it m_page_table.map_page_at(paddr, vaddr, flags);
m_page_table.map_page_at(paddr, vaddr, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
m_physical_page_count++; m_physical_page_count++;
memset((void*)vaddr, 0x00, PAGE_SIZE); memset((void*)vaddr, 0x00, PAGE_SIZE);
@ -247,9 +245,6 @@ namespace LibELF
TRY(m_inode->read(program_header.p_offset + file_offset, { (uint8_t*)vaddr + vaddr_offset, bytes })); TRY(m_inode->read(program_header.p_offset + file_offset, { (uint8_t*)vaddr + vaddr_offset, bytes }));
} }
// Map page with the correct flags
m_page_table.map_page_at(paddr, vaddr, flags);
return {}; return {};
} }
default: default:
@ -307,12 +302,9 @@ namespace LibELF
if (paddr == 0) if (paddr == 0)
return BAN::Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
{ m_page_table.map_page_at(paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
CriticalScope _; memcpy((void*)0, (void*)(start + i * PAGE_SIZE), PAGE_SIZE);
PageTable::map_fast_page(paddr); m_page_table.unmap_page(0);
memcpy(PageTable::fast_page_as_ptr(), (void*)(start + i * PAGE_SIZE), PAGE_SIZE);
PageTable::unmap_fast_page();
}
new_page_table.map_page_at(paddr, start + i * PAGE_SIZE, flags); new_page_table.map_page_at(paddr, start + i * PAGE_SIZE, flags);
elf->m_physical_page_count++; elf->m_physical_page_count++;

View File

@ -2,7 +2,7 @@
# banan-os # banan-os
This is my hobby operating system written in C++. Currently supports only x86\_64 architecture. We have a ext2 filesystem, basic ramfs, IDE disk drivers in ATA PIO mode, ATA AHCI drivers, userspace processes, executable loading from ELF format, linear VBE graphics and multithreaded processing on single core. This is my hobby operating system written in C++. Currently supports only x86_64 architecture. We have a ext2 filesystem, basic ramfs, IDE disk drivers in ATA PIO mode, ATA AHCI drivers, userspace processes, executable loading from ELF format, linear VBE graphics and multithreaded processing on single core.
![screenshot from qemu running banan-os](assets/banan-os.png) ![screenshot from qemu running banan-os](assets/banan-os.png)
@ -20,7 +20,7 @@ To build the toolchain for this os. You can run the following command.
./script/build.sh toolchain ./script/build.sh toolchain
``` ```
To build the os itself you can run one of the following commands. You will need root access for disk image creation/modification. To build the os itself you can run one of the following commands. You will need root access since the sysroot has "proper" permissions.
```sh ```sh
./script/build.sh qemu ./script/build.sh qemu
./script/build.sh qemu-nographic ./script/build.sh qemu-nographic
@ -39,6 +39,8 @@ If you have corrupted your disk image or want to create new one, you can either
./script/build.sh image-full ./script/build.sh image-full
``` ```
> ***NOTE*** ```ninja clean``` has to be ran with root permissions, since it deletes from the banan-so sysroot.
If you feel like ```./script/build.sh``` is too verbose, there exists a symlink _bos_ in this projects root directory. All build commands can be used with ```./bos args...``` instead. If you feel like ```./script/build.sh``` is too verbose, there exists a symlink _bos_ in this projects root directory. All build commands can be used with ```./bos args...``` instead.
I have also created shell completion script for zsh. You can either copy the file in _script/shell-completion/zsh/\_bos_ to _/usr/share/zsh/site-functions/_ or add the _script/shell-completion/zsh_ to your fpath in _.zshrc_. I have also created shell completion script for zsh. You can either copy the file in _script/shell-completion/zsh/\_bos_ to _/usr/share/zsh/site-functions/_ or add the _script/shell-completion/zsh_ to your fpath in _.zshrc_.

View File

@ -36,6 +36,7 @@ set(KERNEL_SOURCES
kernel/kernel.cpp kernel/kernel.cpp
kernel/Memory/DMARegion.cpp kernel/Memory/DMARegion.cpp
kernel/Memory/FileBackedRegion.cpp kernel/Memory/FileBackedRegion.cpp
kernel/Memory/GeneralAllocator.cpp
kernel/Memory/Heap.cpp kernel/Memory/Heap.cpp
kernel/Memory/kmalloc.cpp kernel/Memory/kmalloc.cpp
kernel/Memory/MemoryBackedRegion.cpp kernel/Memory/MemoryBackedRegion.cpp
@ -147,9 +148,6 @@ target_compile_options(kernel PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-Wno-literal-suff
target_compile_options(kernel PUBLIC -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.) target_compile_options(kernel PUBLIC -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.)
target_compile_options(kernel PUBLIC -fstack-protector -ffreestanding -Wall -Werror=return-type -Wstack-usage=1024 -fno-omit-frame-pointer -mgeneral-regs-only) target_compile_options(kernel PUBLIC -fstack-protector -ffreestanding -Wall -Werror=return-type -Wstack-usage=1024 -fno-omit-frame-pointer -mgeneral-regs-only)
# This might not work with other toolchains
target_compile_options(kernel PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>)
if(ENABLE_KERNEL_UBSAN) if(ENABLE_KERNEL_UBSAN)
target_compile_options(kernel PUBLIC -fsanitize=undefined) target_compile_options(kernel PUBLIC -fsanitize=undefined)
endif() endif()
@ -164,15 +162,28 @@ endif()
target_link_options(kernel PUBLIC -ffreestanding -nostdlib) target_link_options(kernel PUBLIC -ffreestanding -nostdlib)
add_custom_target(crt0
COMMAND ${CMAKE_CXX_COMPILER} -c ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/crt0.S -o ${CMAKE_CURRENT_BINARY_DIR}/crt0.o
DEPENDS headers
)
add_custom_command(
TARGET crt0
POST_BUILD
COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/crt0.o ${BANAN_LIB}/
)
add_custom_target(kernel-headers add_custom_target(kernel-headers
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/ COMMAND sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/lai/include/ ${BANAN_INCLUDE}/ COMMAND sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/lai/include/ ${BANAN_INCLUDE}/
DEPENDS sysroot DEPENDS sysroot
USES_TERMINAL
) )
add_custom_target(kernel-install add_custom_target(kernel-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/kernel ${BANAN_BOOT}/banan-os.kernel COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/kernel ${BANAN_BOOT}/banan-os.kernel
DEPENDS kernel DEPENDS kernel
USES_TERMINAL
) )
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtbegin.o OUTPUT_VARIABLE CRTBEGIN OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtbegin.o OUTPUT_VARIABLE CRTBEGIN OUTPUT_STRIP_TRAILING_WHITESPACE)
@ -182,8 +193,8 @@ add_custom_command(
TARGET kernel PRE_LINK TARGET kernel PRE_LINK
COMMAND ${CMAKE_CXX_COMPILER} -MD -c ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/crti.S ${COMPILE_OPTIONS} COMMAND ${CMAKE_CXX_COMPILER} -MD -c ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/crti.S ${COMPILE_OPTIONS}
COMMAND ${CMAKE_CXX_COMPILER} -MD -c ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/crtn.S ${COMPILE_OPTIONS} COMMAND ${CMAKE_CXX_COMPILER} -MD -c ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/crtn.S ${COMPILE_OPTIONS}
COMMAND ${CMAKE_COMMAND} -E copy ${CRTBEGIN} . COMMAND cp ${CRTBEGIN} .
COMMAND ${CMAKE_COMMAND} -E copy ${CRTEND} . COMMAND cp ${CRTEND} .
) )
#add_custom_command( #add_custom_command(

View File

@ -181,20 +181,14 @@ namespace Kernel::IDT
{ {
// Check if stack is OOB // Check if stack is OOB
auto& stack = Thread::current().stack(); auto& stack = Thread::current().stack();
auto& istack = Thread::current().interrupt_stack(); if (interrupt_stack.rsp < stack.vaddr())
if (stack.vaddr() < interrupt_stack.rsp && interrupt_stack.rsp <= stack.vaddr() + stack.size())
; // using normal stack
else if (istack.vaddr() < interrupt_stack.rsp && interrupt_stack.rsp <= istack.vaddr() + istack.size())
; // using interrupt stack
else
{ {
derrorln("Stack pointer out of bounds!"); derrorln("Stack overflow");
derrorln("rsp {H}, stack {H}->{H}, istack {H}->{H}", goto done;
interrupt_stack.rsp, }
stack.vaddr(), stack.vaddr() + stack.size(), if (interrupt_stack.rsp >= stack.vaddr() + stack.size())
istack.vaddr(), istack.vaddr() + istack.size() {
); derrorln("Stack underflow");
Thread::current().handle_signal(SIGKILL);
goto done; goto done;
} }
@ -213,7 +207,7 @@ namespace Kernel::IDT
if (result.is_error()) if (result.is_error())
{ {
dwarnln("Demand paging: {}", result.error()); dwarnln("Demand paging: {}", result.error());
Thread::current().handle_signal(SIGKILL); Thread::current().handle_signal(SIGTERM);
goto done; goto done;
} }
} }

View File

@ -1,6 +1,6 @@
#include <BAN/Errors.h>
#include <kernel/Arch.h> #include <kernel/Arch.h>
#include <kernel/CPUID.h> #include <kernel/CPUID.h>
#include <kernel/InterruptController.h>
#include <kernel/LockGuard.h> #include <kernel/LockGuard.h>
#include <kernel/Memory/kmalloc.h> #include <kernel/Memory/kmalloc.h>
#include <kernel/Memory/PageTable.h> #include <kernel/Memory/PageTable.h>
@ -92,13 +92,6 @@ namespace Kernel
s_has_pge = true; s_has_pge = true;
} }
// enable write protect to kernel
asm volatile(
"movq %cr0, %rax;"
"orq $0x10000, %rax;"
"movq %rax, %cr0;"
);
ASSERT(s_kernel == nullptr); ASSERT(s_kernel == nullptr);
s_kernel = new PageTable(); s_kernel = new PageTable();
ASSERT(s_kernel); ASSERT(s_kernel);
@ -143,16 +136,8 @@ namespace Kernel
uint64_t* pml4 = (uint64_t*)P2V(m_highest_paging_struct); uint64_t* pml4 = (uint64_t*)P2V(m_highest_paging_struct);
pml4[511] = s_global_pml4e; pml4[511] = s_global_pml4e;
prepare_fast_page(); // Map (0 -> phys_kernel_end) to (KERNEL_OFFSET -> virt_kernel_end)
map_range_at(0, KERNEL_OFFSET, (uintptr_t)g_kernel_end - KERNEL_OFFSET, Flags::ReadWrite | Flags::Present);
// Map (phys_kernel_start -> phys_kernel_end) to (virt_kernel_start -> virt_kernel_end)
ASSERT((vaddr_t)g_kernel_start % PAGE_SIZE == 0);
map_range_at(
V2P(g_kernel_start),
(vaddr_t)g_kernel_start,
g_kernel_end - g_kernel_start,
Flags::ReadWrite | Flags::Present
);
// Map executable kernel memory as executable // Map executable kernel memory as executable
map_range_at( map_range_at(
@ -187,76 +172,6 @@ namespace Kernel
g_multiboot2_info = (multiboot2_info_t*)(multiboot2_vaddr + ((vaddr_t)g_multiboot2_info % PAGE_SIZE)); g_multiboot2_info = (multiboot2_info_t*)(multiboot2_vaddr + ((vaddr_t)g_multiboot2_info % PAGE_SIZE));
} }
void PageTable::prepare_fast_page()
{
constexpr vaddr_t uc_vaddr = uncanonicalize(fast_page());
constexpr uint64_t pml4e = (uc_vaddr >> 39) & 0x1FF;
constexpr uint64_t pdpte = (uc_vaddr >> 30) & 0x1FF;
constexpr uint64_t pde = (uc_vaddr >> 21) & 0x1FF;
constexpr uint64_t pte = (uc_vaddr >> 12) & 0x1FF;
uint64_t* pml4 = (uint64_t*)P2V(m_highest_paging_struct);
ASSERT(!(pml4[pml4e] & Flags::Present));
pml4[pml4e] = V2P(allocate_zeroed_page_aligned_page()) | Flags::ReadWrite | Flags::Present;
uint64_t* pdpt = (uint64_t*)P2V(pml4[pml4e] & PAGE_ADDR_MASK);
ASSERT(!(pdpt[pdpte] & Flags::Present));
pdpt[pdpte] = V2P(allocate_zeroed_page_aligned_page()) | Flags::ReadWrite | Flags::Present;
uint64_t* pd = (uint64_t*)P2V(pdpt[pdpte] & PAGE_ADDR_MASK);
ASSERT(!(pd[pde] & Flags::Present));
pd[pde] = V2P(allocate_zeroed_page_aligned_page()) | Flags::ReadWrite | Flags::Present;
uint64_t* pt = (uint64_t*)P2V(pd[pde] & PAGE_ADDR_MASK);
ASSERT(!(pt[pte] & Flags::Present));
pt[pte] = V2P(allocate_zeroed_page_aligned_page());
}
void PageTable::map_fast_page(paddr_t paddr)
{
ASSERT(s_kernel);
ASSERT_NEQ(paddr, 0);
ASSERT(!interrupts_enabled());
constexpr vaddr_t uc_vaddr = uncanonicalize(fast_page());
constexpr uint64_t pml4e = (uc_vaddr >> 39) & 0x1FF;
constexpr uint64_t pdpte = (uc_vaddr >> 30) & 0x1FF;
constexpr uint64_t pde = (uc_vaddr >> 21) & 0x1FF;
constexpr uint64_t pte = (uc_vaddr >> 12) & 0x1FF;
uint64_t* pml4 = (uint64_t*)P2V(s_kernel->m_highest_paging_struct);
uint64_t* pdpt = (uint64_t*)P2V(pml4[pml4e] & PAGE_ADDR_MASK);
uint64_t* pd = (uint64_t*)P2V(pdpt[pdpte] & PAGE_ADDR_MASK);
uint64_t* pt = (uint64_t*)P2V(pd[pde] & PAGE_ADDR_MASK);
ASSERT(!(pt[pte] & Flags::Present));
pt[pte] = paddr | Flags::ReadWrite | Flags::Present;
invalidate(fast_page());
}
void PageTable::unmap_fast_page()
{
ASSERT(s_kernel);
ASSERT(!interrupts_enabled());
constexpr vaddr_t uc_vaddr = uncanonicalize(fast_page());
constexpr uint64_t pml4e = (uc_vaddr >> 39) & 0x1FF;
constexpr uint64_t pdpte = (uc_vaddr >> 30) & 0x1FF;
constexpr uint64_t pde = (uc_vaddr >> 21) & 0x1FF;
constexpr uint64_t pte = (uc_vaddr >> 12) & 0x1FF;
uint64_t* pml4 = (uint64_t*)P2V(s_kernel->m_highest_paging_struct);
uint64_t* pdpt = (uint64_t*)P2V(pml4[pml4e] & PAGE_ADDR_MASK);
uint64_t* pd = (uint64_t*)P2V(pdpt[pdpte] & PAGE_ADDR_MASK);
uint64_t* pt = (uint64_t*)P2V(pd[pde] & PAGE_ADDR_MASK);
ASSERT(pt[pte] & Flags::Present);
pt[pte] = 0;
invalidate(fast_page());
}
BAN::ErrorOr<PageTable*> PageTable::create_userspace() BAN::ErrorOr<PageTable*> PageTable::create_userspace()
{ {
LockGuard _(s_kernel->m_lock); LockGuard _(s_kernel->m_lock);
@ -318,16 +233,13 @@ namespace Kernel
void PageTable::invalidate(vaddr_t vaddr) void PageTable::invalidate(vaddr_t vaddr)
{ {
ASSERT(vaddr % PAGE_SIZE == 0); ASSERT(vaddr % PAGE_SIZE == 0);
asm volatile("invlpg (%0)" :: "r"(vaddr) : "memory"); if (this == s_current)
asm volatile("invlpg (%0)" :: "r"(vaddr) : "memory");
} }
void PageTable::unmap_page(vaddr_t vaddr) void PageTable::unmap_page(vaddr_t vaddr)
{ {
ASSERT(vaddr); if (vaddr && (vaddr >= KERNEL_OFFSET) != (this == s_kernel))
ASSERT(vaddr != fast_page());
if (vaddr >= KERNEL_OFFSET)
ASSERT_GTE(vaddr, (vaddr_t)g_kernel_start);
if ((vaddr >= KERNEL_OFFSET) != (this == s_kernel))
Kernel::panic("unmapping {8H}, kernel: {}", vaddr, this == s_kernel); Kernel::panic("unmapping {8H}, kernel: {}", vaddr, this == s_kernel);
ASSERT(is_canonical(vaddr)); ASSERT(is_canonical(vaddr));
@ -369,11 +281,7 @@ namespace Kernel
void PageTable::map_page_at(paddr_t paddr, vaddr_t vaddr, flags_t flags) void PageTable::map_page_at(paddr_t paddr, vaddr_t vaddr, flags_t flags)
{ {
ASSERT(vaddr); if (vaddr && (vaddr >= KERNEL_OFFSET) != (this == s_kernel))
ASSERT(vaddr != fast_page());
if (vaddr >= KERNEL_OFFSET)
ASSERT_GTE(vaddr, (vaddr_t)g_kernel_start);
if ((vaddr >= KERNEL_OFFSET) != (this == s_kernel))
Kernel::panic("mapping {8H} to {8H}, kernel: {}", paddr, vaddr, this == s_kernel); Kernel::panic("mapping {8H} to {8H}, kernel: {}", paddr, vaddr, this == s_kernel);
ASSERT(is_canonical(vaddr)); ASSERT(is_canonical(vaddr));
@ -440,11 +348,12 @@ namespace Kernel
{ {
ASSERT(is_canonical(vaddr)); ASSERT(is_canonical(vaddr));
ASSERT(vaddr);
ASSERT(paddr % PAGE_SIZE == 0); ASSERT(paddr % PAGE_SIZE == 0);
ASSERT(vaddr % PAGE_SIZE == 0); ASSERT(vaddr % PAGE_SIZE == 0);
size_t page_count = range_page_count(vaddr, size); size_t first_page = vaddr / PAGE_SIZE;
size_t last_page = (vaddr + size - 1) / PAGE_SIZE;
size_t page_count = last_page - first_page + 1;
LockGuard _(m_lock); LockGuard _(m_lock);
for (size_t page = 0; page < page_count; page++) for (size_t page = 0; page < page_count; page++)
@ -521,8 +430,6 @@ namespace Kernel
vaddr_t PageTable::reserve_free_page(vaddr_t first_address, vaddr_t last_address) vaddr_t PageTable::reserve_free_page(vaddr_t first_address, vaddr_t last_address)
{ {
if (first_address >= KERNEL_OFFSET && first_address < (vaddr_t)g_kernel_end)
first_address = (vaddr_t)g_kernel_end;
if (size_t rem = first_address % PAGE_SIZE) if (size_t rem = first_address % PAGE_SIZE)
first_address += PAGE_SIZE - rem; first_address += PAGE_SIZE - rem;
if (size_t rem = last_address % PAGE_SIZE) if (size_t rem = last_address % PAGE_SIZE)
@ -580,9 +487,8 @@ namespace Kernel
vaddr |= (uint64_t)pdpte << 30; vaddr |= (uint64_t)pdpte << 30;
vaddr |= (uint64_t)pde << 21; vaddr |= (uint64_t)pde << 21;
vaddr |= (uint64_t)pte << 12; vaddr |= (uint64_t)pte << 12;
vaddr = canonicalize(vaddr);
ASSERT(reserve_page(vaddr)); ASSERT(reserve_page(vaddr));
return vaddr; return canonicalize(vaddr);
} }
} }
} }
@ -606,8 +512,6 @@ namespace Kernel
vaddr_t PageTable::reserve_free_contiguous_pages(size_t page_count, vaddr_t first_address, vaddr_t last_address) vaddr_t PageTable::reserve_free_contiguous_pages(size_t page_count, vaddr_t first_address, vaddr_t last_address)
{ {
if (first_address >= KERNEL_OFFSET && first_address < (vaddr_t)g_kernel_start)
first_address = (vaddr_t)g_kernel_start;
if (size_t rem = first_address % PAGE_SIZE) if (size_t rem = first_address % PAGE_SIZE)
first_address += PAGE_SIZE - rem; first_address += PAGE_SIZE - rem;
if (size_t rem = last_address % PAGE_SIZE) if (size_t rem = last_address % PAGE_SIZE)

View File

@ -8,19 +8,19 @@ _start:
pushq %rbp # rbp=0 pushq %rbp # rbp=0
movq %rsp, %rbp movq %rsp, %rbp
# Save argc, argv, environ # We need those in a moment when we call main.
pushq %rdx pushq %rdx
pushq %rsi pushq %rsi
pushq %rdi pushq %rdi
# Prepare malloc, environment # Prepare signals, memory allocation, stdio and such.
movq %rdx, %rdi movq %rdx, %rdi
call _init_libc call _init_libc
# Call global constructos # Run the global constructors.
call _init call _init
# Restore argc, argv, environ # Restore argc and argv.
popq %rdi popq %rdi
popq %rsi popq %rsi
popq %rdx popq %rdx
@ -28,8 +28,7 @@ _start:
# Run main # Run main
call main call main
# Cleanly exit the process # Terminate the process with the exit code.
movl %eax, %edi movl %eax, %edi
call exit call exit
.size _start, . - _start .size _start, . - _start

View File

@ -38,7 +38,6 @@ namespace Kernel
BAN::RefPtr<Inode> m_inode; BAN::RefPtr<Inode> m_inode;
const off_t m_offset; const off_t m_offset;
// FIXME: is this even synchronized?
BAN::RefPtr<SharedFileData> m_shared_data; BAN::RefPtr<SharedFileData> m_shared_data;
}; };

View File

@ -0,0 +1,46 @@
#pragma once
#include <BAN/LinkedList.h>
#include <BAN/Optional.h>
#include <BAN/UniqPtr.h>
#include <kernel/Memory/Heap.h>
#include <kernel/Memory/PageTable.h>
namespace Kernel
{
class GeneralAllocator
{
BAN_NON_COPYABLE(GeneralAllocator);
BAN_NON_MOVABLE(GeneralAllocator);
public:
static BAN::ErrorOr<BAN::UniqPtr<GeneralAllocator>> create(PageTable&, vaddr_t first_vaddr);
~GeneralAllocator();
BAN::ErrorOr<BAN::UniqPtr<GeneralAllocator>> clone(PageTable&);
BAN::Optional<paddr_t> paddr_of(vaddr_t);
vaddr_t allocate(size_t);
bool deallocate(vaddr_t);
private:
GeneralAllocator(PageTable&, vaddr_t first_vaddr);
private:
struct Allocation
{
vaddr_t address { 0 };
BAN::Vector<paddr_t> pages;
bool contains(vaddr_t);
};
private:
PageTable& m_page_table;
BAN::LinkedList<Allocation> m_allocations;
const vaddr_t m_first_vaddr;
};
}

View File

@ -29,24 +29,6 @@ namespace Kernel
static PageTable& kernel(); static PageTable& kernel();
static PageTable& current(); static PageTable& current();
static void map_fast_page(paddr_t);
static void unmap_fast_page();
static constexpr vaddr_t fast_page() { return KERNEL_OFFSET; }
// FIXME: implement sized checks, return span, etc
static void* fast_page_as_ptr(size_t offset = 0)
{
ASSERT(offset <= PAGE_SIZE);
return reinterpret_cast<void*>(fast_page() + offset);
}
template<typename T>
static T& fast_page_as(size_t offset = 0)
{
ASSERT(offset + sizeof(T) <= PAGE_SIZE);
return *reinterpret_cast<T*>(fast_page() + offset);
}
static bool is_valid_pointer(uintptr_t); static bool is_valid_pointer(uintptr_t);
static BAN::ErrorOr<PageTable*> create_userspace(); static BAN::ErrorOr<PageTable*> create_userspace();
@ -82,8 +64,7 @@ namespace Kernel
uint64_t get_page_data(vaddr_t) const; uint64_t get_page_data(vaddr_t) const;
void initialize_kernel(); void initialize_kernel();
void map_kernel_memory(); void map_kernel_memory();
void prepare_fast_page(); void invalidate(vaddr_t);
static void invalidate(vaddr_t);
private: private:
paddr_t m_highest_paging_struct { 0 }; paddr_t m_highest_paging_struct { 0 };

View File

@ -11,11 +11,11 @@ namespace Kernel::detail
template<typename... Args> template<typename... Args>
__attribute__((__noreturn__)) __attribute__((__noreturn__))
static void panic_impl(const char* file, int line, const char* message, Args&&... args) static void panic_impl(const char* file, int line, const char* message, Args... args)
{ {
asm volatile("cli"); asm volatile("cli");
derrorln("Kernel panic at {}:{}", file, line); derrorln("Kernel panic at {}:{}", file, line);
derrorln(message, BAN::forward<Args>(args)...); derrorln(message, args...);
if (!g_paniced) if (!g_paniced)
{ {
g_paniced = true; g_paniced = true;

View File

@ -71,7 +71,6 @@ namespace Kernel
vaddr_t stack_base() const { return m_stack->vaddr(); } vaddr_t stack_base() const { return m_stack->vaddr(); }
size_t stack_size() const { return m_stack->size(); } size_t stack_size() const { return m_stack->size(); }
VirtualRange& stack() { return *m_stack; } VirtualRange& stack() { return *m_stack; }
VirtualRange& interrupt_stack() { return *m_interrupt_stack; }
vaddr_t interrupt_stack_base() const { return m_interrupt_stack ? m_interrupt_stack->vaddr() : 0; } vaddr_t interrupt_stack_base() const { return m_interrupt_stack ? m_interrupt_stack->vaddr() : 0; }
size_t interrupt_stack_size() const { return m_interrupt_stack ? m_interrupt_stack->size() : 0; } size_t interrupt_stack_size() const { return m_interrupt_stack ? m_interrupt_stack->size() : 0; }

View File

@ -117,33 +117,33 @@ namespace Kernel
if (rsdp->revision >= 2) if (rsdp->revision >= 2)
{ {
PageTable::map_fast_page(rsdp->xsdt_address & PAGE_ADDR_MASK); PageTable::kernel().map_page_at(rsdp->xsdt_address & PAGE_ADDR_MASK, 0, PageTable::Flags::Present);
auto& xsdt = PageTable::fast_page_as<const XSDT>(rsdp->xsdt_address % PAGE_SIZE); const XSDT* xsdt = (const XSDT*)(rsdp->xsdt_address % PAGE_SIZE);
BAN::ScopeGuard _([] { PageTable::unmap_fast_page(); }); BAN::ScopeGuard _([xsdt] { PageTable::kernel().unmap_page(0); });
if (memcmp(xsdt.signature, "XSDT", 4) != 0) if (memcmp(xsdt->signature, "XSDT", 4) != 0)
return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid); return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid);
if (!is_valid_std_header(&xsdt)) if (!is_valid_std_header(xsdt))
return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid); return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid);
m_header_table_paddr = rsdp->xsdt_address + offsetof(XSDT, entries); m_header_table_paddr = (paddr_t)xsdt->entries + (rsdp->rsdt_address & PAGE_ADDR_MASK);
m_entry_size = 8; m_entry_size = 8;
root_entry_count = (xsdt.length - sizeof(SDTHeader)) / 8; root_entry_count = (xsdt->length - sizeof(SDTHeader)) / 8;
} }
else else
{ {
PageTable::map_fast_page(rsdp->rsdt_address & PAGE_ADDR_MASK); PageTable::kernel().map_page_at(rsdp->rsdt_address & PAGE_ADDR_MASK, 0, PageTable::Flags::Present);
auto& rsdt = PageTable::fast_page_as<const RSDT>(rsdp->rsdt_address % PAGE_SIZE); const RSDT* rsdt = (const RSDT*)((vaddr_t)rsdp->rsdt_address % PAGE_SIZE);
BAN::ScopeGuard _([] { PageTable::unmap_fast_page(); }); BAN::ScopeGuard _([rsdt] { PageTable::kernel().unmap_page(0); });
if (memcmp(rsdt.signature, "RSDT", 4) != 0) if (memcmp(rsdt->signature, "RSDT", 4) != 0)
return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid); return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid);
if (!is_valid_std_header(&rsdt)) if (!is_valid_std_header(rsdt))
return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid); return BAN::Error::from_error_code(ErrorCode::ACPI_RootInvalid);
m_header_table_paddr = rsdp->rsdt_address + offsetof(RSDT, entries); m_header_table_paddr = (paddr_t)rsdt->entries + (rsdp->rsdt_address & PAGE_ADDR_MASK);
m_entry_size = 4; m_entry_size = 4;
root_entry_count = (rsdt.length - sizeof(SDTHeader)) / 4; root_entry_count = (rsdt->length - sizeof(SDTHeader)) / 4;
} }
size_t needed_pages = range_page_count(m_header_table_paddr, root_entry_count * m_entry_size); size_t needed_pages = range_page_count(m_header_table_paddr, root_entry_count * m_entry_size);
@ -162,9 +162,9 @@ namespace Kernel
auto map_header = auto map_header =
[](paddr_t header_paddr) -> vaddr_t [](paddr_t header_paddr) -> vaddr_t
{ {
PageTable::map_fast_page(header_paddr & PAGE_ADDR_MASK); PageTable::kernel().map_page_at(header_paddr & PAGE_ADDR_MASK, 0, PageTable::Flags::Present);
size_t header_length = PageTable::fast_page_as<SDTHeader>(header_paddr % PAGE_SIZE).length; size_t header_length = ((SDTHeader*)(header_paddr % PAGE_SIZE))->length;
PageTable::unmap_fast_page(); PageTable::kernel().unmap_page(0);
size_t needed_pages = range_page_count(header_paddr, header_length); size_t needed_pages = range_page_count(header_paddr, header_length);
vaddr_t page_vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET); vaddr_t page_vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET);
@ -211,10 +211,7 @@ namespace Kernel
if (memcmp(header->signature, "FACP", 4) == 0) if (memcmp(header->signature, "FACP", 4) == 0)
{ {
auto* fadt = (FADT*)header; auto* fadt = (FADT*)header;
paddr_t dsdt_paddr = fadt->x_dsdt;
paddr_t dsdt_paddr = 0;
if (fadt->length > offsetof(FADT, x_dsdt))
dsdt_paddr = fadt->x_dsdt;
if (dsdt_paddr == 0 || !PageTable::is_valid_pointer(dsdt_paddr)) if (dsdt_paddr == 0 || !PageTable::is_valid_pointer(dsdt_paddr))
dsdt_paddr = fadt->dsdt; dsdt_paddr = fadt->dsdt;

View File

@ -274,9 +274,6 @@ namespace Kernel
{ {
ASSERT(m_inode.links_count == 0); ASSERT(m_inode.links_count == 0);
if (mode().iflnk() && (size_t)size() < sizeof(m_inode.block))
goto done;
// cleanup direct blocks // cleanup direct blocks
for (uint32_t i = 0; i < 12; i++) for (uint32_t i = 0; i < 12; i++)
if (m_inode.block[i]) if (m_inode.block[i])
@ -290,7 +287,6 @@ namespace Kernel
if (m_inode.block[14]) if (m_inode.block[14])
cleanup_indirect_block(m_inode.block[14], 3); cleanup_indirect_block(m_inode.block[14], 3);
done:
// mark blocks as deleted // mark blocks as deleted
memset(m_inode.block, 0x00, sizeof(m_inode.block)); memset(m_inode.block, 0x00, sizeof(m_inode.block));
@ -763,7 +759,7 @@ needs_new_block:
if (data_block_index < indices_per_fs_block * indices_per_fs_block) if (data_block_index < indices_per_fs_block * indices_per_fs_block)
return TRY(allocate_new_block_to_indirect_block(m_inode.block[13], data_block_index, 2)); return TRY(allocate_new_block_to_indirect_block(m_inode.block[13], data_block_index, 2));
data_block_index -= indices_per_fs_block * indices_per_fs_block; data_block_index -= indices_per_fs_block;
if (data_block_index < indices_per_fs_block * indices_per_fs_block * indices_per_fs_block) if (data_block_index < indices_per_fs_block * indices_per_fs_block * indices_per_fs_block)
return TRY(allocate_new_block_to_indirect_block(m_inode.block[14], data_block_index, 3)); return TRY(allocate_new_block_to_indirect_block(m_inode.block[14], data_block_index, 3));

View File

@ -1,4 +1,3 @@
#include <kernel/CriticalScope.h>
#include <kernel/LockGuard.h> #include <kernel/LockGuard.h>
#include <kernel/Memory/FileBackedRegion.h> #include <kernel/Memory/FileBackedRegion.h>
#include <kernel/Memory/Heap.h> #include <kernel/Memory/Heap.h>
@ -72,10 +71,13 @@ namespace Kernel
continue; continue;
{ {
CriticalScope _; auto& page_table = PageTable::current();
PageTable::map_fast_page(pages[i]); LockGuard _(page_table);
memcpy(page_buffer, PageTable::fast_page_as_ptr(), PAGE_SIZE); ASSERT(page_table.is_page_free(0));
PageTable::unmap_fast_page();
page_table.map_page_at(pages[i], 0, PageTable::Flags::Present);
memcpy(page_buffer, (void*)0, PAGE_SIZE);
page_table.unmap_page(0);
} }
if (auto ret = inode->write(i * PAGE_SIZE, BAN::ConstByteSpan::from(page_buffer)); ret.is_error()) if (auto ret = inode->write(i * PAGE_SIZE, BAN::ConstByteSpan::from(page_buffer)); ret.is_error())
@ -98,15 +100,28 @@ namespace Kernel
paddr_t paddr = Heap::get().take_free_page(); paddr_t paddr = Heap::get().take_free_page();
if (paddr == 0) if (paddr == 0)
return BAN::Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
m_page_table.map_page_at(paddr, vaddr, m_flags);
// Temporarily force mapping to be writable so kernel can write to it
m_page_table.map_page_at(paddr, vaddr, m_flags | PageTable::Flags::ReadWrite);
size_t file_offset = m_offset + (vaddr - m_vaddr); size_t file_offset = m_offset + (vaddr - m_vaddr);
size_t bytes = BAN::Math::min<size_t>(m_size - file_offset, PAGE_SIZE); size_t bytes = BAN::Math::min<size_t>(m_size - file_offset, PAGE_SIZE);
ASSERT_EQ(&PageTable::current(), &m_page_table); BAN::ErrorOr<size_t> read_ret = 0;
auto read_ret = m_inode->read(file_offset, BAN::ByteSpan((uint8_t*)vaddr, bytes));
// Zero out the new page
if (&PageTable::current() == &m_page_table)
read_ret = m_inode->read(file_offset, BAN::ByteSpan((uint8_t*)vaddr, bytes));
else
{
auto& page_table = PageTable::current();
LockGuard _(page_table);
ASSERT(page_table.is_page_free(0));
page_table.map_page_at(paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
read_ret = m_inode->read(file_offset, BAN::ByteSpan((uint8_t*)0, bytes));
memset((void*)0, 0x00, PAGE_SIZE);
page_table.unmap_page(0);
}
if (read_ret.is_error()) if (read_ret.is_error())
{ {
@ -122,10 +137,6 @@ namespace Kernel
m_page_table.unmap_page(vaddr); m_page_table.unmap_page(vaddr);
return BAN::Error::from_errno(EIO); return BAN::Error::from_errno(EIO);
} }
// Disable writable if not wanted
if (!(m_flags & PageTable::Flags::ReadWrite))
m_page_table.map_page_at(paddr, vaddr, m_flags);
} }
else if (m_type == Type::SHARED) else if (m_type == Type::SHARED)
{ {
@ -147,10 +158,15 @@ namespace Kernel
TRY(m_inode->read(offset, BAN::ByteSpan(m_shared_data->page_buffer, bytes))); TRY(m_inode->read(offset, BAN::ByteSpan(m_shared_data->page_buffer, bytes)));
CriticalScope _; auto& page_table = PageTable::current();
PageTable::map_fast_page(pages[page_index]);
memcpy(PageTable::fast_page_as_ptr(), m_shared_data->page_buffer, PAGE_SIZE); // TODO: check if this can cause deadlock?
PageTable::unmap_fast_page(); LockGuard page_table_lock(page_table);
ASSERT(page_table.is_page_free(0));
page_table.map_page_at(pages[page_index], 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
memcpy((void*)0, m_shared_data->page_buffer, PAGE_SIZE);
page_table.unmap_page(0);
} }
paddr_t paddr = pages[page_index]; paddr_t paddr = pages[page_index];

View File

@ -0,0 +1,145 @@
#include <kernel/Memory/GeneralAllocator.h>
namespace Kernel
{
BAN::ErrorOr<BAN::UniqPtr<GeneralAllocator>> GeneralAllocator::create(PageTable& page_table, vaddr_t first_vaddr)
{
auto* allocator = new GeneralAllocator(page_table, first_vaddr);
if (allocator == nullptr)
return BAN::Error::from_errno(ENOMEM);
return BAN::UniqPtr<GeneralAllocator>::adopt(allocator);
}
GeneralAllocator::GeneralAllocator(PageTable& page_table, vaddr_t first_vaddr)
: m_page_table(page_table)
, m_first_vaddr(first_vaddr)
{ }
GeneralAllocator::~GeneralAllocator()
{
while (!m_allocations.empty())
deallocate(m_allocations.front().address);
}
vaddr_t GeneralAllocator::allocate(size_t bytes)
{
size_t needed_pages = BAN::Math::div_round_up<size_t>(bytes, PAGE_SIZE);
Allocation allocation;
if (allocation.pages.resize(needed_pages, 0).is_error())
return 0;
for (size_t i = 0; i < needed_pages; i++)
{
paddr_t paddr = Heap::get().take_free_page();
if (paddr == 0)
{
for (size_t j = 0; j < i; j++)
Heap::get().release_page(allocation.pages[j]);
return 0;
}
allocation.pages[i] = paddr;
}
m_page_table.lock();
allocation.address = m_page_table.reserve_free_contiguous_pages(needed_pages, m_first_vaddr);
ASSERT(allocation.address);
for (size_t i = 0; i < needed_pages; i++)
{
vaddr_t vaddr = allocation.address + i * PAGE_SIZE;
m_page_table.map_page_at(allocation.pages[i], vaddr, PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present);
}
if (&m_page_table == &PageTable::current())
m_page_table.load();
m_page_table.unlock();
MUST(m_allocations.push_back(BAN::move(allocation)));
return allocation.address;
}
bool GeneralAllocator::deallocate(vaddr_t address)
{
for (auto it = m_allocations.begin(); it != m_allocations.end(); it++)
{
if (it->address != address)
continue;
m_page_table.unmap_range(it->address, it->pages.size() * PAGE_SIZE);
for (auto paddr : it->pages)
Heap::get().release_page(paddr);
m_allocations.remove(it);
return true;
}
return false;
}
BAN::ErrorOr<BAN::UniqPtr<GeneralAllocator>> GeneralAllocator::clone(PageTable& new_page_table)
{
auto allocator = TRY(GeneralAllocator::create(new_page_table, m_first_vaddr));
m_page_table.lock();
ASSERT(m_page_table.is_page_free(0));
for (auto& allocation : m_allocations)
{
Allocation new_allocation;
ASSERT(new_page_table.is_range_free(allocation.address, allocation.pages.size() * PAGE_SIZE));
new_allocation.address = allocation.address;
MUST(new_allocation.pages.reserve(allocation.pages.size()));
PageTable::flags_t flags = m_page_table.get_page_flags(allocation.address);
for (size_t i = 0; i < allocation.pages.size(); i++)
{
paddr_t paddr = Heap::get().take_free_page();
ASSERT(paddr);
vaddr_t vaddr = allocation.address + i * PAGE_SIZE;
MUST(new_allocation.pages.push_back(paddr));
new_page_table.map_page_at(paddr, vaddr, flags);
m_page_table.map_page_at(paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
memcpy((void*)0, (void*)vaddr, PAGE_SIZE);
}
MUST(allocator->m_allocations.push_back(BAN::move(new_allocation)));
}
m_page_table.unmap_page(0);
m_page_table.unlock();
return allocator;
}
BAN::Optional<paddr_t> GeneralAllocator::paddr_of(vaddr_t vaddr)
{
for (auto& allocation : m_allocations)
{
if (!allocation.contains(vaddr))
continue;
size_t offset = vaddr - allocation.address;
size_t page_index = offset / PAGE_SIZE;
size_t page_offset = offset % PAGE_SIZE;
return allocation.pages[page_index] + page_offset;
}
return {};
}
bool GeneralAllocator::Allocation::contains(vaddr_t vaddr)
{
return this->address <= vaddr && vaddr < this->address + this->pages.size() * PAGE_SIZE;
}
}

View File

@ -1,4 +1,3 @@
#include <kernel/CriticalScope.h>
#include <kernel/LockGuard.h> #include <kernel/LockGuard.h>
#include <kernel/Memory/Heap.h> #include <kernel/Memory/Heap.h>
#include <kernel/Memory/MemoryBackedRegion.h> #include <kernel/Memory/MemoryBackedRegion.h>
@ -61,10 +60,12 @@ namespace Kernel
memset((void*)vaddr, 0x00, PAGE_SIZE); memset((void*)vaddr, 0x00, PAGE_SIZE);
else else
{ {
CriticalScope _; LockGuard _(PageTable::current());
PageTable::map_fast_page(paddr); ASSERT(PageTable::current().is_page_free(0));
memset(PageTable::fast_page_as_ptr(), 0x00, PAGE_SIZE);
PageTable::unmap_fast_page(); PageTable::current().map_page_at(paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
memset((void*)0, 0x00, PAGE_SIZE);
PageTable::current().unmap_page(0);
} }
return true; return true;
@ -104,10 +105,15 @@ namespace Kernel
memcpy((void*)write_vaddr, (void*)(buffer + written), bytes); memcpy((void*)write_vaddr, (void*)(buffer + written), bytes);
else else
{ {
CriticalScope _; paddr_t paddr = m_page_table.physical_address_of(write_vaddr & PAGE_ADDR_MASK);
PageTable::map_fast_page(m_page_table.physical_address_of(write_vaddr & PAGE_ADDR_MASK)); ASSERT(paddr);
memcpy(PageTable::fast_page_as_ptr(page_offset), (void*)(buffer + written), bytes);
PageTable::unmap_fast_page(); LockGuard _(PageTable::current());
ASSERT(PageTable::current().is_page_free(0));
PageTable::current().map_page_at(paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
memcpy((void*)page_offset, (void*)(buffer + written), bytes);
PageTable::current().unmap_page(0);
} }
written += bytes; written += bytes;

View File

@ -1,4 +1,3 @@
#include <kernel/CriticalScope.h>
#include <kernel/LockGuard.h> #include <kernel/LockGuard.h>
#include <kernel/Memory/Heap.h> #include <kernel/Memory/Heap.h>
#include <kernel/Memory/VirtualRange.h> #include <kernel/Memory/VirtualRange.h>
@ -125,6 +124,7 @@ namespace Kernel
auto result = TRY(create_to_vaddr(page_table, vaddr(), size(), flags(), m_preallocated)); auto result = TRY(create_to_vaddr(page_table, vaddr(), size(), flags(), m_preallocated));
LockGuard _(m_page_table); LockGuard _(m_page_table);
ASSERT(m_page_table.is_page_free(0));
for (size_t offset = 0; offset < size(); offset += PAGE_SIZE) for (size_t offset = 0; offset < size(); offset += PAGE_SIZE)
{ {
if (!m_preallocated && m_page_table.physical_address_of(vaddr() + offset)) if (!m_preallocated && m_page_table.physical_address_of(vaddr() + offset))
@ -134,12 +134,10 @@ namespace Kernel
return BAN::Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
result->m_page_table.map_page_at(paddr, vaddr() + offset, m_flags); result->m_page_table.map_page_at(paddr, vaddr() + offset, m_flags);
} }
m_page_table.map_page_at(result->m_page_table.physical_address_of(vaddr() + offset), 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
CriticalScope _; memcpy((void*)0, (void*)(vaddr() + offset), PAGE_SIZE);
PageTable::map_fast_page(result->m_page_table.physical_address_of(vaddr() + offset));
memcpy(PageTable::fast_page_as_ptr(), (void*)(vaddr() + offset), PAGE_SIZE);
PageTable::unmap_fast_page();
} }
m_page_table.unmap_page(0);
return result; return result;
} }
@ -174,13 +172,14 @@ namespace Kernel
return; return;
} }
LockGuard _(page_table);
ASSERT(page_table.is_page_free(0));
for (size_t offset = 0; offset < size(); offset += PAGE_SIZE) for (size_t offset = 0; offset < size(); offset += PAGE_SIZE)
{ {
CriticalScope _; page_table.map_page_at(m_page_table.physical_address_of(vaddr() + offset), 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
PageTable::map_fast_page(m_page_table.physical_address_of(vaddr() + offset)); memset((void*)0, 0, PAGE_SIZE);
memset(PageTable::fast_page_as_ptr(), 0x00, PAGE_SIZE);
PageTable::unmap_fast_page();
} }
page_table.unmap_page(0);
} }
void VirtualRange::copy_from(size_t offset, const uint8_t* buffer, size_t bytes) void VirtualRange::copy_from(size_t offset, const uint8_t* buffer, size_t bytes)
@ -188,34 +187,47 @@ namespace Kernel
if (bytes == 0) if (bytes == 0)
return; return;
// Verify no overflow // NOTE: Handling overflow
ASSERT_LTE(bytes, size()); ASSERT(offset <= size());
ASSERT_LTE(offset, size()); ASSERT(bytes <= size());
ASSERT_LTE(offset, size() - bytes); ASSERT(offset + bytes <= size());
if (m_kmalloc || &PageTable::current() == &m_page_table) PageTable& page_table = PageTable::current();
if (m_kmalloc || &page_table == &m_page_table)
{ {
memcpy((void*)(vaddr() + offset), buffer, bytes); memcpy((void*)(vaddr() + offset), buffer, bytes);
return; return;
} }
size_t page_offset = offset % PAGE_SIZE; LockGuard _(page_table);
size_t page_index = offset / PAGE_SIZE; ASSERT(page_table.is_page_free(0));
size_t off = offset % PAGE_SIZE;
size_t i = offset / PAGE_SIZE;
// NOTE: we map the first page separately since it needs extra calculations
page_table.map_page_at(m_page_table.physical_address_of(vaddr() + i * PAGE_SIZE), 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
memcpy((void*)off, buffer, PAGE_SIZE - off);
buffer += PAGE_SIZE - off;
bytes -= PAGE_SIZE - off;
i++;
while (bytes > 0) while (bytes > 0)
{ {
{ size_t len = BAN::Math::min<size_t>(PAGE_SIZE, bytes);
CriticalScope _;
PageTable::map_fast_page(m_page_table.physical_address_of(vaddr() + page_index * PAGE_SIZE));
memcpy(PageTable::fast_page_as_ptr(page_offset), buffer, PAGE_SIZE - page_offset);
PageTable::unmap_fast_page();
}
buffer += PAGE_SIZE - page_offset; page_table.map_page_at(m_page_table.physical_address_of(vaddr() + i * PAGE_SIZE), 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
bytes -= PAGE_SIZE - page_offset;
page_offset = 0; memcpy((void*)0, buffer, len);
page_index++;
buffer += len;
bytes -= len;
i++;
} }
page_table.unmap_page(0);
} }
} }

View File

@ -1,6 +1,7 @@
#include <BAN/Errors.h> #include <BAN/Errors.h>
#include <kernel/CriticalScope.h> #include <kernel/CriticalScope.h>
#include <kernel/kprint.h> #include <kernel/kprint.h>
#include <kernel/Memory/GeneralAllocator.h>
#include <kernel/Memory/kmalloc.h> #include <kernel/Memory/kmalloc.h>
#include <kernel/Thread.h> #include <kernel/Thread.h>

View File

@ -47,9 +47,9 @@ namespace Kernel
continue; continue;
CriticalScope _; CriticalScope _;
PageTable::map_fast_page(cache.paddr); page_table.map_page_at(cache.paddr, 0, PageTable::Flags::Present);
memcpy(buffer.data(), PageTable::fast_page_as_ptr(page_cache_offset * m_sector_size), m_sector_size); memcpy(buffer.data(), (void*)(page_cache_offset * m_sector_size), m_sector_size);
PageTable::unmap_fast_page(); page_table.unmap_page(0);
return true; return true;
} }
@ -82,9 +82,9 @@ namespace Kernel
{ {
CriticalScope _; CriticalScope _;
PageTable::map_fast_page(cache.paddr); page_table.map_page_at(cache.paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
memcpy(PageTable::fast_page_as_ptr(page_cache_offset * m_sector_size), buffer.data(), m_sector_size); memcpy((void*)(page_cache_offset * m_sector_size), buffer.data(), m_sector_size);
PageTable::unmap_fast_page(); page_table.unmap_page(0);
} }
cache.sector_mask |= 1 << page_cache_offset; cache.sector_mask |= 1 << page_cache_offset;
@ -113,9 +113,9 @@ namespace Kernel
{ {
CriticalScope _; CriticalScope _;
PageTable::map_fast_page(cache.paddr); page_table.map_page_at(cache.paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
memcpy(PageTable::fast_page_as_ptr(page_cache_offset * m_sector_size), buffer.data(), m_sector_size); memcpy((void*)(page_cache_offset * m_sector_size), buffer.data(), m_sector_size);
PageTable::unmap_fast_page(); page_table.unmap_page(0);
} }
return {}; return {};
@ -123,16 +123,21 @@ namespace Kernel
BAN::ErrorOr<void> DiskCache::sync() BAN::ErrorOr<void> DiskCache::sync()
{ {
ASSERT(&PageTable::current() == &PageTable::kernel());
auto& page_table = PageTable::kernel();
for (auto& cache : m_cache) for (auto& cache : m_cache)
{ {
if (cache.dirty_mask == 0) if (cache.dirty_mask == 0)
continue; continue;
{ {
CriticalScope _; LockGuard _(page_table);
PageTable::map_fast_page(cache.paddr); ASSERT(page_table.is_page_free(0));
memcpy(m_sync_cache.data(), PageTable::fast_page_as_ptr(), PAGE_SIZE);
PageTable::unmap_fast_page(); page_table.map_page_at(cache.paddr, 0, PageTable::Flags::Present);
memcpy(m_sync_cache.data(), (void*)0, PAGE_SIZE);
page_table.unmap_page(0);
} }
uint8_t sector_start = 0; uint8_t sector_start = 0;

View File

@ -79,6 +79,9 @@ static void parse_command_line()
} }
} }
extern "C" uint8_t g_userspace_start[];
extern "C" uint8_t g_userspace_end[];
TerminalDriver* g_terminal_driver = nullptr; TerminalDriver* g_terminal_driver = nullptr;
static void init2(void*); static void init2(void*);

View File

@ -26,32 +26,21 @@ set(LIBC_SOURCES
) )
add_custom_target(libc-headers add_custom_target(libc-headers
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/ COMMAND sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
DEPENDS sysroot DEPENDS sysroot
) USES_TERMINAL
add_custom_target(crtx
COMMAND ${CMAKE_C_COMPILER} -c ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/crt0.S -o crt0.o
COMMAND ${CMAKE_C_COMPILER} -c ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/crti.S -o crti.o
COMMAND ${CMAKE_C_COMPILER} -c ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/crtn.S -o crtn.o
)
add_custom_target(crtx-install
COMMAND ${CMAKE_COMMAND} -E copy crt0.o ${BANAN_LIB}/
COMMAND ${CMAKE_COMMAND} -E copy crti.o ${BANAN_LIB}/
COMMAND ${CMAKE_COMMAND} -E copy crtn.o ${BANAN_LIB}/
DEPENDS crtx
) )
add_library(libc ${LIBC_SOURCES}) add_library(libc ${LIBC_SOURCES})
add_dependencies(libc headers crtx-install) add_dependencies(libc headers crt0)
target_compile_options(libc PRIVATE -g -Wstack-usage=512) target_compile_options(libc PRIVATE -g -Wstack-usage=512)
add_custom_target(libc-install add_custom_target(libc-install
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/libc.a ${BANAN_LIB}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/libc.a ${BANAN_LIB}/
DEPENDS libc DEPENDS libc
BYPRODUCTS ${BANAN_LIB}/libc.a BYPRODUCTS ${BANAN_LIB}/libc.a
USES_TERMINAL
) )
set(CMAKE_STATIC_LIBRARY_PREFIX "") set(CMAKE_STATIC_LIBRARY_PREFIX "")

View File

@ -1,16 +0,0 @@
/* x86-64 crti.s */
.section .init
.global _init
.type _init, @function
_init:
pushq %rbp
movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .init section here. */
.section .fini
.global _fini
.type _fini, @function
_fini:
pushq %rbp
movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */

View File

@ -1,10 +0,0 @@
/* x86-64 crtn.s */
.section .init
/* gcc will nicely put the contents of crtend.o's .init section here. */
popq %rbp
ret
.section .fini
/* gcc will nicely put the contents of crtend.o's .fini section here. */
popq %rbp
ret

View File

@ -1,37 +1,35 @@
#include <icxxabi.h>
#define ATEXIT_MAX_FUNCS 128 #define ATEXIT_MAX_FUNCS 128
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned uarch_t;
struct atexit_func_entry_t struct atexit_func_entry_t
{ {
void (*destructor)(void*); /*
void* data; * Each member is at least 4 bytes large. Such that each entry is 12bytes.
void* dso_handle; * 128 * 12 = 1.5KB exact.
**/
void (*destructor_func)(void *);
void *obj_ptr;
void *dso_handle;
}; };
static atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS]; atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS];
static int __atexit_func_count = 0; uarch_t __atexit_func_count = 0;
int __cxa_atexit(void (*func)(void*), void* data, void* dso_handle) int __cxa_atexit(void (*f)(void *), void *objptr, void *dso)
{ {
if (__atexit_func_count >= ATEXIT_MAX_FUNCS) if (__atexit_func_count >= ATEXIT_MAX_FUNCS) {return -1;};
return -1;; __atexit_funcs[__atexit_func_count].destructor_func = f;
__atexit_funcs[__atexit_func_count].destructor = func; __atexit_funcs[__atexit_func_count].obj_ptr = objptr;
__atexit_funcs[__atexit_func_count].data = data; __atexit_funcs[__atexit_func_count].dso_handle = dso;
__atexit_funcs[__atexit_func_count].dso_handle = dso_handle;
__atexit_func_count++; __atexit_func_count++;
return 0; return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/
}; };
void __cxa_finalize(void* func) #ifdef __cplusplus
{ };
for (int i = __atexit_func_count - 1; i >= 0; i--) #endif
{
if (func && func != __atexit_funcs[i].destructor)
continue;
if (__atexit_funcs[i].destructor == nullptr)
continue;
__atexit_funcs[i].destructor(__atexit_funcs[i].data);
__atexit_funcs[i].destructor = nullptr;
}
}

View File

@ -1,10 +0,0 @@
#pragma once
#include <sys/cdefs.h>
__BEGIN_DECLS
int __cxa_atexit(void (*func)(void*), void* data, void* dso_handle);
void __cxa_finalize(void* func);
__END_DECLS

View File

@ -7,8 +7,6 @@
#include <sys/syscall.h> #include <sys/syscall.h>
#include <unistd.h> #include <unistd.h>
#include <icxxabi.h>
extern "C" char** environ; extern "C" char** environ;
extern "C" void _fini(); extern "C" void _fini();
@ -23,7 +21,6 @@ void abort(void)
void exit(int status) void exit(int status)
{ {
fflush(nullptr); fflush(nullptr);
__cxa_finalize(nullptr);
_fini(); _fini();
_exit(status); _exit(status);
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();

View File

@ -4,12 +4,6 @@ set -e
export BANAN_SCRIPT_DIR=$(dirname $(realpath $0)) export BANAN_SCRIPT_DIR=$(dirname $(realpath $0))
source $BANAN_SCRIPT_DIR/config.sh source $BANAN_SCRIPT_DIR/config.sh
FAKEROOT_FILE="$BANAN_BUILD_DIR/fakeroot-context"
run_fakeroot() {
fakeroot -i $FAKEROOT_FILE -s $FAKEROOT_FILE -- /bin/bash -c '$@' bash $@
}
make_build_dir () { make_build_dir () {
mkdir -p $BANAN_BUILD_DIR mkdir -p $BANAN_BUILD_DIR
cd $BANAN_BUILD_DIR cd $BANAN_BUILD_DIR
@ -25,7 +19,7 @@ build_target () {
exit 1 exit 1
fi fi
cd $BANAN_BUILD_DIR cd $BANAN_BUILD_DIR
run_fakeroot ninja $1 ninja $1
} }
build_toolchain () { build_toolchain () {
@ -45,7 +39,11 @@ build_toolchain () {
create_image () { create_image () {
build_target install-sysroot build_target install-sysroot
$BANAN_SCRIPT_DIR/image.sh "$1" if [[ "$1" == "full" ]]; then
$BANAN_SCRIPT_DIR/image-full.sh
else
$BANAN_SCRIPT_DIR/image.sh
fi
} }
run_qemu () { run_qemu () {
@ -58,7 +56,7 @@ run_bochs () {
$BANAN_SCRIPT_DIR/bochs.sh $@ $BANAN_SCRIPT_DIR/bochs.sh $@
} }
if [[ -c /dev/kvm ]]; then if [[ "$(uname)" == "Linux" ]]; then
QEMU_ACCEL="-accel kvm" QEMU_ACCEL="-accel kvm"
fi fi

View File

@ -18,7 +18,6 @@ export BANAN_TOOLCHAIN_TRIPLE_PREFIX=$BANAN_ARCH-banan_os
export BANAN_BUILD_DIR=$BANAN_ROOT_DIR/build export BANAN_BUILD_DIR=$BANAN_ROOT_DIR/build
export BANAN_SYSROOT=$BANAN_BUILD_DIR/sysroot export BANAN_SYSROOT=$BANAN_BUILD_DIR/sysroot
export BANAN_SYSROOT_TAR=$BANAN_SYSROOT.tar
export BANAN_DISK_IMAGE_PATH=$BANAN_BUILD_DIR/banan-os.img export BANAN_DISK_IMAGE_PATH=$BANAN_BUILD_DIR/banan-os.img

View File

@ -72,7 +72,7 @@ sudo partprobe $LOOP_DEV
PARTITION1=${LOOP_DEV}p1 PARTITION1=${LOOP_DEV}p1
PARTITION2=${LOOP_DEV}p2 PARTITION2=${LOOP_DEV}p2
sudo mkfs.ext2 -b 1024 -q $PARTITION2 sudo mkfs.ext2 -d $BANAN_SYSROOT -b 1024 -q $PARTITION2
if [[ "$BANAN_UEFI_BOOT" == "1" ]]; then if [[ "$BANAN_UEFI_BOOT" == "1" ]]; then
sudo mkfs.fat $PARTITION1 > /dev/null sudo mkfs.fat $PARTITION1 > /dev/null

View File

@ -1,38 +1,44 @@
#!/bin/bash #!/bin/bash
if [[ -z $BANAN_ROOT_DIR ]]; then
echo "You must set the BANAN_ROOT_DIR environment variable" >&2
exit 1
fi
if [[ -z $BANAN_DISK_IMAGE_PATH ]]; then if [[ -z $BANAN_DISK_IMAGE_PATH ]]; then
echo "You must set the BANAN_DISK_IMAGE_PATH environment variable" >&2 echo "You must set the BANAN_DISK_IMAGE_PATH environment variable" >&2
exit 1 exit 1
fi fi
if [[ -z $BANAN_SYSROOT_TAR ]]; then if [[ -z $BANAN_SYSROOT ]]; then
echo "You must set the BANAN_SYSROOT_TAR environment variable" >&2 echo "You must set the BANAN_SYSROOT environment variable" >&2
exit 1 exit 1
fi fi
if [[ "$1" == "full" ]] || [[ ! -f $BANAN_DISK_IMAGE_PATH ]]; then if [[ ! -f $BANAN_DISK_IMAGE_PATH ]]; then
$BANAN_SCRIPT_DIR/image-create.sh $BANAN_SCRIPT_DIR/image-full.sh
else exit 0
fdisk -l $BANAN_DISK_IMAGE_PATH | grep -q 'EFI System'; IMAGE_IS_UEFI=$?
[[ $BANAN_UEFI_BOOT == 1 ]]; CREATE_IS_UEFI=$?
if [[ $IMAGE_IS_UEFI -ne $CREATE_IS_UEFI ]]; then
echo Converting disk image to/from UEFI
$BANAN_SCRIPT_DIR/image-create.sh
fi
fi fi
LOOP_DEV=$(sudo losetup --show -f "$BANAN_DISK_IMAGE_PATH") fdisk -l $BANAN_DISK_IMAGE_PATH | grep -q 'EFI System'; IMAGE_IS_UEFI=$?
sudo partprobe $LOOP_DEV [[ $BANAN_UEFI_BOOT == 1 ]]; CREATE_IS_UEFI=$?
if [[ $IMAGE_IS_UEFI -ne $CREATE_IS_UEFI ]]; then
echo Converting disk image to/from UEFI
$BANAN_SCRIPT_DIR/image-full.sh
exit 0
fi
ROOT_PARTITION=${LOOP_DEV}p2
MOUNT_DIR=/mnt MOUNT_DIR=/mnt
sudo mount $ROOT_PARTITION $MOUNT_DIR LOOP_DEV=$(sudo losetup -f --show $BANAN_DISK_IMAGE_PATH)
sudo partprobe $LOOP_DEV
cd $MOUNT_DIR ROOT_PARTITON=${LOOP_DEV}p2
sudo tar xf $BANAN_SYSROOT_TAR
cd sudo mount $ROOT_PARTITON $MOUNT_DIR
sudo rsync -a ${BANAN_SYSROOT}/* ${MOUNT_DIR}/
sudo umount $MOUNT_DIR sudo umount $MOUNT_DIR

View File

@ -1,19 +1,9 @@
if (NOT DEFINED ENV{BANAN_ARCH}) if (NOT DEFINED ENV{BANAN_ARCH})
message(FATAL_ERROR "environment variable BANAN_ARCH not defined") message(FATAL_ERROR "environment variable BANAN_ARCH not defined")
endif () endif ()
set(BANAN_ARCH $ENV{BANAN_ARCH}) set(BANAN_ARCH $ENV{BANAN_ARCH})
if (NOT DEFINED ENV{BANAN_SYSROOT})
message(FATAL_ERROR "environment variable BANAN_SYSROOT not defined")
endif ()
set(BANAN_SYSROOT $ENV{BANAN_SYSROOT})
if (NOT DEFINED ENV{BANAN_SYSROOT_TAR})
message(FATAL_ERROR "environment variable BANAN_SYSROOT_TAR not defined")
endif ()
set(BANAN_SYSROOT_TAR $ENV{BANAN_SYSROOT_TAR})
set(TOOLCHAIN_PREFIX ${CMAKE_SOURCE_DIR}/toolchain/local) set(TOOLCHAIN_PREFIX ${CMAKE_SOURCE_DIR}/toolchain/local)
set(CMAKE_SYSTEM_NAME banan-os) set(CMAKE_SYSTEM_NAME banan-os)

File diff suppressed because it is too large Load Diff

View File

@ -2,13 +2,7 @@
set -e set -e
BINUTILS_VERSION="binutils-2.39" BINUTILS_VERSION="binutils-2.39"
BINUTILS_GIT="https://sourceware.org/git/binutils-gdb.git"
BINUTILS_BRANCH="binutils-2_39"
GCC_VERSION="gcc-12.2.0" GCC_VERSION="gcc-12.2.0"
GCC_GIT="https://gcc.gnu.org/git/gcc.git"
GCC_BRANCH="releases/$GCC_VERSION"
GRUB_VERSION="grub-2.06" GRUB_VERSION="grub-2.06"
if [[ -z $BANAN_SYSROOT ]]; then if [[ -z $BANAN_SYSROOT ]]; then
@ -57,20 +51,22 @@ build_binutils () {
cd $BANAN_BUILD_DIR/toolchain cd $BANAN_BUILD_DIR/toolchain
if [ ! -d $BINUTILS_VERSION ]; then if [ ! -f ${BINUTILS_VERSION}.tar.xz ]; then
git clone --single-branch --branch $BINUTILS_BRANCH $BINUTILS_GIT $BINUTILS_VERSION wget https://ftp.gnu.org/gnu/binutils/${BINUTILS_VERSION}.tar.xz
cd $BINUTILS_VERSION
git am $BANAN_TOOLCHAIN_DIR/$BINUTILS_VERSION.patch
fi fi
cd $BANAN_BUILD_DIR/toolchain/$BINUTILS_VERSION if [ ! -d $BINUTILS_VERSION ]; then
tar xvf ${BINUTILS_VERSION}.tar.xz
patch -s -p0 < $BANAN_TOOLCHAIN_DIR/${BINUTILS_VERSION}.patch
fi
cd $BINUTILS_VERSION
enter_clean_build enter_clean_build
../configure \ ../configure \
--target="$BANAN_TOOLCHAIN_TRIPLE_PREFIX" \ --target="$BANAN_TOOLCHAIN_TRIPLE_PREFIX" \
--prefix="$BANAN_TOOLCHAIN_PREFIX" \ --prefix="$BANAN_TOOLCHAIN_PREFIX" \
--with-sysroot="$BANAN_SYSROOT" \ --with-sysroot="$BANAN_SYSROOT" \
--disable-initfini-array \
--disable-nls \ --disable-nls \
--disable-werror --disable-werror
@ -83,20 +79,22 @@ build_gcc () {
cd $BANAN_BUILD_DIR/toolchain cd $BANAN_BUILD_DIR/toolchain
if [ ! -d $GCC_VERSION ]; then if [ ! -f ${GCC_VERSION}.tar.xz ]; then
git clone --single-branch --branch $GCC_BRANCH $GCC_GIT $GCC_VERSION wget https://ftp.gnu.org/gnu/gcc/${GCC_VERSION}/${GCC_VERSION}.tar.xz
cd $GCC_VERSION
git am $BANAN_TOOLCHAIN_DIR/$GCC_VERSION.patch
fi fi
cd $BANAN_BUILD_DIR/toolchain/$GCC_VERSION if [ ! -d $GCC_VERSION ]; then
tar xvf ${GCC_VERSION}.tar.xz
patch -s -p0 < $BANAN_TOOLCHAIN_DIR/${GCC_VERSION}.patch
fi
cd ${GCC_VERSION}
enter_clean_build enter_clean_build
../configure \ ../configure \
--target="$BANAN_TOOLCHAIN_TRIPLE_PREFIX" \ --target="$BANAN_TOOLCHAIN_TRIPLE_PREFIX" \
--prefix="$BANAN_TOOLCHAIN_PREFIX" \ --prefix="$BANAN_TOOLCHAIN_PREFIX" \
--with-sysroot="$BANAN_SYSROOT" \ --with-sysroot="$BANAN_SYSROOT" \
--disable-initfini-array \
--disable-nls \ --disable-nls \
--enable-languages=c,c++ --enable-languages=c,c++
@ -161,9 +159,6 @@ sudo rsync -a $BANAN_ROOT_DIR/libc/include/ $BANAN_SYSROOT/usr/include/
mkdir -p $BANAN_BUILD_DIR/toolchain mkdir -p $BANAN_BUILD_DIR/toolchain
# Cleanup all old files from toolchain prefix
rm -rf $BANAN_TOOLCHAIN_PREFIX
build_binutils build_binutils
build_gcc build_gcc
build_grub build_grub

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,6 @@ set(USERSPACE_PROJECTS
sync sync
tee tee
test test
test-globals
touch touch
u8sum u8sum
whoami whoami

View File

@ -11,6 +11,7 @@ target_compile_options(Shell PUBLIC -O2 -g)
target_link_libraries(Shell PUBLIC libc ban) target_link_libraries(Shell PUBLIC libc ban)
add_custom_target(Shell-install add_custom_target(Shell-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/Shell ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/Shell ${BANAN_BIN}/
DEPENDS Shell DEPENDS Shell
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(cat-mmap PUBLIC -O2 -g)
target_link_libraries(cat-mmap PUBLIC libc) target_link_libraries(cat-mmap PUBLIC libc)
add_custom_target(cat-mmap-install add_custom_target(cat-mmap-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/cat-mmap ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/cat-mmap ${BANAN_BIN}/
DEPENDS cat-mmap DEPENDS cat-mmap
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(cat PUBLIC -O2 -g)
target_link_libraries(cat PUBLIC libc) target_link_libraries(cat PUBLIC libc)
add_custom_target(cat-install add_custom_target(cat-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/cat ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/cat ${BANAN_BIN}/
DEPENDS cat DEPENDS cat
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(chmod PUBLIC -O2 -g)
target_link_libraries(chmod PUBLIC libc) target_link_libraries(chmod PUBLIC libc)
add_custom_target(chmod-install add_custom_target(chmod-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/chmod ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/chmod ${BANAN_BIN}/
DEPENDS chmod DEPENDS chmod
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(cp PUBLIC -O2 -g)
target_link_libraries(cp PUBLIC libc ban) target_link_libraries(cp PUBLIC libc ban)
add_custom_target(cp-install add_custom_target(cp-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/cp ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/cp ${BANAN_BIN}/
DEPENDS cp DEPENDS cp
USES_TERMINAL
) )

View File

@ -20,8 +20,9 @@ target_compile_options($PROGRAM_NAME PUBLIC -O2 -g)
target_link_libraries($PROGRAM_NAME PUBLIC libc) target_link_libraries($PROGRAM_NAME PUBLIC libc)
add_custom_target($PROGRAM_NAME-install add_custom_target($PROGRAM_NAME-install
COMMAND \${CMAKE_COMMAND} -E copy \${CMAKE_CURRENT_BINARY_DIR}/$PROGRAM_NAME \${BANAN_BIN}/ COMMAND sudo cp \${CMAKE_CURRENT_BINARY_DIR}/$PROGRAM_NAME \${BANAN_BIN}/
DEPENDS $PROGRAM_NAME DEPENDS $PROGRAM_NAME
USES_TERMINAL
) )
EOF EOF

View File

@ -11,6 +11,7 @@ target_compile_options(dd PUBLIC -O2 -g)
target_link_libraries(dd PUBLIC libc) target_link_libraries(dd PUBLIC libc)
add_custom_target(dd-install add_custom_target(dd-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/dd ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/dd ${BANAN_BIN}/
DEPENDS dd DEPENDS dd
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(echo PUBLIC -O2 -g)
target_link_libraries(echo PUBLIC libc) target_link_libraries(echo PUBLIC libc)
add_custom_target(echo-install add_custom_target(echo-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/echo ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/echo ${BANAN_BIN}/
DEPENDS echo DEPENDS echo
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(id PUBLIC -O2 -g)
target_link_libraries(id PUBLIC libc ban) target_link_libraries(id PUBLIC libc ban)
add_custom_target(id-install add_custom_target(id-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/id ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/id ${BANAN_BIN}/
DEPENDS id DEPENDS id
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(init PUBLIC -O2 -g)
target_link_libraries(init PUBLIC libc ban) target_link_libraries(init PUBLIC libc ban)
add_custom_target(init-install add_custom_target(init-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/init ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/init ${BANAN_BIN}/
DEPENDS init DEPENDS init
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(ls PUBLIC -O2 -g)
target_link_libraries(ls PUBLIC libc) target_link_libraries(ls PUBLIC libc)
add_custom_target(ls-install add_custom_target(ls-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/ls ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/ls ${BANAN_BIN}/
DEPENDS ls DEPENDS ls
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(meminfo PUBLIC -O2 -g)
target_link_libraries(meminfo PUBLIC libc) target_link_libraries(meminfo PUBLIC libc)
add_custom_target(meminfo-install add_custom_target(meminfo-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/meminfo ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/meminfo ${BANAN_BIN}/
DEPENDS meminfo DEPENDS meminfo
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(mkdir PUBLIC -O2 -g)
target_link_libraries(mkdir PUBLIC libc) target_link_libraries(mkdir PUBLIC libc)
add_custom_target(mkdir-install add_custom_target(mkdir-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/mkdir ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/mkdir ${BANAN_BIN}/
DEPENDS mkdir DEPENDS mkdir
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(mmap-shared-test PUBLIC -O2 -g)
target_link_libraries(mmap-shared-test PUBLIC libc) target_link_libraries(mmap-shared-test PUBLIC libc)
add_custom_target(mmap-shared-test-install add_custom_target(mmap-shared-test-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/mmap-shared-test ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/mmap-shared-test ${BANAN_BIN}/
DEPENDS mmap-shared-test DEPENDS mmap-shared-test
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(poweroff PUBLIC -O2 -g)
target_link_libraries(poweroff PUBLIC libc) target_link_libraries(poweroff PUBLIC libc)
add_custom_target(poweroff-install add_custom_target(poweroff-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/poweroff ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/poweroff ${BANAN_BIN}/
DEPENDS poweroff DEPENDS poweroff
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(rm PUBLIC -O2 -g)
target_link_libraries(rm PUBLIC libc ban) target_link_libraries(rm PUBLIC libc ban)
add_custom_target(rm-install add_custom_target(rm-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/rm ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/rm ${BANAN_BIN}/
DEPENDS rm DEPENDS rm
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(snake PUBLIC -O2 -g)
target_link_libraries(snake PUBLIC libc) target_link_libraries(snake PUBLIC libc)
add_custom_target(snake-install add_custom_target(snake-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/snake ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/snake ${BANAN_BIN}/
DEPENDS snake DEPENDS snake
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(stat PUBLIC -O2 -g)
target_link_libraries(stat PUBLIC libc ban) target_link_libraries(stat PUBLIC libc ban)
add_custom_target(stat-install add_custom_target(stat-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/stat ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/stat ${BANAN_BIN}/
DEPENDS stat DEPENDS stat
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(sync PUBLIC -O2 -g)
target_link_libraries(sync PUBLIC libc) target_link_libraries(sync PUBLIC libc)
add_custom_target(sync-install add_custom_target(sync-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/sync ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/sync ${BANAN_BIN}/
DEPENDS sync DEPENDS sync
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(tee PUBLIC -O2 -g)
target_link_libraries(tee PUBLIC libc) target_link_libraries(tee PUBLIC libc)
add_custom_target(tee-install add_custom_target(tee-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/tee ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/tee ${BANAN_BIN}/
DEPENDS tee DEPENDS tee
USES_TERMINAL
) )

View File

@ -1,16 +0,0 @@
cmake_minimum_required(VERSION 3.26)
project(test-globals CXX)
set(SOURCES
main.cpp
)
add_executable(test-globals ${SOURCES})
target_compile_options(test-globals PUBLIC -O2 -g)
target_link_libraries(test-globals PUBLIC libc)
add_custom_target(test-globals-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/test-globals ${BANAN_BIN}/
DEPENDS test-globals
)

View File

@ -1,14 +0,0 @@
#include <stdio.h>
struct foo_t
{
foo_t() { printf("global constructor works\n"); }
~foo_t() { printf("global destructor works\n"); }
};
foo_t foo;
int main()
{
}

View File

@ -11,6 +11,7 @@ target_compile_options(test PUBLIC -O2 -g)
target_link_libraries(test PUBLIC libc) target_link_libraries(test PUBLIC libc)
add_custom_target(test-install add_custom_target(test-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/test ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/test ${BANAN_BIN}/
DEPENDS test DEPENDS test
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(touch PUBLIC -O2 -g)
target_link_libraries(touch PUBLIC libc) target_link_libraries(touch PUBLIC libc)
add_custom_target(touch-install add_custom_target(touch-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/touch ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/touch ${BANAN_BIN}/
DEPENDS touch DEPENDS touch
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(u8sum PUBLIC -O2 -g)
target_link_libraries(u8sum PUBLIC libc) target_link_libraries(u8sum PUBLIC libc)
add_custom_target(u8sum-install add_custom_target(u8sum-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/u8sum ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/u8sum ${BANAN_BIN}/
DEPENDS u8sum DEPENDS u8sum
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(whoami PUBLIC -O2 -g)
target_link_libraries(whoami PUBLIC libc ban) target_link_libraries(whoami PUBLIC libc ban)
add_custom_target(whoami-install add_custom_target(whoami-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/whoami ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/whoami ${BANAN_BIN}/
DEPENDS whoami DEPENDS whoami
USES_TERMINAL
) )

View File

@ -11,6 +11,7 @@ target_compile_options(yes PUBLIC -O2 -g)
target_link_libraries(yes PUBLIC libc) target_link_libraries(yes PUBLIC libc)
add_custom_target(yes-install add_custom_target(yes-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/yes ${BANAN_BIN}/ COMMAND sudo cp ${CMAKE_CURRENT_BINARY_DIR}/yes ${BANAN_BIN}/
DEPENDS yes DEPENDS yes
USES_TERMINAL
) )