Compare commits

...

12 Commits

Author SHA1 Message Date
Bananymous b30a79c7fe Kernel: Temporary hack to "fix" munmap
My current munmap implementation does not support partial unmaps and
GCC relies on this behaviour. This patch removes unmapping if the
address and len does not fully contain the mmap region.
2025-02-01 22:25:22 +02:00
Bananymous 22374ac8f7 ports: Add make port 2025-01-28 22:50:11 +02:00
Bananymous 17014bb8de LibC: Fix strndup
I did not null terminate short strndup copies :D
2025-01-28 22:40:06 +02:00
Bananymous d1c3d3d5aa Kernel: Fix ANSI CSI L
With my new memcpy implementation this crashed. I have no idea how this
was not crashing before :D
2025-01-28 18:41:53 +02:00
Bananymous 7fedd94cc5 ln: Don't require link target to exist for symlinks 2025-01-28 17:46:36 +02:00
Bananymous 48eca3d031 LibC: Make libc usable with tcc
tcc does not provide its own stdint.h but defines everything in
stddef.h. Also tcc does not support [[noreturn]] attribute syntax.
2025-01-28 17:27:41 +02:00
Bananymous 21d3cf91a0 LibC: Implement some missing signal.h functions 2025-01-28 17:27:41 +02:00
Bananymous 5938cc4086 Kernel: Support pselect sigmask 2025-01-28 17:17:59 +02:00
Bananymous 7c57d736c6 Kernel/LibC: Fix dirent functions
dirent functions used to fail if a directory contained more than 128
files :D
2025-01-28 17:15:11 +02:00
Bananymous cbe3f2a4ac BuildSystem: Cleanup and fix cmake files
I now set library SONAME so i don't have to build them in build root.

Creating font now makes sure the install directory exists. This allows
building using make files.

LibC now links agains ligcc
2025-01-28 17:11:21 +02:00
Bananymous 7a10e0e347 Kernel: Fix TmpFS inode linking
TmpFS now looks for empty entries in directories instead of always
appending files to the end of directories. This makes kernel not crash
after process pid 126 is created :D
2025-01-28 17:06:35 +02:00
Bananymous efb577769e ports: Add nasm port 2025-01-25 23:10:04 +02:00
21 changed files with 328 additions and 51 deletions

View File

@ -11,5 +11,8 @@ banan_link_library(ban libc)
set_target_properties(ban PROPERTIES OUTPUT_NAME libban)
# set SONAME as cmake doesn't set it for some reason??
set_target_properties(ban PROPERTIES LINK_FLAGS "-Wl,-soname,libban.so")
banan_install_headers(ban)
install(TARGETS ban OPTIONAL)

View File

@ -27,9 +27,6 @@ set(BUILD_SHARED_LIBS True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
# include headers of ${library} to ${target}
function(banan_include_headers target library)
target_include_directories(${target} PRIVATE $<TARGET_PROPERTY:${library},SOURCE_DIR>/include)

View File

@ -245,7 +245,7 @@ endif()
add_custom_command(
OUTPUT font/prefs.psf.o
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && objcopy -O ${ELF_FORMAT} -B i386 -I binary font/prefs.psf ${CMAKE_CURRENT_BINARY_DIR}/font/prefs.psf.o
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/font && objcopy -O ${ELF_FORMAT} -B i386 -I binary font/prefs.psf ${CMAKE_CURRENT_BINARY_DIR}/font/prefs.psf.o
)
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_COMPILER} <CMAKE_CXX_LINK_FLAGS> <FLAGS> <LINK_FLAGS> -o <TARGET> ${CMAKE_CURRENT_BINARY_DIR}/crti.o ${CMAKE_CURRENT_BINARY_DIR}/crtbegin.o <OBJECTS> ${CMAKE_CURRENT_BINARY_DIR}/crtend.o ${CMAKE_CURRENT_BINARY_DIR}/crtn.o -lgcc ")

View File

@ -562,39 +562,86 @@ namespace Kernel
new_entry_size += directory_entry_alignment - rem;
ASSERT(new_entry_size < (size_t)blksize());
size_t new_entry_offset = size() % blksize();
// Target is the last block, or if it doesn't fit the new entry, the next one.
size_t target_data_block = size() / blksize();
if (blksize() - new_entry_offset < new_entry_size)
for (size_t data_block_index = 0; data_block_index * blksize() < (size_t)size(); data_block_index++)
{
// insert an empty entry at the end of current block
m_fs.with_block_buffer(block_index(target_data_block).value(), [&](BAN::ByteSpan bytespan) {
auto& empty_entry = bytespan.slice(new_entry_offset).as<TmpDirectoryEntry>();
empty_entry.type = DT_UNKNOWN;
empty_entry.ino = 0;
empty_entry.rec_len = blksize() - new_entry_offset;
});
m_inode_info.size += blksize() - new_entry_offset;
const size_t block_index = this->block_index(data_block_index).value();
target_data_block++;
new_entry_offset = 0;
bool done = false;
m_fs.with_block_buffer(block_index, [&](BAN::ByteSpan bytespan) {
bytespan = bytespan.slice(0, blksize());
while (bytespan.size() > 0)
{
auto& entry = bytespan.as<TmpDirectoryEntry>();
while (entry.ino == 0 && entry.rec_len < bytespan.size())
{
auto& next_entry = bytespan.slice(entry.rec_len).as<TmpDirectoryEntry>();
if (next_entry.ino)
break;
entry.rec_len += next_entry.rec_len;
}
if (entry.ino != 0 || entry.rec_len < new_entry_size)
{
bytespan = bytespan.slice(entry.rec_len);
continue;
}
if (entry.rec_len <= new_entry_size + sizeof(TmpDirectoryEntry))
new_entry_size = entry.rec_len;
else
{
auto& new_entry = bytespan.slice(new_entry_size).as<TmpDirectoryEntry>();
new_entry.type = DT_UNKNOWN;
new_entry.ino = 0;
new_entry.rec_len = entry.rec_len - new_entry_size;
}
ASSERT(entry.type == DT_UNKNOWN);
entry.type = inode_mode_to_dt_type(inode.mode());
entry.ino = inode.ino();
entry.name_len = name.size();
entry.rec_len = new_entry_size;
memcpy(entry.name, name.data(), name.size());
done = true;
break;
}
});
if (done)
{
// add link to linked inode
inode.m_inode_info.nlink++;
return {};
}
}
size_t block_index = TRY(block_index_with_allocation(target_data_block));
const size_t data_block_index = size() / blksize();
const size_t block_index = TRY(block_index_with_allocation(data_block_index));
m_fs.with_block_buffer(block_index, [&](BAN::ByteSpan bytespan) {
auto& new_entry = bytespan.slice(new_entry_offset).as<TmpDirectoryEntry>();
ASSERT(new_entry.type == DT_UNKNOWN);
new_entry.type = inode_mode_to_dt_type(inode.mode());
new_entry.ino = inode.ino();
new_entry.name_len = name.size();
new_entry.rec_len = new_entry_size;
memcpy(new_entry.name, name.data(), name.size());
// insert new inode
{
auto& entry = bytespan.as<TmpDirectoryEntry>();
entry.type = inode_mode_to_dt_type(inode.mode());
entry.ino = inode.ino();
entry.name_len = name.size();
entry.rec_len = new_entry_size;
memcpy(entry.name, name.data(), name.size());
}
// insert null entry
{
auto& entry = bytespan.slice(new_entry_size).as<TmpDirectoryEntry>();
entry.type = DT_UNKNOWN;
entry.ino = 0;
entry.rec_len = blksize() - new_entry_size;
}
});
// increase current size
m_inode_info.size += new_entry_size;
m_inode_info.size += blksize();
// add link to linked inode
inode.m_inode_info.nlink++;
@ -616,7 +663,7 @@ namespace Kernel
while (bytespan.size() > 0)
{
auto& entry = bytespan.as<TmpDirectoryEntry>();
if (entry.type != DT_UNKNOWN)
if (entry.ino != 0)
{
switch (callback(entry))
{

View File

@ -330,8 +330,11 @@ namespace Kernel
return BAN::Error::from_errno(EACCES);
for (;;)
{
auto ret = open_file.inode()->list_next_inodes(open_file.offset()++, list, list_len);
if (ret.is_error() && ret.error().get_error_code() == ENODATA)
auto ret = open_file.inode()->list_next_inodes(open_file.offset(), list, list_len);
if (ret.is_error() && ret.error().get_error_code() != ENODATA)
return ret;
open_file.offset()++;
if (ret.is_error())
continue;
return ret;
}

View File

@ -1379,8 +1379,10 @@ namespace Kernel
if (arguments->sigmask)
TRY(validate_pointer_access(arguments->sigmask, sizeof(sigset_t), false));
const auto old_sigmask = Thread::current().m_signal_block_mask;
if (arguments->sigmask)
return BAN::Error::from_errno(ENOTSUP);
Thread::current().m_signal_block_mask = *arguments->sigmask;
BAN::ScopeGuard sigmask_restore([old_sigmask] { Thread::current().m_signal_block_mask = old_sigmask; });
uint64_t timedout_ns = SystemTimer::get().ns_since_boot();
if (arguments->timeout)
@ -1737,16 +1739,29 @@ namespace Kernel
if (len == 0)
return BAN::Error::from_errno(EINVAL);
vaddr_t vaddr = (vaddr_t)addr;
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
if (vaddr % PAGE_SIZE != 0)
return BAN::Error::from_errno(EINVAL);
if (auto rem = len % PAGE_SIZE)
len += PAGE_SIZE - rem;
LockGuard _(m_process_lock);
// FIXME: We should only map partial regions
// FIXME: We should unmap partial regions.
// This is a hack to only unmap if the whole mmap region
// is contained within [addr, addr + len]
for (size_t i = 0; i < m_mapped_regions.size(); i++)
if (m_mapped_regions[i]->overlaps(vaddr, len))
m_mapped_regions.remove(i);
{
auto& region = m_mapped_regions[i];
const vaddr_t region_s = region->vaddr();
const vaddr_t region_e = region->vaddr() + region->size();
if (vaddr <= region_s && region_e <= vaddr + len)
m_mapped_regions.remove(i--);
else if (region->overlaps(vaddr, len))
dwarnln("TODO: partial region munmap");
}
return 0;
}

View File

@ -269,8 +269,8 @@ namespace Kernel
for (uint32_t row = m_height; row > m_row; row--)
{
const uint32_t dst_y = row - 1;
const uint32_t src_y = dst_y - m_ansi_state.nums[0];
memcpy(&m_buffer[dst_y * m_width], &m_buffer[src_y * m_width], m_width * sizeof(Cell));
if (const uint32_t src_y = dst_y - m_ansi_state.nums[0]; src_y < dst_y)
memcpy(&m_buffer[dst_y * m_width], &m_buffer[src_y * m_width], m_width * sizeof(Cell));
for (uint32_t x = 0; x < m_width; x++)
render_from_buffer(x, dst_y);
}

11
ports/make/build.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash ../install.sh
NAME='make'
VERSION='4.4.1'
DOWNLOAD_URL="https://ftp.gnu.org/gnu/make/make-$VERSION.tar.gz#dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3"
CONFIGURE_OPTIONS=(
'--with-sysroot=/'
'--disable-nls'
'--disable-posix-spawn'
'--enable-year2038'
)

View File

@ -0,0 +1,12 @@
diff -ruN make-4.4.1/build-aux/config.sub make-4.4.1-banan_os/build-aux/config.sub
--- make-4.4.1/build-aux/config.sub 2023-02-18 17:38:13.000000000 +0200
+++ make-4.4.1-banan_os/build-aux/config.sub 2024-12-04 23:15:11.865989888 +0200
@@ -1758,7 +1758,7 @@
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* | mlibc* )
+ | fiwix* | mlibc* | banan_os* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)

View File

@ -0,0 +1,12 @@
diff -ruN make-4.4.1/src/arscan.c make-4.4.1-banan_os/src/arscan.c
--- make-4.4.1/src/arscan.c 2023-01-08 17:45:38.000000000 +0200
+++ make-4.4.1-banan_os/src/arscan.c 2024-12-04 23:49:39.898722479 +0200
@@ -331,7 +331,7 @@
#endif
#ifndef WINDOWS32
-# if !defined (__ANDROID__) && !defined (__BEOS__) && !defined(MK_OS_ZOS)
+# if !defined (__ANDROID__) && !defined (__BEOS__) && !defined(MK_OS_ZOS) && !defined(__banan_os__)
# include <ar.h>
# else
/* These platforms don't have <ar.h> but have archives in the same format

8
ports/nasm/build.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash ../install.sh
NAME='nasm'
VERSION='2.16.03'
DOWNLOAD_URL="https://www.nasm.us/pub/nasm/releasebuilds/$VERSION/nasm-$VERSION.tar.gz#5bc940dd8a4245686976a8f7e96ba9340a0915f2d5b88356874890e207bdb581"
CONFIGURE_OPTIONS=(
'--disable-gdb'
)

View File

@ -0,0 +1,12 @@
diff -ruN nasm-2.16.03/autoconf/helpers/config.sub nasm-2.16.03-banan_os/autoconf/helpers/config.sub
--- nasm-2.16.03/autoconf/helpers/config.sub 2024-04-17 20:04:08.000000000 +0300
+++ nasm-2.16.03-banan_os/autoconf/helpers/config.sub 2024-08-18 18:47:13.768447183 +0300
@@ -1754,7 +1754,7 @@
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* )
+ | fiwix* | banan_os* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)

View File

@ -0,0 +1,50 @@
diff -ruN nasm-2.16.03/nasmlib/file.c nasm-2.16.03-banan_os/nasmlib/file.c
--- nasm-2.16.03/nasmlib/file.c 2024-04-17 20:04:08.000000000 +0300
+++ nasm-2.16.03-banan_os/nasmlib/file.c 2025-01-25 23:07:51.415526537 +0200
@@ -160,30 +160,7 @@
osfname = os_mangle_filename(filename);
if (osfname) {
- os_fopenflag fopen_flags[4];
- memset(fopen_flags, 0, sizeof fopen_flags);
-
- fopen_flags[0] = 'r';
- fopen_flags[1] = (flags & NF_TEXT) ? 't' : 'b';
-
-#if defined(__GLIBC__) || defined(__linux__)
- /*
- * Try to open this file with memory mapping for speed, unless we are
- * going to do it "manually" with nasm_map_file()
- */
- if (!(flags & NF_FORMAP))
- fopen_flags[2] = 'm';
-#endif
-
- while (true) {
- f = os_fopen(osfname, fopen_flags);
- if (f || errno != EINVAL || !fopen_flags[2])
- break;
-
- /* We got EINVAL but with 'm'; try again without 'm' */
- fopen_flags[2] = '\0';
- }
-
+ f = os_fopen(osfname, "r");
os_free_filename(osfname);
}
@@ -201,13 +178,7 @@
osfname = os_mangle_filename(filename);
if (osfname) {
- os_fopenflag fopen_flags[3];
-
- fopen_flags[0] = 'w';
- fopen_flags[1] = (flags & NF_TEXT) ? 't' : 'b';
- fopen_flags[2] = '\0';
-
- f = os_fopen(osfname, fopen_flags);
+ f = os_fopen(osfname, "w");
os_free_filename(osfname);
}

View File

@ -21,5 +21,8 @@ foreach(library ${USERSPACE_LIBRARIES})
target_link_options(${library_lower} PRIVATE -nolibc)
# Default compile options
target_compile_options(${library_lower} PRIVATE -g -O2 -Wall -Wextra -Werror)
# set SONAME as cmake doesn't set it for some reason??
set_target_properties(${library_lower} PROPERTIES LINK_FLAGS "-Wl,-soname,${library_lower}.so")
endif()
endforeach()

View File

@ -76,7 +76,10 @@ add_library(libc-static STATIC $<TARGET_OBJECTS:objlibc>)
add_library(libc-shared SHARED $<TARGET_OBJECTS:objlibc>)
target_link_options(libc-static PRIVATE -nostdlib)
target_link_libraries(libc-static PRIVATE -lgcc)
target_link_options(libc-shared PRIVATE -nostdlib)
target_link_libraries(libc-shared PRIVATE -lgcc)
install(TARGETS libc-static OPTIONAL)
install(TARGETS libc-shared OPTIONAL)
@ -84,6 +87,9 @@ install(TARGETS libc-shared OPTIONAL)
set_target_properties(libc-static PROPERTIES OUTPUT_NAME libc)
set_target_properties(libc-shared PROPERTIES OUTPUT_NAME libc)
# set SONAME as cmake doesn't set it for some reason??
set_target_properties(libc-shared PROPERTIES LINK_FLAGS "-Wl,-soname,libc.so")
add_library(libc ALIAS libc-shared)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libgcc_s.so OUTPUT_VARIABLE LIBGCC_S_LINK OUTPUT_STRIP_TRAILING_WHITESPACE)

View File

@ -10,9 +10,10 @@ struct __DIR
int fd { -1 };
size_t entry_count { 0 };
size_t entry_index { 0 };
// FIXME: we should probably allocate entries dynamically
// based if syscall returns ENOBUFS
dirent entries[128];
size_t entries_size { 0 };
dirent* entries { nullptr };
static constexpr size_t default_entries_size { 128 };
};
int closedir(DIR* dirp)
@ -42,10 +43,18 @@ int dirfd(DIR* dirp)
DIR* fdopendir(int fd)
{
DIR* dirp = (DIR*)malloc(sizeof(DIR));
DIR* dirp = static_cast<DIR*>(malloc(sizeof(DIR)));
if (dirp == nullptr)
return nullptr;
dirp->entries = static_cast<dirent*>(malloc(DIR::default_entries_size * sizeof(dirent)));
dirp->entries_size = DIR::default_entries_size;
if (dirp->entries == nullptr)
{
free(dirp);
return nullptr;
}
dirp->fd = fd;
dirp->entry_count = 0;
dirp->entry_index = 0;
@ -73,7 +82,18 @@ struct dirent* readdir(DIR* dirp)
if (dirp->entry_index < dirp->entry_count)
return &dirp->entries[dirp->entry_index];
long entry_count = syscall(SYS_READ_DIR, dirp->fd, dirp->entries, sizeof(dirp->entries) / sizeof(dirp->entries[0]));
readdir_do_syscall:
long entry_count = syscall(SYS_READ_DIR, dirp->fd, dirp->entries, dirp->entries_size);
if (entry_count == -1 && errno == ENOBUFS)
{
const size_t new_entries_size = dirp->entries_size * 2;
dirent* new_entries = static_cast<dirent*>(malloc(new_entries_size * sizeof(dirent)));
if (new_entries == nullptr)
return nullptr;
dirp->entries = new_entries;
dirp->entries_size = new_entries_size;
goto readdir_do_syscall;
}
if (entry_count <= 0)
return nullptr;

View File

@ -13,7 +13,8 @@
__BEGIN_DECLS
[[noreturn]] void __assert_fail(const char*, const char*, int, const char*);
__attribute__((noreturn))
void __assert_fail(const char*, const char*, int, const char*);
__END_DECLS

View File

@ -0,0 +1,5 @@
#ifdef __TINYC__
#include <stddef.h>
#else
#include_next <stdint.h>
#endif

View File

@ -1,4 +1,5 @@
#include <BAN/Assert.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/syscall.h>
@ -6,11 +7,29 @@
static_assert(sizeof(sigset_t) * 8 >= _SIGMAX);
static int validate_signal(int sig)
{
if (_SIGMIN <= sig && sig <= _SIGMAX)
return 0;
errno = EINVAL;
return -1;
}
int kill(pid_t pid, int sig)
{
return syscall(SYS_KILL, pid, sig);
}
int killpg(pid_t pgrp, int sig)
{
if (pgrp <= 1)
{
errno = EINVAL;
return -1;
}
return kill(-pgrp, sig);
}
void psignal(int signum, const char* message)
{
if (message && *message)
@ -37,10 +56,20 @@ int sigaction(int sig, const struct sigaction* __restrict act, struct sigaction*
int sigaddset(sigset_t* set, int signo)
{
if (validate_signal(signo) == -1)
return -1;
*set |= 1ull << signo;
return 0;
}
int sigdelset(sigset_t* set, int signo)
{
if (validate_signal(signo) == -1)
return -1;
*set &= ~(1ull << signo);
return 0;
}
int sigemptyset(sigset_t* set)
{
*set = 0;
@ -53,8 +82,40 @@ int sigfillset(sigset_t* set)
return 0;
}
int sighold(int sig)
{
if (validate_signal(sig) == -1)
return -1;
sigset_t set;
(void)sigemptyset(&set);
(void)sigaddset(&set, sig);
return sigprocmask(SIG_BLOCK, &set, nullptr);
}
int sigignore(int sig)
{
if (signal(sig, SIG_IGN) == SIG_ERR)
return -1;
return 0;
}
int siginterrupt(int sig, int flag)
{
if (validate_signal(sig) == -1)
return -1;
struct sigaction act;
(void)sigaction(sig, nullptr, &act);
if (flag)
act.sa_flags &= ~SA_RESTART;
else
act.sa_flags |= SA_RESTART;
return sigaction(sig, &act, nullptr);
}
int sigismember(const sigset_t* set, int signo)
{
if (validate_signal(signo) == -1)
return -1;
return (*set >> signo) & 1;
}
@ -79,3 +140,13 @@ int sigprocmask(int how, const sigset_t* __restrict set, sigset_t* __restrict os
{
return pthread_sigmask(how, set, oset);
}
int sigrelse(int sig)
{
if (validate_signal(sig) == -1)
return -1;
sigset_t set;
(void)sigemptyset(&set);
(void)sigaddset(&set, sig);
return sigprocmask(SIG_UNBLOCK, &set, nullptr);
}

View File

@ -189,27 +189,28 @@ int strcoll(const char* s1, const char* s2)
char* strdup(const char* str)
{
const size_t size = strlen(str) + 1;
const size_t size = strlen(str);
char* new_str = (char*)malloc(size);
char* new_str = (char*)malloc(size + 1);
if (new_str == nullptr)
return nullptr;
memcpy(new_str, str, size);
new_str[size] = '\0';
return new_str;
}
char* strndup(const char* str, size_t size)
{
if (strlen(str) < size)
size = strlen(str);
size += 1;
if (size_t len = strlen(str); len < size)
size = len;
char* new_str = (char*)malloc(size);
char* new_str = (char*)malloc(size + 1);
if (new_str == nullptr)
return nullptr;
memcpy(new_str, str, size);
new_str[size] = '\0';
return new_str;
}

View File

@ -43,7 +43,7 @@ int main(int argc, const char* argv[])
const char* target = argv[i++];
struct stat st;
if (stat(target, &st) == -1)
if (!do_symlink && stat(target, &st) == -1)
{
perror("stat");
return 1;