Compare commits
21 Commits
1af3ca19ab
...
6d899aa6ce
Author | SHA1 | Date |
---|---|---|
Bananymous | 6d899aa6ce | |
Bananymous | 120f7329b1 | |
Bananymous | 4f25c20c97 | |
Bananymous | 5e396851f4 | |
Bananymous | a44482639d | |
Bananymous | 3bac19e518 | |
Bananymous | 4dbe15aa0e | |
Bananymous | 1c5985148c | |
Bananymous | ce2461d0e8 | |
Bananymous | 4e785a133c | |
Bananymous | 26c7aee327 | |
Bananymous | 0405461742 | |
Bananymous | 8a10853ba7 | |
Bananymous | 5d34cebeca | |
Bananymous | 3d899d2e44 | |
Bananymous | f72fdeeb59 | |
Bananymous | 382f9d9bb3 | |
Bananymous | bc1d1bf919 | |
Bananymous | f05b9a6877 | |
Bananymous | ea5ed3001e | |
Bananymous | f312c3a4d7 |
|
@ -2,4 +2,4 @@
|
||||||
.idea/
|
.idea/
|
||||||
build/
|
build/
|
||||||
base/
|
base/
|
||||||
|
script/fakeroot-context
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include <BAN/String.h>
|
#include <BAN/String.h>
|
||||||
#include <BAN/New.h>
|
#include <BAN/New.h>
|
||||||
#include <BAN/Variant.h>
|
|
||||||
|
|
||||||
namespace BAN
|
namespace BAN
|
||||||
{
|
{
|
||||||
|
@ -32,8 +31,7 @@ namespace BAN
|
||||||
String& String::operator=(const String& other)
|
String& String::operator=(const String& other)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
if (!other.fits_in_sso())
|
MUST(ensure_capacity(other.size()));
|
||||||
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;
|
||||||
|
@ -43,14 +41,18 @@ namespace BAN
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (other.fits_in_sso())
|
if (other.has_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 = SSOStorage();
|
other.m_storage.sso_storage = SSOStorage();
|
||||||
|
other.m_has_sso = true;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -58,8 +60,7 @@ namespace BAN
|
||||||
String& String::operator=(StringView other)
|
String& String::operator=(StringView other)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
if (!fits_in_sso(other.size()))
|
MUST(ensure_capacity(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';
|
||||||
|
@ -125,8 +126,9 @@ namespace BAN
|
||||||
{
|
{
|
||||||
if (!has_sso())
|
if (!has_sso())
|
||||||
{
|
{
|
||||||
deallocator(m_storage.get<GeneralStorage>().data);
|
deallocator(m_storage.general_storage.data);
|
||||||
m_storage = SSOStorage();
|
m_storage.sso_storage = SSOStorage();
|
||||||
|
m_has_sso = true;
|
||||||
}
|
}
|
||||||
m_size = 0;
|
m_size = 0;
|
||||||
data()[m_size] = '\0';
|
data()[m_size] = '\0';
|
||||||
|
@ -166,15 +168,6 @@ 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';
|
||||||
|
@ -194,20 +187,21 @@ namespace BAN
|
||||||
|
|
||||||
if (fits_in_sso())
|
if (fits_in_sso())
|
||||||
{
|
{
|
||||||
char* data = m_storage.get<GeneralStorage>().data;
|
char* data = m_storage.general_storage.data;
|
||||||
m_storage = SSOStorage();
|
m_storage.sso_storage = SSOStorage();
|
||||||
memcpy(m_storage.get<SSOStorage>().storage, data, m_size + 1);
|
m_has_sso = true;
|
||||||
|
memcpy(this->data(), data, m_size + 1);
|
||||||
deallocator(data);
|
deallocator(data);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneralStorage& storage = m_storage.get<GeneralStorage>();
|
GeneralStorage& storage = m_storage.general_storage;
|
||||||
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 BAN::Error::from_errno(ENOMEM);
|
return Error::from_errno(ENOMEM);
|
||||||
|
|
||||||
memcpy(new_data, storage.data, m_size);
|
memcpy(new_data, storage.data, m_size);
|
||||||
deallocator(storage.data);
|
deallocator(storage.data);
|
||||||
|
@ -222,40 +216,45 @@ namespace BAN
|
||||||
{
|
{
|
||||||
if (has_sso())
|
if (has_sso())
|
||||||
return sso_capacity;
|
return sso_capacity;
|
||||||
return m_storage.get<GeneralStorage>().capacity;
|
return m_storage.general_storage.capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* String::data()
|
char* String::data()
|
||||||
{
|
{
|
||||||
if (has_sso())
|
if (has_sso())
|
||||||
return m_storage.get<SSOStorage>().storage;
|
return m_storage.sso_storage.data;
|
||||||
return m_storage.get<GeneralStorage>().data;
|
return m_storage.general_storage.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* String::data() const
|
const char* String::data() const
|
||||||
{
|
{
|
||||||
if (has_sso())
|
if (has_sso())
|
||||||
return m_storage.get<SSOStorage>().storage;
|
return m_storage.sso_storage.data;
|
||||||
return m_storage.get<GeneralStorage>().data;
|
return m_storage.general_storage.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> String::ensure_capacity(size_type new_size)
|
ErrorOr<void> String::ensure_capacity(size_type new_size)
|
||||||
{
|
{
|
||||||
if (m_size >= new_size || fits_in_sso(new_size))
|
if (m_size >= 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 BAN::Error::from_errno(ENOMEM);
|
return 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.get<GeneralStorage>().data);
|
deallocator(m_storage.general_storage.data);
|
||||||
|
|
||||||
auto& storage = m_storage.get<GeneralStorage>();
|
auto& storage = m_storage.general_storage;
|
||||||
storage.capacity = new_size;
|
storage.capacity = new_size;
|
||||||
storage.data = new_data;
|
storage.data = new_data;
|
||||||
|
|
||||||
|
@ -264,7 +263,7 @@ namespace BAN
|
||||||
|
|
||||||
bool String::has_sso() const
|
bool String::has_sso() const
|
||||||
{
|
{
|
||||||
return m_storage.has<SSOStorage>();
|
return m_has_sso;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,17 +10,15 @@ set(BAN_SOURCES
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(ban-headers
|
add_custom_target(ban-headers
|
||||||
COMMAND sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
|
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/libban.a ${BANAN_LIB}/
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/libban.a ${BANAN_LIB}/
|
||||||
DEPENDS ban
|
DEPENDS ban
|
||||||
BYPRODUCTS ${BANAN_LIB}/libban.a
|
BYPRODUCTS ${BANAN_LIB}/libban.a
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,11 +1,33 @@
|
||||||
#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
|
||||||
|
|
|
@ -82,17 +82,21 @@ namespace BAN
|
||||||
private:
|
private:
|
||||||
struct SSOStorage
|
struct SSOStorage
|
||||||
{
|
{
|
||||||
char storage[sso_capacity + 1] {};
|
char data[sso_capacity + 1] {};
|
||||||
};
|
};
|
||||||
struct GeneralStorage
|
struct GeneralStorage
|
||||||
{
|
{
|
||||||
size_type capacity { 0 };
|
size_type capacity { 0 };
|
||||||
char* data;
|
char* data { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Variant<SSOStorage, GeneralStorage> m_storage { SSOStorage() };
|
union {
|
||||||
size_type m_size { 0 };
|
SSOStorage sso_storage;
|
||||||
|
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>
|
||||||
|
|
|
@ -10,7 +10,6 @@ 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)
|
||||||
|
@ -24,8 +23,7 @@ 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} && sudo tar xf ${BANAN_BASE_SYSROOT}
|
COMMAND cd ${BANAN_SYSROOT} && tar xf ${BANAN_BASE_SYSROOT}
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(headers
|
add_custom_target(headers
|
||||||
|
@ -36,6 +34,7 @@ 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
|
||||||
|
|
|
@ -3,9 +3,8 @@ cmake_minimum_required(VERSION 3.26)
|
||||||
project(LibELF CXX)
|
project(LibELF CXX)
|
||||||
|
|
||||||
add_custom_target(libelf-headers
|
add_custom_target(libelf-headers
|
||||||
COMMAND sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
|
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
|
||||||
DEPENDS sysroot
|
DEPENDS sysroot
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(libelf-install
|
add_custom_target(libelf-install
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#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>
|
||||||
|
@ -226,7 +227,8 @@ 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, vaddr, flags);
|
// Temporarily map page as RW so kernel can write to it
|
||||||
|
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);
|
||||||
|
@ -245,6 +247,9 @@ 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:
|
||||||
|
@ -302,9 +307,12 @@ 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);
|
{
|
||||||
memcpy((void*)0, (void*)(start + i * PAGE_SIZE), PAGE_SIZE);
|
CriticalScope _;
|
||||||
m_page_table.unmap_page(0);
|
PageTable::map_fast_page(paddr);
|
||||||
|
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++;
|
||||||
|
|
|
@ -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 since the sysroot has "proper" permissions.
|
To build the os itself you can run one of the following commands. You will need root access for disk image creation/modification.
|
||||||
```sh
|
```sh
|
||||||
./script/build.sh qemu
|
./script/build.sh qemu
|
||||||
./script/build.sh qemu-nographic
|
./script/build.sh qemu-nographic
|
||||||
|
@ -39,8 +39,6 @@ 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_.
|
||||||
|
|
|
@ -36,7 +36,6 @@ 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
|
||||||
|
@ -148,6 +147,9 @@ 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()
|
||||||
|
@ -162,28 +164,15 @@ 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 sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
|
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
|
||||||
COMMAND sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/lai/include/ ${BANAN_INCLUDE}/
|
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/kernel ${BANAN_BOOT}/banan-os.kernel
|
COMMAND ${CMAKE_COMMAND} -E copy ${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)
|
||||||
|
@ -193,8 +182,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 cp ${CRTBEGIN} .
|
COMMAND ${CMAKE_COMMAND} -E copy ${CRTBEGIN} .
|
||||||
COMMAND cp ${CRTEND} .
|
COMMAND ${CMAKE_COMMAND} -E copy ${CRTEND} .
|
||||||
)
|
)
|
||||||
|
|
||||||
#add_custom_command(
|
#add_custom_command(
|
||||||
|
|
|
@ -181,14 +181,20 @@ namespace Kernel::IDT
|
||||||
{
|
{
|
||||||
// Check if stack is OOB
|
// Check if stack is OOB
|
||||||
auto& stack = Thread::current().stack();
|
auto& stack = Thread::current().stack();
|
||||||
if (interrupt_stack.rsp < stack.vaddr())
|
auto& istack = Thread::current().interrupt_stack();
|
||||||
|
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 overflow");
|
derrorln("Stack pointer out of bounds!");
|
||||||
goto done;
|
derrorln("rsp {H}, stack {H}->{H}, istack {H}->{H}",
|
||||||
}
|
interrupt_stack.rsp,
|
||||||
if (interrupt_stack.rsp >= stack.vaddr() + stack.size())
|
stack.vaddr(), stack.vaddr() + stack.size(),
|
||||||
{
|
istack.vaddr(), istack.vaddr() + istack.size()
|
||||||
derrorln("Stack underflow");
|
);
|
||||||
|
Thread::current().handle_signal(SIGKILL);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +213,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(SIGTERM);
|
Thread::current().handle_signal(SIGKILL);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,6 +92,13 @@ 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);
|
||||||
|
@ -136,8 +143,16 @@ 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;
|
||||||
|
|
||||||
// Map (0 -> phys_kernel_end) to (KERNEL_OFFSET -> virt_kernel_end)
|
prepare_fast_page();
|
||||||
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(
|
||||||
|
@ -172,6 +187,76 @@ 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);
|
||||||
|
@ -233,13 +318,16 @@ namespace Kernel
|
||||||
void PageTable::invalidate(vaddr_t vaddr)
|
void PageTable::invalidate(vaddr_t vaddr)
|
||||||
{
|
{
|
||||||
ASSERT(vaddr % PAGE_SIZE == 0);
|
ASSERT(vaddr % PAGE_SIZE == 0);
|
||||||
if (this == s_current)
|
asm volatile("invlpg (%0)" :: "r"(vaddr) : "memory");
|
||||||
asm volatile("invlpg (%0)" :: "r"(vaddr) : "memory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageTable::unmap_page(vaddr_t vaddr)
|
void PageTable::unmap_page(vaddr_t vaddr)
|
||||||
{
|
{
|
||||||
if (vaddr && (vaddr >= KERNEL_OFFSET) != (this == s_kernel))
|
ASSERT(vaddr);
|
||||||
|
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));
|
||||||
|
@ -281,7 +369,11 @@ 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)
|
||||||
{
|
{
|
||||||
if (vaddr && (vaddr >= KERNEL_OFFSET) != (this == s_kernel))
|
ASSERT(vaddr);
|
||||||
|
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));
|
||||||
|
@ -348,12 +440,11 @@ 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 first_page = vaddr / PAGE_SIZE;
|
size_t page_count = range_page_count(vaddr, 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++)
|
||||||
|
@ -430,6 +521,8 @@ 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)
|
||||||
|
@ -487,8 +580,9 @@ 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 canonicalize(vaddr);
|
return vaddr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -512,6 +606,8 @@ 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)
|
||||||
|
|
|
@ -38,6 +38,7 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
#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;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -29,6 +29,24 @@ 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();
|
||||||
|
@ -64,7 +82,8 @@ 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 invalidate(vaddr_t);
|
void prepare_fast_page();
|
||||||
|
static void invalidate(vaddr_t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
paddr_t m_highest_paging_struct { 0 };
|
paddr_t m_highest_paging_struct { 0 };
|
||||||
|
|
|
@ -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, args...);
|
derrorln(message, BAN::forward<Args>(args)...);
|
||||||
if (!g_paniced)
|
if (!g_paniced)
|
||||||
{
|
{
|
||||||
g_paniced = true;
|
g_paniced = true;
|
||||||
|
|
|
@ -71,6 +71,7 @@ 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; }
|
||||||
|
|
|
@ -117,33 +117,33 @@ namespace Kernel
|
||||||
|
|
||||||
if (rsdp->revision >= 2)
|
if (rsdp->revision >= 2)
|
||||||
{
|
{
|
||||||
PageTable::kernel().map_page_at(rsdp->xsdt_address & PAGE_ADDR_MASK, 0, PageTable::Flags::Present);
|
PageTable::map_fast_page(rsdp->xsdt_address & PAGE_ADDR_MASK);
|
||||||
const XSDT* xsdt = (const XSDT*)(rsdp->xsdt_address % PAGE_SIZE);
|
auto& xsdt = PageTable::fast_page_as<const XSDT>(rsdp->xsdt_address % PAGE_SIZE);
|
||||||
BAN::ScopeGuard _([xsdt] { PageTable::kernel().unmap_page(0); });
|
BAN::ScopeGuard _([] { PageTable::unmap_fast_page(); });
|
||||||
|
|
||||||
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 = (paddr_t)xsdt->entries + (rsdp->rsdt_address & PAGE_ADDR_MASK);
|
m_header_table_paddr = rsdp->xsdt_address + offsetof(XSDT, entries);
|
||||||
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::kernel().map_page_at(rsdp->rsdt_address & PAGE_ADDR_MASK, 0, PageTable::Flags::Present);
|
PageTable::map_fast_page(rsdp->rsdt_address & PAGE_ADDR_MASK);
|
||||||
const RSDT* rsdt = (const RSDT*)((vaddr_t)rsdp->rsdt_address % PAGE_SIZE);
|
auto& rsdt = PageTable::fast_page_as<const RSDT>(rsdp->rsdt_address % PAGE_SIZE);
|
||||||
BAN::ScopeGuard _([rsdt] { PageTable::kernel().unmap_page(0); });
|
BAN::ScopeGuard _([] { PageTable::unmap_fast_page(); });
|
||||||
|
|
||||||
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 = (paddr_t)rsdt->entries + (rsdp->rsdt_address & PAGE_ADDR_MASK);
|
m_header_table_paddr = rsdp->rsdt_address + offsetof(RSDT, entries);
|
||||||
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::kernel().map_page_at(header_paddr & PAGE_ADDR_MASK, 0, PageTable::Flags::Present);
|
PageTable::map_fast_page(header_paddr & PAGE_ADDR_MASK);
|
||||||
size_t header_length = ((SDTHeader*)(header_paddr % PAGE_SIZE))->length;
|
size_t header_length = PageTable::fast_page_as<SDTHeader>(header_paddr % PAGE_SIZE).length;
|
||||||
PageTable::kernel().unmap_page(0);
|
PageTable::unmap_fast_page();
|
||||||
|
|
||||||
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,7 +211,10 @@ 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;
|
||||||
|
|
||||||
|
|
|
@ -274,6 +274,9 @@ 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])
|
||||||
|
@ -287,6 +290,7 @@ 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));
|
||||||
|
|
||||||
|
@ -759,7 +763,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;
|
data_block_index -= indices_per_fs_block * 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));
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#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>
|
||||||
|
@ -71,13 +72,10 @@ namespace Kernel
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto& page_table = PageTable::current();
|
CriticalScope _;
|
||||||
LockGuard _(page_table);
|
PageTable::map_fast_page(pages[i]);
|
||||||
ASSERT(page_table.is_page_free(0));
|
memcpy(page_buffer, PageTable::fast_page_as_ptr(), PAGE_SIZE);
|
||||||
|
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())
|
||||||
|
@ -100,28 +98,15 @@ 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);
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> read_ret = 0;
|
ASSERT_EQ(&PageTable::current(), &m_page_table);
|
||||||
|
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())
|
||||||
{
|
{
|
||||||
|
@ -137,6 +122,10 @@ 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)
|
||||||
{
|
{
|
||||||
|
@ -158,15 +147,10 @@ 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)));
|
||||||
|
|
||||||
auto& page_table = PageTable::current();
|
CriticalScope _;
|
||||||
|
PageTable::map_fast_page(pages[page_index]);
|
||||||
// TODO: check if this can cause deadlock?
|
memcpy(PageTable::fast_page_as_ptr(), m_shared_data->page_buffer, PAGE_SIZE);
|
||||||
LockGuard page_table_lock(page_table);
|
PageTable::unmap_fast_page();
|
||||||
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];
|
||||||
|
|
|
@ -1,145 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#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>
|
||||||
|
@ -60,12 +61,10 @@ namespace Kernel
|
||||||
memset((void*)vaddr, 0x00, PAGE_SIZE);
|
memset((void*)vaddr, 0x00, PAGE_SIZE);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LockGuard _(PageTable::current());
|
CriticalScope _;
|
||||||
ASSERT(PageTable::current().is_page_free(0));
|
PageTable::map_fast_page(paddr);
|
||||||
|
memset(PageTable::fast_page_as_ptr(), 0x00, PAGE_SIZE);
|
||||||
PageTable::current().map_page_at(paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
|
PageTable::unmap_fast_page();
|
||||||
memset((void*)0, 0x00, PAGE_SIZE);
|
|
||||||
PageTable::current().unmap_page(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -105,15 +104,10 @@ namespace Kernel
|
||||||
memcpy((void*)write_vaddr, (void*)(buffer + written), bytes);
|
memcpy((void*)write_vaddr, (void*)(buffer + written), bytes);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
paddr_t paddr = m_page_table.physical_address_of(write_vaddr & PAGE_ADDR_MASK);
|
CriticalScope _;
|
||||||
ASSERT(paddr);
|
PageTable::map_fast_page(m_page_table.physical_address_of(write_vaddr & PAGE_ADDR_MASK));
|
||||||
|
memcpy(PageTable::fast_page_as_ptr(page_offset), (void*)(buffer + written), bytes);
|
||||||
LockGuard _(PageTable::current());
|
PageTable::unmap_fast_page();
|
||||||
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;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#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>
|
||||||
|
@ -124,7 +125,6 @@ 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,10 +134,12 @@ 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);
|
|
||||||
memcpy((void*)0, (void*)(vaddr() + offset), PAGE_SIZE);
|
CriticalScope _;
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
@ -172,14 +174,13 @@ 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)
|
||||||
{
|
{
|
||||||
page_table.map_page_at(m_page_table.physical_address_of(vaddr() + offset), 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
|
CriticalScope _;
|
||||||
memset((void*)0, 0, PAGE_SIZE);
|
PageTable::map_fast_page(m_page_table.physical_address_of(vaddr() + offset));
|
||||||
|
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)
|
||||||
|
@ -187,47 +188,34 @@ namespace Kernel
|
||||||
if (bytes == 0)
|
if (bytes == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// NOTE: Handling overflow
|
// Verify no overflow
|
||||||
ASSERT(offset <= size());
|
ASSERT_LTE(bytes, size());
|
||||||
ASSERT(bytes <= size());
|
ASSERT_LTE(offset, size());
|
||||||
ASSERT(offset + bytes <= size());
|
ASSERT_LTE(offset, size() - bytes);
|
||||||
|
|
||||||
PageTable& page_table = PageTable::current();
|
if (m_kmalloc || &PageTable::current() == &m_page_table)
|
||||||
|
|
||||||
if (m_kmalloc || &page_table == &m_page_table)
|
|
||||||
{
|
{
|
||||||
memcpy((void*)(vaddr() + offset), buffer, bytes);
|
memcpy((void*)(vaddr() + offset), buffer, bytes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LockGuard _(page_table);
|
size_t page_offset = offset % PAGE_SIZE;
|
||||||
ASSERT(page_table.is_page_free(0));
|
size_t page_index = offset / PAGE_SIZE;
|
||||||
|
|
||||||
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();
|
||||||
|
}
|
||||||
|
|
||||||
page_table.map_page_at(m_page_table.physical_address_of(vaddr() + i * PAGE_SIZE), 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
|
buffer += PAGE_SIZE - page_offset;
|
||||||
|
bytes -= PAGE_SIZE - page_offset;
|
||||||
memcpy((void*)0, buffer, len);
|
page_offset = 0;
|
||||||
|
page_index++;
|
||||||
buffer += len;
|
|
||||||
bytes -= len;
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
page_table.unmap_page(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
#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>
|
||||||
|
|
|
@ -47,9 +47,9 @@ namespace Kernel
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CriticalScope _;
|
CriticalScope _;
|
||||||
page_table.map_page_at(cache.paddr, 0, PageTable::Flags::Present);
|
PageTable::map_fast_page(cache.paddr);
|
||||||
memcpy(buffer.data(), (void*)(page_cache_offset * m_sector_size), m_sector_size);
|
memcpy(buffer.data(), PageTable::fast_page_as_ptr(page_cache_offset * m_sector_size), m_sector_size);
|
||||||
page_table.unmap_page(0);
|
PageTable::unmap_fast_page();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -82,9 +82,9 @@ namespace Kernel
|
||||||
|
|
||||||
{
|
{
|
||||||
CriticalScope _;
|
CriticalScope _;
|
||||||
page_table.map_page_at(cache.paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
|
PageTable::map_fast_page(cache.paddr);
|
||||||
memcpy((void*)(page_cache_offset * m_sector_size), buffer.data(), m_sector_size);
|
memcpy(PageTable::fast_page_as_ptr(page_cache_offset * m_sector_size), buffer.data(), m_sector_size);
|
||||||
page_table.unmap_page(0);
|
PageTable::unmap_fast_page();
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.sector_mask |= 1 << page_cache_offset;
|
cache.sector_mask |= 1 << page_cache_offset;
|
||||||
|
@ -113,9 +113,9 @@ namespace Kernel
|
||||||
|
|
||||||
{
|
{
|
||||||
CriticalScope _;
|
CriticalScope _;
|
||||||
page_table.map_page_at(cache.paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
|
PageTable::map_fast_page(cache.paddr);
|
||||||
memcpy((void*)(page_cache_offset * m_sector_size), buffer.data(), m_sector_size);
|
memcpy(PageTable::fast_page_as_ptr(page_cache_offset * m_sector_size), buffer.data(), m_sector_size);
|
||||||
page_table.unmap_page(0);
|
PageTable::unmap_fast_page();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -123,21 +123,16 @@ 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;
|
||||||
|
|
||||||
{
|
{
|
||||||
LockGuard _(page_table);
|
CriticalScope _;
|
||||||
ASSERT(page_table.is_page_free(0));
|
PageTable::map_fast_page(cache.paddr);
|
||||||
|
memcpy(m_sync_cache.data(), PageTable::fast_page_as_ptr(), PAGE_SIZE);
|
||||||
page_table.map_page_at(cache.paddr, 0, PageTable::Flags::Present);
|
PageTable::unmap_fast_page();
|
||||||
memcpy(m_sync_cache.data(), (void*)0, PAGE_SIZE);
|
|
||||||
page_table.unmap_page(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t sector_start = 0;
|
uint8_t sector_start = 0;
|
||||||
|
|
|
@ -79,9 +79,6 @@ 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*);
|
||||||
|
|
|
@ -26,21 +26,32 @@ set(LIBC_SOURCES
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(libc-headers
|
add_custom_target(libc-headers
|
||||||
COMMAND sudo rsync -a ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${BANAN_INCLUDE}/
|
COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${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 crt0)
|
add_dependencies(libc headers crtx-install)
|
||||||
|
|
||||||
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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/libc.a ${BANAN_LIB}/
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${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 "")
|
||||||
|
|
|
@ -8,19 +8,19 @@ _start:
|
||||||
pushq %rbp # rbp=0
|
pushq %rbp # rbp=0
|
||||||
movq %rsp, %rbp
|
movq %rsp, %rbp
|
||||||
|
|
||||||
# We need those in a moment when we call main.
|
# Save argc, argv, environ
|
||||||
pushq %rdx
|
pushq %rdx
|
||||||
pushq %rsi
|
pushq %rsi
|
||||||
pushq %rdi
|
pushq %rdi
|
||||||
|
|
||||||
# Prepare signals, memory allocation, stdio and such.
|
# Prepare malloc, environment
|
||||||
movq %rdx, %rdi
|
movq %rdx, %rdi
|
||||||
call _init_libc
|
call _init_libc
|
||||||
|
|
||||||
# Run the global constructors.
|
# Call global constructos
|
||||||
call _init
|
call _init
|
||||||
|
|
||||||
# Restore argc and argv.
|
# Restore argc, argv, environ
|
||||||
popq %rdi
|
popq %rdi
|
||||||
popq %rsi
|
popq %rsi
|
||||||
popq %rdx
|
popq %rdx
|
||||||
|
@ -28,7 +28,8 @@ _start:
|
||||||
# Run main
|
# Run main
|
||||||
call main
|
call main
|
||||||
|
|
||||||
# Terminate the process with the exit code.
|
# Cleanly exit the process
|
||||||
movl %eax, %edi
|
movl %eax, %edi
|
||||||
call exit
|
call exit
|
||||||
|
|
||||||
.size _start, . - _start
|
.size _start, . - _start
|
|
@ -0,0 +1,16 @@
|
||||||
|
/* 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. */
|
|
@ -0,0 +1,10 @@
|
||||||
|
/* 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
|
|
@ -1,35 +1,37 @@
|
||||||
|
#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*);
|
||||||
* Each member is at least 4 bytes large. Such that each entry is 12bytes.
|
void* data;
|
||||||
* 128 * 12 = 1.5KB exact.
|
void* dso_handle;
|
||||||
**/
|
|
||||||
void (*destructor_func)(void *);
|
|
||||||
void *obj_ptr;
|
|
||||||
void *dso_handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS];
|
static atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS];
|
||||||
uarch_t __atexit_func_count = 0;
|
static int __atexit_func_count = 0;
|
||||||
|
|
||||||
int __cxa_atexit(void (*f)(void *), void *objptr, void *dso)
|
int __cxa_atexit(void (*func)(void*), void* data, void* dso_handle)
|
||||||
{
|
{
|
||||||
if (__atexit_func_count >= ATEXIT_MAX_FUNCS) {return -1;};
|
if (__atexit_func_count >= ATEXIT_MAX_FUNCS)
|
||||||
__atexit_funcs[__atexit_func_count].destructor_func = f;
|
return -1;;
|
||||||
__atexit_funcs[__atexit_func_count].obj_ptr = objptr;
|
__atexit_funcs[__atexit_func_count].destructor = func;
|
||||||
__atexit_funcs[__atexit_func_count].dso_handle = dso;
|
__atexit_funcs[__atexit_func_count].data = data;
|
||||||
|
__atexit_funcs[__atexit_func_count].dso_handle = dso_handle;
|
||||||
__atexit_func_count++;
|
__atexit_func_count++;
|
||||||
return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
void __cxa_finalize(void* func)
|
||||||
};
|
{
|
||||||
#endif
|
for (int i = __atexit_func_count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#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
|
|
@ -7,6 +7,8 @@
|
||||||
#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();
|
||||||
|
@ -21,6 +23,7 @@ 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();
|
||||||
|
|
|
@ -4,6 +4,12 @@ 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
|
||||||
|
@ -19,7 +25,7 @@ build_target () {
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
cd $BANAN_BUILD_DIR
|
cd $BANAN_BUILD_DIR
|
||||||
ninja $1
|
run_fakeroot ninja $1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_toolchain () {
|
build_toolchain () {
|
||||||
|
@ -39,11 +45,7 @@ build_toolchain () {
|
||||||
|
|
||||||
create_image () {
|
create_image () {
|
||||||
build_target install-sysroot
|
build_target install-sysroot
|
||||||
if [[ "$1" == "full" ]]; then
|
$BANAN_SCRIPT_DIR/image.sh "$1"
|
||||||
$BANAN_SCRIPT_DIR/image-full.sh
|
|
||||||
else
|
|
||||||
$BANAN_SCRIPT_DIR/image.sh
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run_qemu () {
|
run_qemu () {
|
||||||
|
@ -56,7 +58,7 @@ run_bochs () {
|
||||||
$BANAN_SCRIPT_DIR/bochs.sh $@
|
$BANAN_SCRIPT_DIR/bochs.sh $@
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "$(uname)" == "Linux" ]]; then
|
if [[ -c /dev/kvm ]]; then
|
||||||
QEMU_ACCEL="-accel kvm"
|
QEMU_ACCEL="-accel kvm"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ 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
|
||||||
|
|
||||||
|
|
|
@ -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 -d $BANAN_SYSROOT -b 1024 -q $PARTITION2
|
sudo mkfs.ext2 -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
|
|
@ -1,44 +1,38 @@
|
||||||
#!/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 ]]; then
|
if [[ -z $BANAN_SYSROOT_TAR ]]; then
|
||||||
echo "You must set the BANAN_SYSROOT environment variable" >&2
|
echo "You must set the BANAN_SYSROOT_TAR environment variable" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -f $BANAN_DISK_IMAGE_PATH ]]; then
|
if [[ "$1" == "full" ]] || [[ ! -f $BANAN_DISK_IMAGE_PATH ]]; then
|
||||||
$BANAN_SCRIPT_DIR/image-full.sh
|
$BANAN_SCRIPT_DIR/image-create.sh
|
||||||
exit 0
|
else
|
||||||
|
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
|
||||||
|
|
||||||
fdisk -l $BANAN_DISK_IMAGE_PATH | grep -q 'EFI System'; IMAGE_IS_UEFI=$?
|
LOOP_DEV=$(sudo losetup --show -f "$BANAN_DISK_IMAGE_PATH")
|
||||||
[[ $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
|
|
||||||
|
|
||||||
MOUNT_DIR=/mnt
|
|
||||||
|
|
||||||
LOOP_DEV=$(sudo losetup -f --show $BANAN_DISK_IMAGE_PATH)
|
|
||||||
sudo partprobe $LOOP_DEV
|
sudo partprobe $LOOP_DEV
|
||||||
|
|
||||||
ROOT_PARTITON=${LOOP_DEV}p2
|
ROOT_PARTITION=${LOOP_DEV}p2
|
||||||
|
MOUNT_DIR=/mnt
|
||||||
|
|
||||||
sudo mount $ROOT_PARTITON $MOUNT_DIR
|
sudo mount $ROOT_PARTITION $MOUNT_DIR
|
||||||
|
|
||||||
sudo rsync -a ${BANAN_SYSROOT}/* ${MOUNT_DIR}/
|
cd $MOUNT_DIR
|
||||||
|
sudo tar xf $BANAN_SYSROOT_TAR
|
||||||
|
cd
|
||||||
|
|
||||||
sudo umount $MOUNT_DIR
|
sudo umount $MOUNT_DIR
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
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
|
@ -2,7 +2,13 @@
|
||||||
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
|
||||||
|
@ -51,22 +57,20 @@ build_binutils () {
|
||||||
|
|
||||||
cd $BANAN_BUILD_DIR/toolchain
|
cd $BANAN_BUILD_DIR/toolchain
|
||||||
|
|
||||||
if [ ! -f ${BINUTILS_VERSION}.tar.xz ]; then
|
|
||||||
wget https://ftp.gnu.org/gnu/binutils/${BINUTILS_VERSION}.tar.xz
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d $BINUTILS_VERSION ]; then
|
if [ ! -d $BINUTILS_VERSION ]; then
|
||||||
tar xvf ${BINUTILS_VERSION}.tar.xz
|
git clone --single-branch --branch $BINUTILS_BRANCH $BINUTILS_GIT $BINUTILS_VERSION
|
||||||
patch -s -p0 < $BANAN_TOOLCHAIN_DIR/${BINUTILS_VERSION}.patch
|
cd $BINUTILS_VERSION
|
||||||
|
git am $BANAN_TOOLCHAIN_DIR/$BINUTILS_VERSION.patch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd $BINUTILS_VERSION
|
cd $BANAN_BUILD_DIR/toolchain/$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
|
||||||
|
|
||||||
|
@ -79,22 +83,20 @@ build_gcc () {
|
||||||
|
|
||||||
cd $BANAN_BUILD_DIR/toolchain
|
cd $BANAN_BUILD_DIR/toolchain
|
||||||
|
|
||||||
if [ ! -f ${GCC_VERSION}.tar.xz ]; then
|
|
||||||
wget https://ftp.gnu.org/gnu/gcc/${GCC_VERSION}/${GCC_VERSION}.tar.xz
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d $GCC_VERSION ]; then
|
if [ ! -d $GCC_VERSION ]; then
|
||||||
tar xvf ${GCC_VERSION}.tar.xz
|
git clone --single-branch --branch $GCC_BRANCH $GCC_GIT $GCC_VERSION
|
||||||
patch -s -p0 < $BANAN_TOOLCHAIN_DIR/${GCC_VERSION}.patch
|
cd $GCC_VERSION
|
||||||
|
git am $BANAN_TOOLCHAIN_DIR/$GCC_VERSION.patch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd ${GCC_VERSION}
|
cd $BANAN_BUILD_DIR/toolchain/$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++
|
||||||
|
|
||||||
|
@ -159,6 +161,9 @@ 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
|
||||||
|
|
131820
toolchain/gcc-12.2.0.patch
131820
toolchain/gcc-12.2.0.patch
File diff suppressed because it is too large
Load Diff
|
@ -23,6 +23,7 @@ set(USERSPACE_PROJECTS
|
||||||
sync
|
sync
|
||||||
tee
|
tee
|
||||||
test
|
test
|
||||||
|
test-globals
|
||||||
touch
|
touch
|
||||||
u8sum
|
u8sum
|
||||||
whoami
|
whoami
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/Shell ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/Shell ${BANAN_BIN}/
|
||||||
DEPENDS Shell
|
DEPENDS Shell
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/cat-mmap ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/cat-mmap ${BANAN_BIN}/
|
||||||
DEPENDS cat-mmap
|
DEPENDS cat-mmap
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/cat ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/cat ${BANAN_BIN}/
|
||||||
DEPENDS cat
|
DEPENDS cat
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/chmod ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/chmod ${BANAN_BIN}/
|
||||||
DEPENDS chmod
|
DEPENDS chmod
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/cp ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/cp ${BANAN_BIN}/
|
||||||
DEPENDS cp
|
DEPENDS cp
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,9 +20,8 @@ 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 sudo cp \${CMAKE_CURRENT_BINARY_DIR}/$PROGRAM_NAME \${BANAN_BIN}/
|
COMMAND \${CMAKE_COMMAND} -E copy \${CMAKE_CURRENT_BINARY_DIR}/$PROGRAM_NAME \${BANAN_BIN}/
|
||||||
DEPENDS $PROGRAM_NAME
|
DEPENDS $PROGRAM_NAME
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/dd ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/dd ${BANAN_BIN}/
|
||||||
DEPENDS dd
|
DEPENDS dd
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/echo ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/echo ${BANAN_BIN}/
|
||||||
DEPENDS echo
|
DEPENDS echo
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/id ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/id ${BANAN_BIN}/
|
||||||
DEPENDS id
|
DEPENDS id
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/init ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/init ${BANAN_BIN}/
|
||||||
DEPENDS init
|
DEPENDS init
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/ls ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/ls ${BANAN_BIN}/
|
||||||
DEPENDS ls
|
DEPENDS ls
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/meminfo ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/meminfo ${BANAN_BIN}/
|
||||||
DEPENDS meminfo
|
DEPENDS meminfo
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/mkdir ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/mkdir ${BANAN_BIN}/
|
||||||
DEPENDS mkdir
|
DEPENDS mkdir
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/mmap-shared-test ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/mmap-shared-test ${BANAN_BIN}/
|
||||||
DEPENDS mmap-shared-test
|
DEPENDS mmap-shared-test
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/poweroff ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/poweroff ${BANAN_BIN}/
|
||||||
DEPENDS poweroff
|
DEPENDS poweroff
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/rm ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/rm ${BANAN_BIN}/
|
||||||
DEPENDS rm
|
DEPENDS rm
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/snake ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/snake ${BANAN_BIN}/
|
||||||
DEPENDS snake
|
DEPENDS snake
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/stat ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/stat ${BANAN_BIN}/
|
||||||
DEPENDS stat
|
DEPENDS stat
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/sync ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/sync ${BANAN_BIN}/
|
||||||
DEPENDS sync
|
DEPENDS sync
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/tee ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/tee ${BANAN_BIN}/
|
||||||
DEPENDS tee
|
DEPENDS tee
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
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
|
||||||
|
)
|
|
@ -0,0 +1,14 @@
|
||||||
|
#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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/test ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/test ${BANAN_BIN}/
|
||||||
DEPENDS test
|
DEPENDS test
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/touch ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/touch ${BANAN_BIN}/
|
||||||
DEPENDS touch
|
DEPENDS touch
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/u8sum ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/u8sum ${BANAN_BIN}/
|
||||||
DEPENDS u8sum
|
DEPENDS u8sum
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/whoami ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/whoami ${BANAN_BIN}/
|
||||||
DEPENDS whoami
|
DEPENDS whoami
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 sudo cp ${CMAKE_CURRENT_BINARY_DIR}/yes ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/yes ${BANAN_BIN}/
|
||||||
DEPENDS yes
|
DEPENDS yes
|
||||||
USES_TERMINAL
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue