Compare commits

..

No commits in common. "fc0f3157eaa3fa52467be4a1cb34dd450c25b308" and "c84a30d4dd054741e5171af2c1aadf28bcd88e31" have entirely different histories.

40 changed files with 190 additions and 621 deletions

View File

@ -1,6 +1,6 @@
#pragma once
#include <BAN/Iterators.h>
#include <BAN/Iteration.h>
#include <BAN/Swap.h>
#include <BAN/Traits.h>

View File

@ -15,7 +15,9 @@ asm_syscall_handler:
andl $-16, %esp
# push arguments
subl $8, %esp
subl $4, %esp
pushl %ebp
addl $24, (%esp)
pushl %edi
pushl %esi
pushl %edx
@ -63,7 +65,7 @@ sys_fork_trampoline:
call read_ip
testl %eax, %eax
jz .done
jz .reload_stack
movl %esp, %ebx
@ -79,3 +81,9 @@ sys_fork_trampoline:
popl %ebx
popl %ebp
ret
.reload_stack:
call get_thread_start_sp
movl %eax, %esp
xorl %eax, %eax
jmp .done

View File

@ -184,13 +184,6 @@ enable_sse:
movl %eax, %cr4
ret
enable_tsc:
# allow userspace to use RDTSC
movl %cr4, %ecx
andl $0xFFFFFFFB, %ecx
movl %ecx, %cr4
ret
initialize_paging:
# enable PAE
movl %cr4, %ecx
@ -233,7 +226,6 @@ gdt_flush:
# do processor initialization
call check_requirements
call enable_sse
call enable_tsc
call initialize_paging
# load higher half stack pointer
@ -310,7 +302,6 @@ ap_protected_mode:
movb $1, AP_V2P(ap_stack_loaded)
leal V2P(enable_sse), %ecx; call *%ecx
leal V2P(enable_tsc), %ecx; call *%ecx
leal V2P(initialize_paging), %ecx; call *%ecx
# load boot gdt and enter long mode

View File

@ -1,6 +1,6 @@
.macro maybe_load_kernel_segments, n
testb $3, \n(%esp)
jz 1f; jnp 1f
cmpb $0x08, \n(%esp)
je 1f
movw $0x10, %ax
movw %ax, %ds
@ -13,8 +13,8 @@
.endm
.macro maybe_load_userspace_segments, n
testb $3, \n(%esp)
jz 1f; jnp 1f
cmpb $0x08, \n(%esp)
je 1f
movw $(0x20 | 3), %bx
movw %bx, %ds

View File

@ -1,26 +1,50 @@
// arguments in RAX, RBX, RCX, RDX, RSI, RDI
// System V ABI: RDI, RSI, RDX, RCX, R8, R9
.global asm_syscall_handler
asm_syscall_handler:
swapgs
movq %rsp, %rax
movq %gs:8, %rsp
pushq $(0x20 | 3)
pushq %rax
pushq %r11
pushq $(0x28 | 3)
pushq %rbx
pushq %rcx
subq $8, %rsp
pushq %rdx
pushq %rdi
pushq %rsi
pushq %rbp
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r14
pushq %r15
cld
movq %r10, %rcx
movq %rsi, %r8
movq %rdi, %r9
movq %rax, %rdi
movq %rbx, %rsi
xchgq %rcx, %rdx
leaq 112(%rsp), %rbx
pushq %rbx
call cpp_syscall_handler
addq $8, %rsp
movq 8(%rsp), %rcx
movq 24(%rsp), %r11
movq 32(%rsp), %rsp
popq %r15
popq %r14
popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rbp
popq %rsi
popq %rdi
popq %rdx
popq %rcx
popq %rbx
swapgs
sysretq
iretq
.global sys_fork_trampoline
sys_fork_trampoline:
@ -33,7 +57,7 @@ sys_fork_trampoline:
call read_ip
testq %rax, %rax
je .done
je .reload_stack
movq %rax, %rsi
movq %rsp, %rdi
@ -47,3 +71,9 @@ sys_fork_trampoline:
popq %rbp
popq %rbx
ret
.reload_stack:
call get_thread_start_sp
movq %rax, %rsp
xorq %rax, %rax
jmp .done

View File

@ -179,13 +179,6 @@ enable_sse:
movl %eax, %cr4
ret
enable_tsc:
# allow userspace to use RDTSC
movl %cr4, %ecx
andl $0xFFFFFFFB, %ecx
movl %ecx, %cr4
ret
initialize_paging:
# enable PAE
movl %cr4, %ecx
@ -222,7 +215,6 @@ _start:
call check_requirements
call enable_sse
call enable_tsc
call initialize_paging
# flush gdt and jump to 64 bit
@ -309,7 +301,6 @@ ap_protected_mode:
movb $1, AP_V2P(ap_stack_loaded)
leal V2P(enable_sse), %ecx; call *%ecx
leal V2P(enable_tsc), %ecx; call *%ecx
leal V2P(initialize_paging), %ecx; call *%ecx
# load boot gdt and enter long mode

View File

@ -1,6 +1,6 @@
.macro swapgs_if_necessary, n
testb $3, \n(%rsp)
jz 1f; jnp 1f
cmpb $0x08, \n(%rsp)
je 1f
swapgs
1:
.endm

View File

@ -1,37 +0,0 @@
#pragma once
#include <stdint.h>
namespace Kernel::API
{
enum SharedPageFeature : uint32_t
{
SPF_GETTIME = 1 << 0,
};
struct SharedPage
{
uint8_t __sequence[0x100];
uint32_t features;
struct
{
uint8_t shift;
uint64_t mult;
uint64_t realtime_seconds;
} gettime_shared;
struct
{
struct
{
uint32_t seq;
uint64_t last_ns;
uint64_t last_tsc;
} gettime_local;
} cpus[];
};
}

View File

@ -1,44 +0,0 @@
#pragma once
#include <kernel/Attributes.h>
#include <kernel/IDT.h>
#include <stdint.h>
#include <sys/syscall.h>
namespace Kernel
{
ALWAYS_INLINE long syscall(int syscall, uintptr_t arg1 = 0, uintptr_t arg2 = 0, uintptr_t arg3 = 0, uintptr_t arg4 = 0, uintptr_t arg5 = 0)
{
long ret;
#if ARCH(x86_64)
register uintptr_t r10 asm("r10") = arg3;
register uintptr_t r8 asm( "r8") = arg4;
register uintptr_t r9 asm( "r9") = arg5;
asm volatile(
"syscall"
: "=a"(ret)
, "+D"(syscall)
, "+S"(arg1)
, "+d"(arg2)
, "+r"(r10)
, "+r"(r8)
, "+r"(r9)
:: "rcx", "r11", "memory");
#elif ARCH(i686)
asm volatile(
"int %[irq]"
: "=a"(ret)
: [irq]"i"(static_cast<int>(IRQ_SYSCALL)) // WTF GCC 15
, "a"(syscall)
, "b"(arg1)
, "c"(arg2)
, "d"(arg3)
, "S"(arg4)
, "D"(arg5)
: "memory");
#endif
return ret;
}
}

View File

@ -81,6 +81,5 @@ namespace CPUID
bool has_pge();
bool has_pat();
bool has_1gib_pages();
bool has_invariant_tsc();
}

View File

@ -151,8 +151,8 @@ namespace Kernel
private:
#if ARCH(x86_64)
BAN::Array<SegmentDescriptor, 8> m_gdt; // null, kernel code, kernel data, user code (32 bit), user data, user code (64 bit), tss low, tss high
static constexpr uint16_t m_tss_offset = 0x30;
BAN::Array<SegmentDescriptor, 7> m_gdt; // null, kernel code, kernel data, user code, user data, tss low, tss high
static constexpr uint16_t m_tss_offset = 0x28;
#elif ARCH(i686)
BAN::Array<SegmentDescriptor, 9> m_gdt; // null, kernel code, kernel data, user code, user data, processor data, fsbase, gsbase, tss
static constexpr uint16_t m_tss_offset = 0x40;

View File

@ -18,10 +18,7 @@ namespace Kernel
constexpr uint8_t IRQ_VECTOR_BASE = 0x20;
constexpr uint8_t IRQ_MSI_BASE = 0x80;
constexpr uint8_t IRQ_MSI_END = 0xF0;
#if ARCH(i686)
constexpr uint8_t IRQ_SYSCALL = 0xF0;
#endif
constexpr uint8_t IRQ_YIELD = 0xF1;
constexpr uint8_t IRQ_IPI = 0xF2;
constexpr uint8_t IRQ_TIMER = 0xF3;

View File

@ -187,7 +187,7 @@ namespace Kernel::PCI
void initialize_impl();
private:
static constexpr uint8_t m_msi_count = IRQ_MSI_END - IRQ_MSI_BASE;
static constexpr uint8_t m_msi_count = IRQ_SYSCALL - IRQ_MSI_BASE;
using PCIBus = BAN::Array<BAN::Array<Device, 8>, 32>;
BAN::Array<PCIBus, 256> m_buses;
BAN::Array<paddr_t, 256> m_bus_pcie_paddr;

View File

@ -228,8 +228,6 @@ namespace Kernel
static Process& current() { return Thread::current().process(); }
vaddr_t shared_page_vaddr() const { return m_shared_page_vaddr; }
PageTable& page_table() { return m_page_table ? *m_page_table : PageTable::kernel(); }
size_t proc_meminfo(off_t offset, BAN::ByteSpan) const;
@ -344,8 +342,6 @@ namespace Kernel
VirtualFileSystem::File m_working_directory;
VirtualFileSystem::File m_root_file;
vaddr_t m_shared_page_vaddr { 0 };
BAN::Vector<Thread*> m_threads;
struct pthread_info_t

View File

@ -3,12 +3,10 @@
#include <BAN/Atomic.h>
#include <BAN/ForwardList.h>
#include <kernel/API/SharedPage.h>
#include <kernel/Arch.h>
#include <kernel/GDT.h>
#include <kernel/IDT.h>
#include <kernel/InterruptStack.h>
#include <kernel/Memory/Types.h>
#include <kernel/ProcessorID.h>
#include <kernel/Scheduler.h>
@ -35,7 +33,6 @@ namespace Kernel
FlushTLB,
NewThread,
UnblockThread,
UpdateTSC,
StackTrace,
};
SMPMessage* next { nullptr };
@ -58,7 +55,6 @@ namespace Kernel
static Processor& initialize();
static ProcessorID current_id() { return read_gs_sized<ProcessorID>(offsetof(Processor, m_id)); }
static uint8_t current_index() { return read_gs_sized<uint8_t>(offsetof(Processor, m_index)); }
static ProcessorID id_from_index(size_t index);
static uint8_t count() { return s_processor_count; }
@ -82,11 +78,8 @@ namespace Kernel
static InterruptState get_interrupt_state()
{
#if ARCH(x86_64)
const auto flags = __builtin_ia32_readeflags_u64();
#elif ARCH(i686)
const auto flags = __builtin_ia32_readeflags_u32();
#endif
uintptr_t flags;
asm volatile("pushf; pop %0" : "=rm"(flags));
if (flags & (1 << 9))
return InterruptState::Enabled;
return InterruptState::Disabled;
@ -105,8 +98,6 @@ namespace Kernel
uintptr_t stack_bottom() const { return reinterpret_cast<uintptr_t>(m_stack); }
uintptr_t stack_top() const { return stack_bottom() + s_stack_size; }
static void set_thread_syscall_stack(vaddr_t vaddr) { write_gs_sized<vaddr_t>(offsetof(Processor, m_thread_syscall_stack), vaddr); }
static GDT& gdt() { return *read_gs_sized<GDT*>(offsetof(Processor, m_gdt)); }
static IDT& idt() { return *read_gs_sized<IDT*>(offsetof(Processor, m_idt)); }
@ -116,13 +107,6 @@ namespace Kernel
static void yield();
static Scheduler& scheduler() { return *read_gs_sized<Scheduler*>(offsetof(Processor, m_scheduler)); }
static void initialize_tsc(uint8_t shift, uint64_t mult, uint64_t realtime_seconds);
static void update_tsc();
static uint64_t ns_since_boot_tsc();
static paddr_t shared_page_paddr() { return s_shared_page_paddr; }
static volatile API::SharedPage& shared_page() { return *reinterpret_cast<API::SharedPage*>(s_shared_page_vaddr); }
static void handle_ipi();
static void handle_smp_messages();
@ -140,14 +124,6 @@ namespace Kernel
static ProcessorID read_processor_id();
static void initialize_smp();
static void initialize_shared_page();
static void dummy()
{
#if ARCH(x86_64)
static_assert(offsetof(Processor, m_thread_syscall_stack) == 8, "This is hardcoded in Syscall.S");
#endif
}
template<typename T>
static T read_gs_sized(uintptr_t offset) requires(sizeof(T) <= 8)
@ -186,13 +162,8 @@ namespace Kernel
static BAN::Atomic<uint8_t> s_processor_count;
static BAN::Atomic<bool> s_is_smp_enabled;
static BAN::Atomic<bool> s_should_print_cpu_load;
static paddr_t s_shared_page_paddr;
static vaddr_t s_shared_page_vaddr;
ProcessorID m_id { 0 };
uint8_t m_index { 0xFF };
vaddr_t m_thread_syscall_stack;
static constexpr size_t s_stack_size { 4096 };
void* m_stack { nullptr };

View File

@ -0,0 +1,27 @@
#pragma once
#include <kernel/Attributes.h>
#include <kernel/IDT.h>
#include <stdint.h>
#include <sys/syscall.h>
namespace Kernel
{
ALWAYS_INLINE long syscall(int syscall, uintptr_t arg1 = 0, uintptr_t arg2 = 0, uintptr_t arg3 = 0, uintptr_t arg4 = 0, uintptr_t arg5 = 0)
{
long ret;
asm volatile("int %[irq]"
: "=a"(ret)
: [irq]"i"(static_cast<int>(IRQ_SYSCALL)) // WTF GCC 15
, "a"(syscall)
, "b"((uintptr_t)arg1)
, "c"((uintptr_t)arg2)
, "d"((uintptr_t)arg3)
, "S"((uintptr_t)arg4)
, "D"((uintptr_t)arg5)
: "memory");
return ret;
}
}

View File

@ -122,8 +122,6 @@ namespace Kernel
void set_cpu_time_start();
void set_cpu_time_stop();
void update_processor_index_address();
void set_fsbase(vaddr_t base) { m_fsbase = base; }
vaddr_t get_fsbase() const { return m_fsbase; }
void set_gsbase(vaddr_t base) { m_gsbase = base; }

View File

@ -35,8 +35,6 @@ namespace Kernel
static SystemTimer& get();
static bool is_initialized();
void initialize_tsc();
virtual uint64_t ms_since_boot() const override;
virtual uint64_t ns_since_boot() const override;
virtual timespec time_since_boot() const override;
@ -49,9 +47,6 @@ namespace Kernel
void dont_invoke_scheduler() { m_timer->m_should_invoke_scheduler = false; }
void update_tsc() const;
uint64_t ns_since_boot_no_tsc() const;
timespec real_time() const;
private:
@ -59,14 +54,10 @@ namespace Kernel
void initialize_timers(bool force_pic);
uint64_t get_tsc_frequency() const;
private:
uint64_t m_boot_time { 0 };
BAN::UniqPtr<RTC> m_rtc;
BAN::UniqPtr<Timer> m_timer;
bool m_has_invariant_tsc { false };
mutable uint32_t m_timer_ticks { 0 };
};
}

View File

@ -75,7 +75,6 @@ namespace Kernel
BAN::ErrorOr<void> initialize();
const USBDeviceDescriptor& device_descriptor() const { return m_descriptor.descriptor; }
const BAN::Vector<ConfigurationDescriptor>& configurations() { return m_descriptor.configurations; }
virtual BAN::ErrorOr<uint8_t> initialize_device_on_hub_port(uint8_t port_id, USB::SpeedClass) = 0;

View File

@ -75,16 +75,6 @@ namespace CPUID
return buffer[3] & (1 << 26);
}
bool has_invariant_tsc()
{
uint32_t buffer[4] {};
get_cpuid(0x80000000, buffer);
if (buffer[0] < 0x80000007)
return false;
get_cpuid(0x80000007, buffer);
return buffer[3] & (1 << 8);
}
const char* feature_string_ecx(uint32_t feat)
{
switch (feat)

View File

@ -15,23 +15,23 @@ namespace Kernel
ASSERT(gdt);
#if ARCH(x86_64)
gdt->write_entry(0x00, 0x00000000, 0x00000, 0x00, 0x0); // null
gdt->write_entry(0x08, 0x00000000, 0xFFFFF, 0x9A, 0xA); // kernel code
gdt->write_entry(0x10, 0x00000000, 0xFFFFF, 0x92, 0xC); // kernel data
gdt->write_entry(0x18, 0x00000000, 0xFFFFF, 0xFA, 0xC); // user code (32 bit)
gdt->write_entry(0x20, 0x00000000, 0xFFFFF, 0xF2, 0xC); // user data
gdt->write_entry(0x28, 0x00000000, 0xFFFFF, 0xFA, 0xA); // user code (64 bit)
constexpr uint8_t code_flags = 0xA;
constexpr uint8_t data_flags = 0xC;
#elif ARCH(i686)
gdt->write_entry(0x00, 0x00000000, 0x00000, 0x00, 0x0); // null
gdt->write_entry(0x08, 0x00000000, 0xFFFFF, 0x9A, 0xC); // kernel code
gdt->write_entry(0x10, 0x00000000, 0xFFFFF, 0x92, 0xC); // kernel data
gdt->write_entry(0x18, 0x00000000, 0xFFFFF, 0xFA, 0xC); // user code
gdt->write_entry(0x20, 0x00000000, 0xFFFFF, 0xF2, 0xC); // user data
gdt->write_entry(0x28, reinterpret_cast<uint32_t>(processor), sizeof(Processor), 0x92, 0x4); // processor data
gdt->write_entry(0x30, 0x00000000, 0x00000, 0xF2, 0xC); // fsbase
gdt->write_entry(0x38, 0x00000000, 0x00000, 0xF2, 0xC); // gsbase
constexpr uint8_t code_flags = 0xC;
constexpr uint8_t data_flags = 0xC;
#endif
gdt->write_entry(0x00, 0x00000000, 0x00000, 0x00, 0x0); // null
gdt->write_entry(0x08, 0x00000000, 0xFFFFF, 0x9A, code_flags); // kernel code
gdt->write_entry(0x10, 0x00000000, 0xFFFFF, 0x92, data_flags); // kernel data
gdt->write_entry(0x18, 0x00000000, 0xFFFFF, 0xFA, code_flags); // user code
gdt->write_entry(0x20, 0x00000000, 0xFFFFF, 0xF2, data_flags); // user data
#if ARCH(i686)
gdt->write_entry(0x28, reinterpret_cast<uint32_t>(processor), sizeof(Processor), 0x92, 0x4); // processor data
gdt->write_entry(0x30, 0x00000000, 0x00000, 0xF2, data_flags); // fsbase
gdt->write_entry(0x38, 0x00000000, 0x00000, 0xF2, data_flags); // gsbase
#endif
gdt->write_tss();
return gdt;

View File

@ -18,6 +18,8 @@
X(160) X(161) X(162) X(163) X(164) X(165) X(166) X(167) X(168) X(169) X(170) X(171) X(172) X(173) X(174) X(175) X(176) X(177) X(178) X(179) X(180) X(181) X(182) X(183) X(184) X(185) X(186) X(187) X(188) X(189) X(190) X(191) \
X(192) X(193) X(194) X(195) X(196) X(197) X(198) X(199) X(200) X(201) X(202) X(203) X(204) X(205) X(206) X(207)
static_assert(Kernel::IRQ_SYSCALL == Kernel::IRQ_VECTOR_BASE + 208);
namespace Kernel
{
@ -444,9 +446,7 @@ namespace Kernel
extern "C" void asm_yield_handler();
extern "C" void asm_ipi_handler();
extern "C" void asm_timer_handler();
#if ARCH(i686)
extern "C" void asm_syscall_handler();
#endif
IDT* IDT::create()
{
@ -480,9 +480,7 @@ namespace Kernel
idt->register_interrupt_handler(IRQ_YIELD, asm_yield_handler);
idt->register_interrupt_handler(IRQ_IPI, asm_ipi_handler);
idt->register_interrupt_handler(IRQ_TIMER, asm_timer_handler);
#if ARCH(i686)
idt->register_syscall_handler(IRQ_SYSCALL, asm_syscall_handler);
#endif
return idt;
}

View File

@ -152,20 +152,6 @@ namespace Kernel
}));
}
process->m_shared_page_vaddr = process->page_table().reserve_free_page(process->m_mapped_regions.back()->vaddr(), USERSPACE_END);
if (process->m_shared_page_vaddr == 0)
return BAN::Error::from_errno(ENOMEM);
process->page_table().map_page_at(
Processor::shared_page_paddr(),
process->m_shared_page_vaddr,
PageTable::UserSupervisor | PageTable::Present
);
TRY(auxiliary_vector.push_back({
.a_type = LibELF::AT_SHARED_PAGE,
.a_un = { .a_ptr = reinterpret_cast<void*>(process->m_shared_page_vaddr) },
}));
TRY(auxiliary_vector.push_back({
.a_type = LibELF::AT_NULL,
.a_un = { .a_val = 0 },
@ -697,13 +683,6 @@ namespace Kernel
for (auto& mapped_region : m_mapped_regions)
MUST(mapped_regions.push_back(TRY(mapped_region->clone(*page_table))));
const vaddr_t shared_page_vaddr = m_shared_page_vaddr;
page_table->map_page_at(
Processor::shared_page_paddr(),
shared_page_vaddr,
PageTable::UserSupervisor | PageTable::Present
);
Process* forked = create_process(m_credentials, m_pid, m_sid, m_pgrp);
forked->m_controlling_terminal = m_controlling_terminal;
forked->m_working_directory = BAN::move(working_directory);
@ -712,7 +691,6 @@ namespace Kernel
forked->m_environ = BAN::move(environ);
forked->m_executable = BAN::move(executable);
forked->m_page_table = BAN::move(page_table);
forked->m_shared_page_vaddr = BAN::move(shared_page_vaddr);
forked->m_open_file_descriptors = BAN::move(*open_file_descriptors);
forked->m_mapped_regions = BAN::move(mapped_regions);
forked->m_has_called_exec = false;
@ -788,20 +766,6 @@ namespace Kernel
}));
}
const vaddr_t shared_page_vaddr = new_page_table->reserve_free_page(new_mapped_regions.back()->vaddr(), USERSPACE_END);
if (shared_page_vaddr == 0)
return BAN::Error::from_errno(ENOMEM);
new_page_table->map_page_at(
Processor::shared_page_paddr(),
shared_page_vaddr,
PageTable::UserSupervisor | PageTable::Present
);
TRY(auxiliary_vector.push_back({
.a_type = LibELF::AT_SHARED_PAGE,
.a_un = { .a_ptr = reinterpret_cast<void*>(shared_page_vaddr) },
}));
TRY(auxiliary_vector.push_back({
.a_type = LibELF::AT_NULL,
.a_un = { .a_val = 0 },
@ -873,9 +837,6 @@ namespace Kernel
m_mapped_regions = BAN::move(new_mapped_regions);
m_page_table = BAN::move(new_page_table);
m_shared_page_vaddr = shared_page_vaddr;
m_threads.front()->update_processor_index_address();
execfd_guard.disable();
m_cmdline = BAN::move(str_argv);

View File

@ -13,19 +13,12 @@ namespace Kernel
static constexpr uint32_t MSR_IA32_FS_BASE = 0xC0000100;
static constexpr uint32_t MSR_IA32_GS_BASE = 0xC0000101;
static constexpr uint32_t MSR_IA32_KERNEL_GS_BASE = 0xC0000102;
static constexpr uint32_t MSR_IA32_EFER = 0xC0000080;
static constexpr uint32_t MSR_IA32_STAR = 0xC0000081;
static constexpr uint32_t MSR_IA32_LSTAR = 0xC0000082;
static constexpr uint32_t MSR_IA32_FMASK = 0xC0000084;
#endif
ProcessorID Processor::s_bsp_id { PROCESSOR_NONE };
BAN::Atomic<uint8_t> Processor::s_processor_count { 0 };
BAN::Atomic<bool> Processor::s_is_smp_enabled { false };
BAN::Atomic<bool> Processor::s_should_print_cpu_load { false };
paddr_t Processor::s_shared_page_paddr { 0 };
vaddr_t Processor::s_shared_page_vaddr { 0 };
ProcessorID Processor::s_bsp_id { PROCESSOR_NONE };
BAN::Atomic<uint8_t> Processor::s_processor_count { 0 };
BAN::Atomic<bool> Processor::s_is_smp_enabled { false };
BAN::Atomic<bool> Processor::s_should_print_cpu_load { false };
static BAN::Atomic<uint8_t> s_processors_created { 0 };
@ -35,8 +28,6 @@ namespace Kernel
static BAN::Array<Processor, 0xFF> s_processors;
static BAN::Array<ProcessorID, 0xFF> s_processor_ids { PROCESSOR_NONE };
extern "C" void asm_syscall_handler();
ProcessorID Processor::read_processor_id()
{
uint32_t id;
@ -94,53 +85,13 @@ namespace Kernel
// initialize GS
#if ARCH(x86_64)
{
// set gs base to pointer to this processor
const uint64_t val = reinterpret_cast<uint64_t>(&processor);
const uint32_t val_hi = val >> 32;
const uint32_t val_lo = val & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(val_hi), "a"(val_lo), "c"(MSR_IA32_GS_BASE));
}
// set gs base to pointer to this processor
uint64_t ptr = reinterpret_cast<uint64_t>(&processor);
uint32_t ptr_hi = ptr >> 32;
uint32_t ptr_lo = ptr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(ptr_hi), "a"(ptr_lo), "c"(MSR_IA32_GS_BASE));
#elif ARCH(i686)
asm volatile("movw %0, %%gs" :: "r"(0x28));
#endif
#if ARCH(x86_64)
// enable syscall instruction
asm volatile("rdmsr; orb $1, %%al; wrmsr" :: "c"(MSR_IA32_EFER) : "eax", "edx");
{
union STAR
{
struct
{
uint32_t : 32;
uint16_t sel_ring0;
uint16_t sel_ring3;
};
uint64_t raw;
};
// set kernel and user segments
const uint64_t val = STAR { .sel_ring0 = 0x08, .sel_ring3 = 0x18 | 3 }.raw;
const uint32_t val_hi = val >> 32;
const uint32_t val_lo = val & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(val_hi), "a"(val_lo), "c"(MSR_IA32_STAR));
}
{
// set syscall handler address
const uint64_t val = reinterpret_cast<uint64_t>(&asm_syscall_handler);
const uint32_t val_hi = val >> 32;
const uint32_t val_lo = val & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(val_hi), "a"(val_lo), "c"(MSR_IA32_LSTAR));
}
{
// mask DF and IF
const uint64_t val = (1 << 10) | (1 << 9);
const uint32_t val_hi = val >> 32;
const uint32_t val_lo = val & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(val_hi), "a"(val_lo), "c"(MSR_IA32_FMASK));
}
asm volatile("movw $0x28, %%ax; movw %%ax, %%gs" ::: "ax");
#endif
ASSERT(processor.m_idt);
@ -177,33 +128,6 @@ namespace Kernel
processor.m_smp_free = smp_storage;
}
void Processor::initialize_shared_page()
{
[[maybe_unused]] constexpr size_t max_processors = (PAGE_SIZE - sizeof(API::SharedPage)) / sizeof(decltype(*API::SharedPage::cpus));
ASSERT(s_processors_created < max_processors);
s_shared_page_paddr = Heap::get().take_free_page();
ASSERT(s_shared_page_paddr);
s_shared_page_vaddr = PageTable::kernel().reserve_free_page(KERNEL_OFFSET);
ASSERT(s_shared_page_vaddr);
PageTable::kernel().map_page_at(
s_shared_page_paddr,
s_shared_page_vaddr,
PageTable::ReadWrite | PageTable::Present
);
memset(reinterpret_cast<void*>(s_shared_page_vaddr), 0, PAGE_SIZE);
auto& shared_page = *reinterpret_cast<volatile API::SharedPage*>(s_shared_page_vaddr);
for (size_t i = 0; i <= 0xFF; i++)
shared_page.__sequence[i] = i;
shared_page.features = 0;
ASSERT(Processor::count() + sizeof(Kernel::API::SharedPage) <= PAGE_SIZE);
}
ProcessorID Processor::id_from_index(size_t index)
{
ASSERT(index < s_processor_count);
@ -218,11 +142,8 @@ namespace Kernel
// wait until bsp is ready
if (current_is_bsp())
{
initialize_shared_page();
s_processor_count = 1;
s_processor_ids[0] = current_id();
s_processors[current_id().as_u32()].m_index = 0;
// single processor system
if (s_processors_created == 1)
@ -246,10 +167,9 @@ namespace Kernel
while (s_processor_count == 0)
__builtin_ia32_pause();
const auto index = s_processor_count++;
ASSERT(s_processor_ids[index] == PROCESSOR_NONE);
s_processor_ids[index] = current_id();
s_processors[current_id().as_u32()].m_index = index;
auto lookup_index = s_processor_count++;
ASSERT(s_processor_ids[lookup_index] == PROCESSOR_NONE);
s_processor_ids[lookup_index] = current_id();
uint32_t expected = static_cast<uint32_t>(-1);
s_first_ap_ready_ms.compare_exchange(expected, SystemTimer::get().ms_since_boot());
@ -271,62 +191,6 @@ namespace Kernel
}
}
void Processor::initialize_tsc(uint8_t shift, uint64_t mult, uint64_t realtime_seconds)
{
auto& shared_page = Processor::shared_page();
shared_page.gettime_shared.shift = shift;
shared_page.gettime_shared.mult = mult;
shared_page.gettime_shared.realtime_seconds = realtime_seconds;
update_tsc();
broadcast_smp_message({
.type = SMPMessage::Type::UpdateTSC,
.dummy = 0,
});
bool everyone_initialized { false };
while (!everyone_initialized)
{
everyone_initialized = true;
for (size_t i = 0; i < count(); i++)
{
if (shared_page.cpus[i].gettime_local.seq != 0)
continue;
everyone_initialized = false;
break;
}
}
shared_page.features |= API::SPF_GETTIME;
}
void Processor::update_tsc()
{
auto& sgettime = shared_page().cpus[current_index()].gettime_local;
sgettime.seq = sgettime.seq + 1;
sgettime.last_ns = SystemTimer::get().ns_since_boot_no_tsc();
sgettime.last_tsc = __builtin_ia32_rdtsc();
sgettime.seq = sgettime.seq + 1;
}
uint64_t Processor::ns_since_boot_tsc()
{
const auto& shared_page = Processor::shared_page();
const auto& sgettime = shared_page.gettime_shared;
const auto& lgettime = shared_page.cpus[current_index()].gettime_local;
auto state = get_interrupt_state();
set_interrupt_state(InterruptState::Disabled);
const auto current_ns = lgettime.last_ns + (((__builtin_ia32_rdtsc() - lgettime.last_tsc) * sgettime.mult) >> sgettime.shift);
set_interrupt_state(state);
return current_ns;
}
void Processor::handle_ipi()
{
handle_smp_messages();
@ -376,9 +240,6 @@ namespace Kernel
case SMPMessage::Type::UnblockThread:
processor.m_scheduler->unblock_thread(message->unblock_thread);
break;
case SMPMessage::Type::UpdateTSC:
update_tsc();
break;
#if WITH_PROFILING
case SMPMessage::Type::StartProfiling:
processor.start_profiling();
@ -405,17 +266,36 @@ namespace Kernel
void Processor::load_segments()
{
load_fsbase();
load_gsbase();
{
const auto addr = scheduler().current_thread().get_fsbase();
#if ARCH(x86_64)
uint32_t ptr_hi = addr >> 32;
uint32_t ptr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(ptr_hi), "a"(ptr_lo), "c"(MSR_IA32_FS_BASE));
#elif ARCH(i686)
gdt().set_fsbase(addr);
#endif
}
{
const auto addr = scheduler().current_thread().get_gsbase();
#if ARCH(x86_64)
uint32_t ptr_hi = addr >> 32;
uint32_t ptr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(ptr_hi), "a"(ptr_lo), "c"(MSR_IA32_KERNEL_GS_BASE));
#elif ARCH(i686)
gdt().set_gsbase(addr);
#endif
}
}
void Processor::load_fsbase()
{
const auto addr = scheduler().current_thread().get_fsbase();
#if ARCH(x86_64)
const uint32_t addr_hi = addr >> 32;
const uint32_t addr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(addr_hi), "a"(addr_lo), "c"(MSR_IA32_FS_BASE));
uint32_t ptr_hi = addr >> 32;
uint32_t ptr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(ptr_hi), "a"(ptr_lo), "c"(MSR_IA32_FS_BASE));
#elif ARCH(i686)
gdt().set_fsbase(addr);
#endif
@ -425,9 +305,9 @@ namespace Kernel
{
const auto addr = scheduler().current_thread().get_gsbase();
#if ARCH(x86_64)
const uint32_t addr_hi = addr >> 32;
const uint32_t addr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(addr_hi), "a"(addr_lo), "c"(MSR_IA32_KERNEL_GS_BASE));
uint32_t ptr_hi = addr >> 32;
uint32_t ptr_lo = addr & 0xFFFFFFFF;
asm volatile("wrmsr" :: "d"(ptr_hi), "a"(ptr_lo), "c"(MSR_IA32_KERNEL_GS_BASE));
#elif ARCH(i686)
gdt().set_gsbase(addr);
#endif
@ -495,14 +375,13 @@ namespace Kernel
if (!is_smp_enabled())
return;
const auto state = get_interrupt_state();
auto state = get_interrupt_state();
set_interrupt_state(InterruptState::Disabled);
const auto current_id = Processor::current_id();
for (size_t i = 0; i < Processor::count(); i++)
{
const auto processor_id = s_processor_ids[i];
if (processor_id != current_id)
auto processor_id = s_processor_ids[i];
if (processor_id != current_id())
send_smp_message(processor_id, message, false);
}

View File

@ -284,14 +284,9 @@ namespace Kernel
thread->set_cpu_time_start();
}
Processor::gdt().set_tss_stack(thread->kernel_stack_top());
if (thread->is_userspace())
{
const vaddr_t kernel_stack_top = thread->kernel_stack_top();
Processor::gdt().set_tss_stack(kernel_stack_top);
Processor::set_thread_syscall_stack(kernel_stack_top);
Processor::load_segments();
}
*interrupt_stack = thread->interrupt_stack();
*interrupt_registers = thread->interrupt_registers();
@ -392,9 +387,6 @@ namespace Kernel
else
m_block_queue.add_thread_with_wake_time(node);
if (auto* thread = node->thread; thread->is_userspace() && thread->has_process())
thread->update_processor_index_address();
m_thread_count++;
Processor::set_interrupt_state(state);

View File

@ -1,9 +1,9 @@
#include <BAN/Bitcast.h>
#include <kernel/API/Syscall.h>
#include <kernel/Debug.h>
#include <kernel/InterruptStack.h>
#include <kernel/Process.h>
#include <kernel/Scheduler.h>
#include <kernel/Syscall.h>
#include <kernel/Timer/Timer.h>
#include <termios.h>
@ -40,8 +40,10 @@ namespace Kernel
static bool is_restartable_syscall(int syscall);
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5)
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, InterruptStack* interrupt_stack)
{
ASSERT(GDT::is_user_segment(interrupt_stack->cs));
Processor::set_interrupt_state(InterruptState::Enabled);
Process::current().wait_while_stopped();

View File

@ -295,20 +295,6 @@ namespace Kernel
m_cpu_time_start_ns = UINT64_MAX;
}
void Thread::update_processor_index_address()
{
if (!is_userspace() || !has_process())
return;
const vaddr_t vaddr = process().shared_page_vaddr() + Processor::current_index();
#if ARCH(x86_64)
set_gsbase(vaddr);
#elif ARCH(i686)
set_fsbase(vaddr);
#endif
}
BAN::ErrorOr<Thread*> Thread::pthread_create(entry_t entry, void* arg)
{
auto* thread = TRY(create_userspace(m_process, m_process->page_table()));
@ -490,11 +476,7 @@ namespace Kernel
write_to_stack(cur_sp, 0x20 | 3);
write_to_stack(cur_sp, sp);
write_to_stack(cur_sp, 0x202);
#if ARCH(x86_64)
write_to_stack(cur_sp, 0x28 | 3);
#elif ARCH(i686)
write_to_stack(cur_sp, 0x18 | 3);
#endif
write_to_stack(cur_sp, ip);
});
@ -908,9 +890,9 @@ namespace Kernel
void Thread::save_sse()
{
#if ARCH(x86_64)
__builtin_ia32_fxsave64(m_sse_storage);
asm volatile("fxsave64 %0" :: "m"(m_sse_storage));
#elif ARCH(i686)
__builtin_ia32_fxsave(m_sse_storage);
asm volatile("fxsave %0" :: "m"(m_sse_storage));
#else
#error
#endif
@ -919,9 +901,9 @@ namespace Kernel
void Thread::load_sse()
{
#if ARCH(x86_64)
__builtin_ia32_fxrstor64(m_sse_storage);
asm volatile("fxrstor64 %0" :: "m"(m_sse_storage));
#elif ARCH(i686)
__builtin_ia32_fxrstor(m_sse_storage);
asm volatile("fxrstor %0" :: "m"(m_sse_storage));
#else
#error
#endif

View File

@ -272,8 +272,6 @@ namespace Kernel
m_last_ticks = current_ticks;
}
SystemTimer::get().update_tsc();
if (should_invoke_scheduler())
Processor::scheduler().timer_interrupt();
}

View File

@ -58,8 +58,6 @@ namespace Kernel
m_system_time_ms++;
}
SystemTimer::get().update_tsc();
if (should_invoke_scheduler())
Processor::scheduler().timer_interrupt();
}

View File

@ -1,6 +1,3 @@
#include <BAN/Sort.h>
#include <kernel/CPUID.h>
#include <kernel/Scheduler.h>
#include <kernel/Timer/HPET.h>
#include <kernel/Timer/PIT.h>
@ -57,100 +54,19 @@ namespace Kernel
Kernel::panic("Could not initialize any timer");
}
void SystemTimer::initialize_tsc()
{
if (!CPUID::has_invariant_tsc())
{
dwarnln("CPU does not have an invariant TSC");
return;
}
const uint64_t tsc_freq = get_tsc_frequency();
dprintln("Initialized invariant TSC ({} Hz)", tsc_freq);
const uint8_t tsc_shift = 22;
const uint64_t tsc_mult = (static_cast<uint64_t>(1'000'000'000) << tsc_shift) / tsc_freq;
Processor::initialize_tsc(tsc_shift, tsc_mult, m_boot_time);
m_has_invariant_tsc = true;
}
uint64_t SystemTimer::get_tsc_frequency() const
{
// take 5x 50 ms samples and use the median value
constexpr size_t tsc_sample_count = 5;
constexpr size_t tsc_sample_ns = 50'000'000;
uint64_t tsc_freq_samples[tsc_sample_count];
for (size_t i = 0; i < tsc_sample_count; i++)
{
const auto start_ns = m_timer->ns_since_boot();
const auto start_tsc = ({ __builtin_ia32_lfence(); __builtin_ia32_rdtsc(); });
while (m_timer->ns_since_boot() < start_ns + tsc_sample_ns)
Processor::pause();
const auto stop_tsc = ({ __builtin_ia32_lfence(); __builtin_ia32_rdtsc(); });
const auto stop_ns = m_timer->ns_since_boot();
const auto duration_ns = stop_ns - start_ns;
const auto count_tsc = stop_tsc - start_tsc;
tsc_freq_samples[i] = count_tsc * 1'000'000'000 / duration_ns;
}
BAN::sort::sort(tsc_freq_samples, tsc_freq_samples + tsc_sample_count);
return tsc_freq_samples[tsc_sample_count / 2];
}
void SystemTimer::update_tsc() const
{
if (!m_has_invariant_tsc)
return;
// only update every 100 ms
if (++m_timer_ticks < 100)
return;
m_timer_ticks = 0;
Processor::update_tsc();
Processor::broadcast_smp_message({
.type = Processor::SMPMessage::Type::UpdateTSC,
.dummy = 0,
});
}
uint64_t SystemTimer::ns_since_boot_no_tsc() const
{
return m_timer->ns_since_boot();
}
uint64_t SystemTimer::ms_since_boot() const
{
if (!m_has_invariant_tsc)
return m_timer->ms_since_boot();
return Processor::ns_since_boot_tsc() / 1'000'000;
return m_timer->ms_since_boot();
}
uint64_t SystemTimer::ns_since_boot() const
{
if (!m_has_invariant_tsc)
return m_timer->ns_since_boot();
return Processor::ns_since_boot_tsc();
return m_timer->ns_since_boot();
}
timespec SystemTimer::time_since_boot() const
{
if (!m_has_invariant_tsc)
return m_timer->time_since_boot();
const auto ns_since_boot = Processor::ns_since_boot_tsc();
return {
.tv_sec = static_cast<time_t>(ns_since_boot / 1'000'000'000),
.tv_nsec = static_cast<long>(ns_since_boot % 1'000'000'000)
};
return m_timer->time_since_boot();
}
bool SystemTimer::pre_scheduler_sleep_needs_lock() const

View File

@ -22,6 +22,7 @@
#include <kernel/Processor.h>
#include <kernel/Random.h>
#include <kernel/Scheduler.h>
#include <kernel/Syscall.h>
#include <kernel/Terminal/FramebufferTerminal.h>
#include <kernel/Terminal/Serial.h>
#include <kernel/Terminal/VirtualTTY.h>
@ -207,8 +208,6 @@ static void init2(void*)
dprintln("Scheduler started");
SystemTimer::get().initialize_tsc();
auto console = MUST(DevFileSystem::get().root_inode()->find_inode(cmdline.console));
ASSERT(console->is_tty());
static_cast<Kernel::TTY*>(console.ptr())->set_as_current();

View File

@ -1,8 +1,8 @@
#!/bin/bash ../install.sh
NAME='freetype'
VERSION='2.14.1'
DOWNLOAD_URL="https://download.savannah.gnu.org/releases/freetype/freetype-$VERSION.tar.xz#32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc"
VERSION='2.13.3'
DOWNLOAD_URL="https://download.savannah.gnu.org/releases/freetype/freetype-$VERSION.tar.gz#5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747"
DEPENDENCIES=('zlib' 'libpng')
CONFIG_SUB=('builds/unix/config.sub')
CONFIGURE_OPTIONS=(

View File

@ -3,11 +3,12 @@
NAME='openal-soft'
VERSION='1.24.3'
DOWNLOAD_URL="https://github.com/kcat/openal-soft/archive/refs/tags/$VERSION.tar.gz#7e1fecdeb45e7f78722b776c5cf30bd33934b961d7fd2a11e0494e064cc631ce"
DEPENDENCIES=('SDL2' 'zlib' 'libsndfile')
DEPENDENCIES=('zlib' 'libsndfile')
configure() {
$BANAN_CMAKE -B build -S . -G Ninja --fresh \
$BANAN_CMAKE \
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
-B build -G Ninja --fresh . \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE=Release \
-DALSOFT_EXAMPLES=OFF \

View File

@ -1,8 +1,8 @@
#!/bin/bash ../install.sh
NAME='openssl'
VERSION='3.6.0'
DOWNLOAD_URL="https://github.com/openssl/openssl/releases/download/openssl-$VERSION/openssl-$VERSION.tar.gz#b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9"
VERSION='3.3.1'
DOWNLOAD_URL="https://github.com/openssl/openssl/releases/download/openssl-$VERSION/openssl-$VERSION.tar.gz#777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e"
DEPENDENCIES=('zlib')
MAKE_INSTALL_TARGETS=('install_sw' 'install_ssldirs')

View File

@ -0,0 +1,12 @@
diff -ruN openssl-3.3.1/crypto/bio/bss_dgram.c openssl-3.3.1-banan_os/crypto/bio/bss_dgram.c
--- openssl-3.3.1/crypto/bio/bss_dgram.c 2024-06-04 15:53:04.000000000 +0300
+++ openssl-3.3.1-banan_os/crypto/bio/bss_dgram.c 2025-06-01 19:48:55.088806701 +0300
@@ -61,7 +61,7 @@
# define NO_RECVMMSG
# endif
# endif
-# if defined(__GNU__)
+# if defined(__GNU__) || defined(__banan_os__)
/* GNU/Hurd does not have IP_PKTINFO yet */
#undef NO_RECVMSG
#define NO_RECVMSG

View File

@ -34,16 +34,10 @@ NET_ARGS="-device e1000e,netdev=net $NET_ARGS"
USB_ARGS='-device qemu-xhci -device usb-kbd,port=1 -device usb-hub,port=2 -device usb-tablet,port=2.1'
#SOUND_ARGS='-device ac97'
SOUND_ARGS='-device intel-hda -device hda-output'
if [[ $@ == *"-accel kvm"* ]]; then
CPU_ARGS='-cpu host,migratable=off'
fi
SOUND_ARGS='-device ac97'
qemu-system-$QEMU_ARCH \
-m 1G -smp 4 \
$CPU_ARGS \
$BIOS_ARGS \
$USB_ARGS \
$DISK_ARGS \

View File

@ -2,8 +2,6 @@
#include <BAN/Debug.h>
#include <BAN/Math.h>
#include <kernel/API/SharedPage.h>
#include <ctype.h>
#include <errno.h>
#include <langinfo.h>
@ -17,53 +15,9 @@ int daylight;
long timezone;
char* tzname[2];
extern volatile Kernel::API::SharedPage* g_shared_page;
int clock_gettime(clockid_t clock_id, struct timespec* tp)
{
if (clock_id != CLOCK_MONOTONIC && clock_id != CLOCK_REALTIME)
return syscall(SYS_CLOCK_GETTIME, clock_id, tp);
if (g_shared_page == nullptr || !(g_shared_page->features & Kernel::API::SPF_GETTIME))
return syscall(SYS_CLOCK_GETTIME, clock_id, tp);
const auto get_cpu =
[]() -> uint8_t {
uint8_t cpu;
#if defined(__x86_64__)
asm volatile("movb %%gs:0, %0" : "=r"(cpu));
#elif defined(__i686__)
asm volatile("movb %%fs:0, %0" : "=q"(cpu));
#endif
return cpu;
};
for (;;)
{
const auto cpu = get_cpu();
const auto& sgettime = g_shared_page->gettime_shared;
const auto& lgettime = g_shared_page->cpus[cpu].gettime_local;
const auto old_seq = lgettime.seq;
if (old_seq & 1)
continue;
const auto monotonic_ns = lgettime.last_ns + (((__builtin_ia32_rdtsc() - lgettime.last_tsc) * sgettime.mult) >> sgettime.shift);
if (old_seq != lgettime.seq || cpu != get_cpu())
continue;
*tp = {
.tv_sec = static_cast<time_t>(monotonic_ns / 1'000'000'000),
.tv_nsec = static_cast<long>(monotonic_ns % 1'000'000'000)
};
if (clock_id == CLOCK_REALTIME)
tp->tv_sec += sgettime.realtime_seconds;
return monotonic_ns;
}
return syscall(SYS_CLOCK_GETTIME, clock_id, tp);
}
int clock_getres(clockid_t clock_id, struct timespec* res)

View File

@ -2,11 +2,8 @@
#include <BAN/Debug.h>
#include <BAN/StringView.h>
#include <LibELF/AuxiliaryVector.h>
#include <kernel/API/SharedPage.h>
#include <kernel/API/Syscall.h>
#include <kernel/Memory/Types.h>
#include <kernel/Syscall.h>
#include <ctype.h>
#include <dlfcn.h>
@ -34,8 +31,6 @@ struct init_funcs_t
extern "C" char** environ;
volatile Kernel::API::SharedPage* g_shared_page = nullptr;
#define DUMP_BACKTRACE 1
#define DEMANGLE_BACKTRACE 0
@ -45,28 +40,11 @@ volatile Kernel::API::SharedPage* g_shared_page = nullptr;
static void __dump_backtrace(int, siginfo_t*, void*);
static LibELF::AuxiliaryVector* find_auxv(char** envp)
{
if (envp == nullptr)
return nullptr;
char** null_env = envp;
while (*null_env)
null_env++;
return reinterpret_cast<LibELF::AuxiliaryVector*>(null_env + 1);
}
extern "C" void _init_libc(char** environ, init_funcs_t init_funcs, init_funcs_t fini_funcs)
{
if (::environ == nullptr)
::environ = environ;
if (auto* auxv = find_auxv(environ))
for (auto* aux = auxv; aux->a_type != LibELF::AT_NULL; aux++)
if (aux->a_type == LibELF::AT_SHARED_PAGE)
g_shared_page = static_cast<Kernel::API::SharedPage*>(aux->a_un.a_ptr);
#if defined(__x86_64__)
if (uthread* self = reinterpret_cast<uthread*>(syscall(SYS_GET_FSBASE)))
#elif defined(__i686__)

View File

@ -23,8 +23,6 @@ namespace LibELF
AT_PHDR = 3,
AT_PHENT = 4,
AT_PHNUM = 5,
AT_SHARED_PAGE = 0xFFFF0001,
};
}

View File

@ -1,7 +1,7 @@
#pragma once
#include <BAN/Traits.h>
#include <kernel/API/Syscall.h>
#include <kernel/Syscall.h>
#include <stddef.h>
#include <stdint.h>