#Ilobilix - a linux compatible kernel

1 messages ยท Page 2 of 1

chilly pond
#

send the error or it works fine

worn sierra
chilly pond
#

should be in your distro's repo

worn sierra
#

yea

#

now your repos is broken

chilly pond
#

bruh

worn sierra
#

bruh

chilly pond
#

I have some fixing to do

worn sierra
#

tbh i just wanted a compile_commands json so i can search through the source code

chilly pond
# worn sierra

I can't reproduce either of those errors
can you try cloning with --recursive instead of updating after?

#

the xmake one might have been a github thing because v3.0.0 was released only a few minutes ago

worn sierra
#

nope still broken

chilly pond
#

smh

worn sierra
chilly pond
worn sierra
#

k

#

@chilly pond now the config doesn't work

#

this is crazy

chilly pond
#

?????

worn sierra
chilly pond
#

๐Ÿ˜ญ

worn sierra
#

๐Ÿ˜ญ do you have a ci

chilly pond
#

no ๐Ÿ˜ญ

#

I should

worn sierra
#

like bruh

#

can you just send me your compile_commands.json

#

idk if that works

#

maybe the paths are absolute

chilly pond
chilly pond
worn sierra
#

nothing

#

i just followed the readme

chilly pond
#

or xmake run

worn sierra
#

yknow I WOULD

chilly pond
#

I regret using xmake

chilly pond
# worn sierra

what xmake version is that and how did you install it?

worn sierra
#

arch repos

#

2.9.9

chilly pond
#

ah

chilly pond
#

it should work

#

hopefully

worn sierra
#

yea works

chilly pond
#

nice

worn sierra
#

maybe hard code the xmake version

#

relying on the latest commit will break

chilly pond
#

hmm yeah

worn sierra
#

ok im gonna look at your vfs code now

worn sierra
#

@chilly pond what is a vfs::path?

chilly pond
worn sierra
#

when do you need that

chilly pond
#

when going up from a mountpoint to parent dentry

#

that solves the multiple mounts for single fs issue

worn sierra
#

right

chilly pond
#

idk

#

when I'm feeling better

worn sierra
#

@chilly pond wth is this input parameter

worn sierra
#

source?

chilly pond
#

yes like /dev/sda1

worn sierra
#

but i thought path stores an entry and struct mount

chilly pond
#

it does

worn sierra
#

wouldn't it make more sense to store a reference to struct mount in dentry

#

like

worn sierra
#
struct dentry {
    ...
    std::optional<std::shared_ptr<mount>> mount;
};
chilly pond
#

no because there could be multiple paths with different mounts all referring to the same file

light cosmos
#

so the thing is

#

the very same dentry in memory is used for two different mount points of the same filesystem

chilly pond
#

it was shared_ptr before and I probably left it

worn sierra
#

also unmount() on a fs::instance doesn't make sense, right?

chilly pond
#

right

#

it should take struct mount as an argument

worn sierra
#

but like

#

why does mount take a path

#

if that already points to a mount

chilly pond
#

I don't understand what you mean

worn sierra
#

path contains a struct entry and a struct mount

chilly pond
#

yes

worn sierra
#

why exactly are you passing a struct mount to the mount() function

chilly pond
#

huh true

worn sierra
#

i would expect to pass just an entry

chilly pond
#

just dentry should work fine

#

more stuff like this might come up when I do a real filesystem :P

worn sierra
#

different paths would be different dentry's

#

they can point to the same inode

chilly pond
#

no, then you would need to duplicate every dentry of the filesystem

#

/dev/sda1 mounted on /abcd/mnt1 and /home/user/mnt2
one path could be mount: /abcd/mnt1 and dentry: {/dev/sda1}/file.txt while other path can be mount: /home/user/mnt2 but the same dentry

light cosmos
#

two paths are different if path.mount differs or path.dentry differs

worn sierra
#

bruh

#

from looking at the code, it seems like entrys are basically always connected with a mount point

light cosmos
#

which code?

chilly pond
#

shitobilix code

worn sierra
#

i think i'm actually being filtered by this shit

chilly pond
#

filtered?

worn sierra
#

in my mind a dentry is the result of a URI path conversion to a hierarchical structure

chilly pond
#

that would be vfs::path

worn sierra
#

no that's just the representation

#

so /home/user/mnt2 would be a different entry than /abcd/mnt1

#

because mnt1 has abcd as a parent

chilly pond
#

I get why windows uses that shitty simple mount system

chilly pond
worn sierra
#

oh yea but as a vfs you shouldn't care about that

#

the inodes should be the same

#

but not the dentry's

chilly pond
#

then you have as many duplicates of dentries as you have mounts

#

that is simply inefficient

worn sierra
#

i mean you also have a dentry for every failed lookup

chilly pond
#

I don't

worn sierra
#

i do

chilly pond
worn sierra
#

wdym synchronise

#

there's nothing to be synchronised

chilly pond
#

if a file is deleted from under one mounpoint, how does another one know that it's deleted? you would need some hacky workarounds

worn sierra
#

the inode is what's being deleted

#

if you want to access an inode from a dentry you have to validate it first

chilly pond
#

so you keep the dentry allocated until you access it? what if you never do so?

worn sierra
#

if a file is never accessed, nothing gets allocated

chilly pond
#

accessed once, allocated, inode deleted, multiple dentries stay under multiple mountpoints

worn sierra
#

they stay but the fs instance can update a dentry and invalidate it

chilly pond
#

how?

worn sierra
#

by setting inode to None

chilly pond
#

in every dentry in every mountpoint?

worn sierra
#

only the things that are accessed

#

idk how to explain it

chilly pond
#

yes I understand what you mean

#

but as I see it that's inefficient and slow

#

and tricky to get right

worn sierra
#

linux does that afaict

#

unlink calls d_invalidate

chilly pond
#

as @light cosmos told me, linux does what I do

worn sierra
#

because unlink takes in a dentry

#

unless i'm misinterpreting this code

chilly pond
#

I don't see anything about dentries for same inode under different mounts

#

this is indeed complicated, took me a bit to get how it works

worn sierra
#

damn

#

i can see that linux records the mounts in the struct superblock

#

and not in a dentry

chilly pond
#

ah good to hear that because I thought I was doing that part wrong :P

worn sierra
#

wait i'm dumb

#

i have the tanenbaum bible

#

maybe they can explain it

#

oh nahhh i forgor it's the german version

light cosmos
# worn sierra because unlink takes in a dentry

unlink takes in an inode and the name of a file within that directory. dentry is just a nice way to package that name of the file. the filesystem driver doesn't really have to care all that much about VFS shenanigans, apart from knowing that the dentry has a name, and it is that name which should be unlinked from the directory.

worn sierra
#

right

light cosmos
#

iirc: the thing that d_invalidate does is it removes the dentry from the hash table so it cannot be found in a lookup (it only does this if there are any other live references to the dentry). this mitigates certain types of TOCTOU where a task opens a path (e.g. O_PATH), checks something, and the inode under that dentry is unlinked and replaced with a new inode (because the new inode will be installed in another dentry instead).

worn sierra
#

oh and fyi @chilly pond

#

your mount() prototype makes no sense :3

#

remind me again when you have a block fs working ๐Ÿ˜”

chilly pond
worn sierra
#

where does it get the source from

chilly pond
#

from vfs::mount()

#

??

worn sierra
#

then im misunderstanding your struct names

chilly pond
#

mount is both a function and a struct

#

confusingly named, yes

worn sierra
#

i get that part

#

but fs::mount doesn't take a source parameter

#

does the fs just not care about it?

chilly pond
worn sierra
#

where

chilly pond
#

here

#

I changed the path to shared_ptr<dentry> locally

worn sierra
#

I'm so confused again

chilly pond
worn sierra
#

linux' mount needs a device path, a mount path, an fs name and flags

worn sierra
#

mfw

chilly pond
#

appropriate reaction

light cosmos
#

a filesystem driver really only needs the device path and flags

worn sierra
#

meme maybe calling everything the same isn't the best idea

chilly pond
worn sierra
#

bad mentality smh

chilly pond
chilly pond
#

after more than a month of not working, I added kallsyms for symbol lookup

#

hopefully I'll continue doing stuff

grand gulch
#

Time to make an async lockless logger

chilly pond
#

lol

#

I have encountered a little issue

#

modules need mangled names for symbol resolution

#

I have demangled names for kallsyms

#

smh

grand gulch
#

Lol

chilly pond
#

if only I could demangle without allocation

fiery grotto
#

| c++filt

broken beacon
#

I thought you could

chilly pond
chilly pond
broken beacon
#

It appears to be possible non-alloc at a glance to me

fiery grotto
chilly pond
grand gulch
fiery grotto
#

yeah so?

#

make stack trace printing output mangled names

chilly pond
fiery grotto
#

and then use c++filt on the host to demange the serial output

#

that's true

broken beacon
fiery grotto
#

it's hard to demange anything without allocating but i might write a demangler that can output using a callback

#

or do std::format<MangledSymbol> :^)

broken beacon
fiery grotto
#

eh not that hard

#

actually nvm it might be complicated

broken beacon
#

IMO the best option is still to do | c++filt

#

You can do that if you're using some command-line serial monitor just fine.

chilly pond
#

hmm I'll do that

#

I might try to modify llvm's demangler to use a callback, if it's possible

grand gulch
chilly pond
#

I found one that was 2390 characters long in debug mode (demangled)

light cosmos
#

the stuff that happens when you overuse templates and namespaces.

chilly pond
#

there's no such thing as overusing templates trl

#

it was a libstdc++ thing anyway

#

smart pointers and construct()

#

I still left in the runtime demangler, so if I ever need it, I can just uncomment one line

fiery grotto
#

mmm allocation during panic

#

my favorite

chilly pond
#

I love C++ (not an actual line from source)

lib::locked_ptr<filesystem::instance, lib::mutex> instance = lib::make_locked<tmpfs::fs::instance, lib::mutex>();
#

then I can do instance.lock()->stuff

#

or if it's a rwlock instance.read_lock() or instance.write_lock()

#

basically rust mutex + arc

limpid jasper
#

this seems like a prime candidate for auto

chilly pond
grand gulch
light cosmos
#

I'm guessing that this is not so much a "smart" pointer as it is a wrapper type coupling the pointer with a hold on the Mutex.

#

or nevermind

#

I misread.

worn sierra
#

stupid pointer

light cosmos
polar lance
golden kiln
#

wow

#

ilobilix thread is alive

chilly pond
#

and base class can be abstract

grand gulch
chilly pond
#

it's shared, not unique

grand gulch
#

oh

chilly pond
#

I need to be allocating base and derived classes, not some storage type containing them, otherwise ub will smite me

#

if that makes sense

grand gulch
#

placement new?

chilly pond
#

sure, but I'm stuck on coming up with ideas

#

tbh placement new solves a different problem

chilly pond
#

"think" because it works but I feel like something is not right

#

@light cosmos could you take a look, please?

#

especially class storage part

light cosmos
#

but yeah sure, I'm having a look

chilly pond
#

on lines where I use alignof I would prefer to have used offsetof if I could make it work with non-pod types

light cosmos
#

Is the storage::storage(make_locked_tag_t, Args &&...); constructor exception-safe?

chilly pond
#

I have exceptions turned off

#

so I mostly don't bother with noexcept in kernel code

light cosmos
#

The requires(std::is_base_of_v(...)) storage(...) etc. "casting" constructors are definitely worth making sure that they are correct.

chilly pond
#

yes, most of my doubts are with those 2 constructors

light cosmos
#

Your class locker stores objects and locks adjacent to each other --- which is fine, except when you cast from/to something which is not at offset zero from the parent class

#

This can happen with multi inheritance

chilly pond
#

sorry I don't quite understand what you mean

light cosmos
#

If you have this:

struct Foo { void *foo; };
struct Bar { void *bar; }
struct Baz : Foo, Bar { /* ... */ };
#

one of Foo, Bar is stored at an offset from Baz (i.e. (Bar *) baz == (Bar *) ((uintptr_t) baz + 8) or something)

chilly pond
#

sure

light cosmos
#

currently, with the way your 'buffer' works, this breaks

#

this is one of the reasons why std::shared_ptr has separate CB and object pointers.

#

so that the object pointer can point "into" the object

chilly pond
#

ah I do

light cosmos
#

but you don't account for that when moving/copying the pointer

#

If you want correctness, I would advise you to move the Lock into your own "control block" of sorts, using the same approach as shared_ptr does.

#

This might require writing your own shared_ptr because I don't think there's a way to expand the control block with your own stuff.

chilly pond
#

isn't that part of the control block? (I checked: yes)

light cosmos
#

possibly

#

but can you get a hold of the deleter for when you need to... take the lock?

chilly pond
#

I don't understand how I would solve the probem with a control block though

#

do I store the offset in it?

#

how would I get that

light cosmos
#

no, so the way shared_ptr works is you have basically this:

class shared_ptr {
        control_block *cb;
        T *ptr;
};
#

in the typical scenario, (uintptr_t) ptr == (uintptr_t) (cb + 1) (i.e. they are allocated next to each other)

#

if you cast a shared_ptr, cb stays the same but ptr may change

light cosmos
light cosmos
chilly pond
#

but I still need the lock to be in the control block, to fix those two horrendous constructors

light cosmos
#

although I expect things to break if you cast it via a void * or uintptr_t

chilly pond
#

I use the correct types there

light cosmos
#

e.g. static_cast<Bar *>(static_cast<void *>(baz));.

light cosmos
chilly pond
#

ah

#

I don't do that

light cosmos
#

yeah

#

your code is probably correct

light cosmos
#

It breaks because you first cast to void * -- no offset applied, then you cast from void * and you have effectively forgotten to apply the offset.

chilly pond
#

it's not possible to do it with a single allocation only while using a custom deleter

light cosmos
#

What will you be doing instead?

#

IMO using what you've written here and disallowing multi-inheritance (since it is a very uncommon thing anyways) is a valid approach.

chilly pond
#

I believe using allocate_shared with a custom allocator will do the trick

#
{
    struct abcd
    {
        int a;
        abcd(int b) : a { b } { log::println("constructor"); }
        ~abcd() { log::println("destructor"); }
    };
    auto obj = lib::make_locked<abcd, lib::spinlock>(5);
    log::println("value: {}", obj.lock().value().a);
    log::println("value: {}", obj.lock().value().a = 23);
    log::println("value: {}", obj.lock().value().a);
}

output:

allocating
constructor
value: 5
value: 23
value: 23
deallocating
destructor
#

@light cosmos

broken beacon
#

This is some advanced lifetime extension bullshit

chilly pond
#

I'll test it with multiple inheritence as well, but should work fine

broken beacon
#

All this effort just for a mutex?

#

I will admit it's pretty cool to see work though

light cosmos
light cosmos
chilly pond
#

indeed, but this is single allocation

chilly pond
# light cosmos yeah this is the nasty case
{
    struct base1 { int a; };
    struct base2 { int b; };
    struct der : base1, base2 { int c; };
    auto derived = lib::make_locked<der, lib::spinlock>();
    {
        auto locked = derived.lock();
        locked->a = 1;
        locked->b = 2;
        locked->c = 3;
    }
    log::println("derived->a = {}", derived.lock()->a);
    log::println("derived->b = {}", derived.lock()->b);
    log::println("derived->c = {}", derived.lock()->c);
    {
        lib::locked_ptr<base1, lib::spinlock> base1_ptr { derived };
        log::println("\nbase1_ptr->a = {}", base1_ptr.lock()->a);
        base1_ptr.lock()->a = 4;
    }
    {
        lib::locked_ptr<base2, lib::spinlock> base2_ptr { derived };
        log::println("base2_ptr->b = {}\n", base2_ptr.lock()->b);
        base2_ptr.lock()->b = 5;
    }
    log::println("derived->a = {}", derived.lock()->a);
    log::println("derived->b = {}", derived.lock()->b);
    log::println("derived->c = {}", derived.lock()->c);
}

I believe this should cover it, right?

light cosmos
#

with the old gist implementation this would probably give not the results you expect (it's fun to try it actually)

chilly pond
# light cosmos yeah probably
derived->a = 1
derived->b = 2
derived->c = 3

base1_ptr->a = 1
base2_ptr->b = 2

derived->a = 4
derived->b = 5
derived->c = 3
#

works just fine

light cosmos
chilly pond
#

nope, with the new one

light cosmos
#

niiice

#

can you try it with the old one, for fun?

chilly pond
#

sure

#

I hope it doesn't work lol

chilly pond
#

fun indeed

light cosmos
#

well, future pain avoided.

chilly pond
#

I still think it can be improved

#

the size of the locked_ptr is 32 bytes compared to 16 for the old one

light cosmos
#

because the lock pointer has two shared_ptrs now?

chilly pond
#

it has one shared ptr and two pointers pointing to the data inside that shared_ptr

#

shared_ptr is 16 bytes

light cosmos
#

yeah... if you want to cut it down to two pointers, you can implement shared ptr semantics yourself

light cosmos
chilly pond
#

multiple inheritance strikes one again
the object that it's currently accessing isn't necessarily at the address of the data that shared_ptr holds

light cosmos
#

yeah but shared_ptr can deal with that

chilly pond
#

hmmm

#

the shared_ptr stores a struct that contains the obejct class and the lock

light cosmos
#

shared_ptr points to the control block (which you don't use), an object within the allocation (which you would use with this scheme), you have an external raw pointer to a Lock within the same allocation. this is one possible solution.

#

AKA:

struct lockable_shared_ptr {
        shared_ptr<T *> object;
        Lock *lock;

        T *get_pointer()
        {
                return object.get();
        }

        Lock *get_lock()
        {
                return lock;
        }
};
chilly pond
#

I reduced it to 24 bytes by just putting the lock at the start of the held data, instead of storing a pointer to it without knowing it's location

#
error: cannot yet mangle expression type OffsetOfExpr
chilly pond
#

incredible app

light cosmos
#

yeah we all left

#

you are alone here

chilly pond
chilly pond
#

should I switch to cmake

#

it also supports modules

sonic copper
golden kiln
tame jolt
chilly pond
#

xmake

tame jolt
#

oh, never heard of it

worn sierra
#

anything but xmake'

#

why do you need modules

chilly pond
#

because they're nice

#

would you use headers if you had the option to use modules?

#

also cmake has modules now

worn sierra
chilly pond
#

include is just text paste

remote valve
#

Use imake

chilly pond
#

what is that?

#

apple make?

worn sierra
#

i thought xmake was xcode make

chilly pond
worn sierra
#

this seems like headers with extra steps

#

or rather, what rust does

#

this is why i hate c++

chilly pond
#

what

remote valve
worn sierra
#

there's a trillion ways to do the same thing, but with worse syntax

chilly pond
#

it's a new feature bru

remote valve
#

Only time I saw it was when porting xfishtank for astral

#

And the fact that I chose to just manually compile the c files says a lot about imake cross compiling

chilly pond
#

the thing is that I have never written anything in cmake

#

so I'd have to learn it first

past sky
chilly pond
#

nah uh

#

modules speed up compile times as well

#

you don't have to recompile code from included headers for every source file

#

I can just do import std and I have everything i need

chilly pond
#

I started working on a very very simple vmm

#

and I updated the scheduler a bit

#

it should be a bit less bad (it allocated in the scheduler before), but I'm no expert

chilly pond
#

hmmm if the current thread vruntime is the lowest in all threads, should I still switch to a new thread or continue executing the current one until it's vruntime gets high enough?

#

currently I still switch, regardless of the vruntime of the thread that was just running

#

my reasoning is that if the current thread was sleeping for a long time and has just woken up, it would block every other thread from running for a while.

#

switching anyway gives other threads some chance to run as well

#

does this make sense?

light cosmos
#

I'm pretty sure CFS handled this by clamping the vruntime of newly woken tasks to the minimum and maximum vruntime in a queue, plus minus some window of allowance, not sure what they do nowadays though.

chilly pond
#

hmm makes sense

chilly pond
chilly pond
golden kiln
chilly pond
#

wdym

golden kiln
chilly pond
chilly pond
#

added scheduler priorities

#

basically the same as nice values -20 to 19 from linux

chilly pond
#

oh lol

golden kiln
light cosmos
chilly pond
#

is bug_if_not a bad name for assert?

#

because my previous name (ensure) doesn't really explain what the check is for

golden kiln
light cosmos
chilly pond
#

maybe I'll change it

chilly pond
#

okay I renamed it

golden kiln
chilly pond
#

ensure has a slightly different definition compared to assert or bug_on(!

light cosmos
#

BUG_UNLESS(condition)

grand gulch
light cosmos
#

probably not

#

I just made it up

#

if it exists, that's a coincidence.

grand gulch
#

I've seen DIE_UNLESS I think

chilly pond
#

I'll continue working on this joke of a kernel tomorrow

#

hopefully

remote valve
#

@chilly pond do you use slabs and if so how did you get slabs to go 8 mil on uacpi

chilly pond
#

I switched to frigg's slab allocator as it was faster than mine

remote valve
#

Did you do anything differently from the slab paper

#

Oh

#

Booooorinf

chilly pond
#

I don't know how I got 8 million
keep in mind that it was on 9950x3d

remote valve
#

I wrote slabs down to the paper and I still dont really get good scores, maybe I am doing something wrong elsewhere

chilly pond
#

have you profiled the uacpi kernel api functions?

#

maybe spinlocks or mutexes are slow

remote valve
#

Like a long time ago, my kernel and uacpi changed a lot since then so maybe I should do that again

remote valve
#

Fast case

chilly pond
#

hmmm

#

you can also optimise your memcpy for certain sized copies like managarm does

#

phd memcpy

#

and O3

remote valve
#

Hmmm

chilly pond
remote valve
#

Like 4 mil

chilly pond
#

I get 4 mil on my cpu

remote valve
#

On my cpu I get like 1.5 mil ๐Ÿ’€

#

But I think I know what might be up, it might be my uacpi_kernel_map

#

I could probably make that faster and it, alongside unmap, are called a ton I think

#

I need to benchmark to be sure

remote valve
chilly pond
#

it has been a productive day

grand gulch
#

we BACK LETSFUCKINGGOOOOOO

chilly pond
#

pfndb done

#

now I need to modify my buddy allocator so I can actually coalesce buddies

chilly pond
#

1 mib used for mapping pfndb for every 4 gigs of ram with 16 byte struct page seems correct

#

does it?

broken beacon
#

Yeah, Linux has way more overhead

#

So 16 bytes per page is relatively small

remote valve
#

yeah like thats like two pointers

chilly pond
#

hmm I can fit a physical page address in 36 bits can't I

past sky
chilly pond
past sky
#

Chat gpt is good for bullshit like this lol

chilly pond
#

(it wont meme)

chilly pond
#

well

#

unexpected but it appears to be working on the first try

#

good enough :P

#

41 bits used in the struct page

#

I haven't thought of a way of doing it with fewer bits

chilly pond
#

weird

#

xapic sipi seems to work on bare metal

#

but not in qemu

chilly pond
#

it's a bit more than 1 second

#

I want it to be accurate

worn sierra
chilly pond
#

not that much

#

the delay was lower when I was waking them up from the scheduler itself, not from a separate thread

light cosmos
chilly pond
#

6 ms so 1000/6

light cosmos
#

ideally you should be within one tick of it, e.g. if you drive the lAPIC at 1000HZ and you wait for 1000ms, you should be no later than 1001ms when load is low

light cosmos
chilly pond
#

nice

#

I should finish the vmm next and maybe set up the userspace buiild system

chilly pond
#

this is not completely abandoned

#

I added hard and soft links

#

:P

#

and set up jinx and minimal userspace

#

vmm worksโ„ข (it can map)

tame jolt
chilly pond
#

my rating: ๐Ÿคฎ/10

#

it's "inspired" by introduction to algorithms but I ruined it

golden kiln
chilly pond
#

red-black tree

#

a type of binary tree

golden kiln
#

where do you use it

chilly pond
#

thread queue for the scheduler

#

threads are sorted by their virtual runtime

chilly pond
#

how else would I use a hook intrusively

remote valve
#

Idk I dont speak c++ lmao I was just joking cuz of that

#

I still need to implement a red black for astral and to switch a few things over to it

chilly pond
#

finally doing something ๐Ÿ”ฅ ๐Ÿ”ฅ ๐Ÿ”ฅ

grand gulch
#

Nice to see

chilly pond
chilly pond
#

hmmm weird

#

I wonder what I'm doing wrong

#

welp that's for tomorrow me

fiery grotto
#

or it's garbage to begin with

chilly pond
fiery grotto
#

then you're loading in the mlibc ldso incorrectly

#

the backing memory is garbage

chilly pond
#

I do memset it

#

anyway I haven't started debugging yet

chilly pond
fiery grotto
#

hell yeah

#

nice to hear that it works now

golden kiln
#

is ilobilix alive now

chilly pond
#

doin stuff

remote valve
#

Having creat() as a separate syscall than open is an interesting choice

limpid jasper
#

linux has a separate syscall for creat as well

remote valve
#

Huh

#

Interesting

#

Why did they do that?

limpid jasper
#

backwards compatibility i'd guess

chilly pond
#

I'm doing linux syscalls

grand gulch
chilly pond
#

yep

grand gulch
#

Good choice

#

Why did you decide to go for Linux compat?

chilly pond
#

tbh it's easier to follow a design that's already made, instead of coming up with a new one

grand gulch
#

Fair

chilly pond
#

I'll do process groups, sessions and tty next

#

I do have midterms this week so we'll see

golden kiln
golden kiln
#

musl or mlibc

chilly pond
chilly pond
#

I just need to implement a few more syscalls

#

I'll push when I get home

golden kiln
chilly pond
#

maybe but I don't have a tty yet :P

#

I get div by zero somewhere in mlibc

#

I need to fix that as well

golden kiln
#

btw

chilly pond
#

in arch_prctl

chilly pond
#

what is this shite

#

where did that \x1d come from

chilly pond
#

18553 loc and doesn't even run bash KEKW

grand gulch
chilly pond
#

lol

tame jolt
chilly pond
#

stuff

remote valve
#

Astral has like 30k sloc

tame jolt
#

my kernel has 10k loc

grand gulch
remote valve
grand gulch
#

Also no kde I guess trl

tame jolt
chilly pond
grand gulch
#

Astral needs a drm impl ngl

tame jolt
#

i'd love to see that someday

remote valve
grand gulch
grand gulch
chilly pond
remote valve
#

Idk how drm works at all

tame jolt
grand gulch
#

Some ioctls just do modesets, some allocate buffers, some submit userspace command buffers to the GPU

#

Thats kinda it

remote valve
#

That doesnt sound horrible

#

Especially with something like virtio gou

#

Gpu

grand gulch
#

You dont even need the command submission part technically, a lot of stuff works with dumb framebuffers

#

So just the modeset api

#

Like managarm

remote valve
#

Minecraft in astral with virtio gpu hardware accel 2026

chilly pond
grand gulch
tame jolt
#

yk, the 4kb version

remote valve
#

Fullscreen on a 1024xsomething it ran at like 10-20 fps I think

tame jolt
#

oh you tried it already?

remote valve
#

Well not 4k

#

Oh wait

#

I read 4k as resolution

#

I could tey that

tame jolt
blissful sand
chilly pond
#

I made a clanker make mermaid diagrams for my 2 initgraphs

#

one running before the scheduler and the other on a kernel thread

chilly pond
#

it's supposed to be a file instead of \x1d

#

is my ld.so loading wrong?

chilly pond
#

I believe I accidentally fixed it

#

I don't know what the issue was

chilly pond
#

hours debugging an issue with locks only to realise that I shouldn't have used a lock there

chilly pond
#

I'm trying to switch to cmake from xmake

timber terrace
chilly pond
#

huh?

#

they're different build systems

timber terrace
#

is it simpler to use?

chilly pond
#

definitely not

#

but xmake has been really unstable with modules lately

timber terrace
#

ah, to cmake

chilly pond
#

and it's considerably slower

timber terrace
#

i read it wrong XD

#

i read it as cmake to xmake

golden kiln
rugged cipher
timber terrace
polar lance
#

Ilobilix running Minecraft when

chilly pond
#

probably never

polar lance
worn sierra
#

reject c++ modules cringe

#

embrace real rust modules

chilly pond
#

begone rust user
go back to the crate from whence you came

broken beacon
#

Get oxidized

remote valve
#

Is it like imake thats something very used in olden unix

chilly pond
#

I don't know imake

chilly pond
#

boots

#

wtf ubsan

golden kiln
chilly pond
#

it's kallsyms

#

not the kernel

golden kiln
#

i mean exit_group

chilly pond
#

I don't want to leave it unimplemented

#

or it'll stay that way trl

golden kiln
#

just return enosys

chilly pond
#

real

chilly pond
#

anyway exit_group can't really be enosys

#

it exits

fiery grotto
chilly pond
#

I have it

fiery grotto
#

wtf

chilly pond
#

it's quite unnecessary

#

I could remove it

fiery grotto
#

is that a __user pointer i see?

chilly pond
#

yea

fiery grotto
#

damn

chilly pond
#

__attribute__((address_space(1)))

fiery grotto
#

interesting

#

does it have an actual purpose?

#

or is it just for funsies

chilly pond
#

and I do that in copy_from/to_user

fiery grotto
#

oh that's fun

remote valve
chilly pond
fiery grotto
mossy tendon
chilly pond
#
constexpr comptime_string panic_message { "an unfortunate occurrence, which was definitively supposed to have been avoided or precluded, has regrettably come to fruition in the present temporal reality." };
fiery grotto
#

lmao

worn sierra
#

well not exactly

#

it's a clang extension

#

which does the same thing as in sparse

mossy tendon
#

i didnt even notice its there

worn sierra
#

it's not terribly useful in c++

#

since you can just UserPtr<foo>

mossy tendon
#

yea

chilly pond
#

hmmmm

#

what if I use thread_local for cpu local stuff

#

instead of whatever the hell I have currently

#

or both

grand gulch
#

cc @limpid seal KEKW

chilly pond
#

it seems surprisingly easy

chilly pond
#

because I don't think there is such thing as swapfs meme

chilly pond
limpid seal
#

The problem with it is that compilers assume that gsbase never changes

#

So if the code ever gets scheduled on another core, even if you have a compiler barrier, it might still use the value it got before

limpid seal
#

Sorry I meant fsbase

#

But same idea

limpid seal
#

Not that I could find sadly

#

I couldn't find any barrier that does that

light cosmos
chilly pond
#

yes I currently have that

#

I think I worded the original sentence wrong

#

"then I'll use gsbase just for thread struct to access is from a syscall handler after swapgs"

chilly pond
light cosmos
chilly pond
#

then I'll just not move kthreads :P

light cosmos
#

which is why it's okay to use thread_local for thread-local data but not CPU-local data

limpid seal
#

imagine hat after inline and optimizations you have a function like so, and that the barrier is basically a schedule of the code into another core

#

even if you had correctly disabled preemption around each of the accesses, the compiler would still cache the base

#

if you can ensure that the same code path will never run on a different core, then you can use it

#

but otherwise you risk running into really really weird bugs

grand gulch
#

linux does have cpu_read_stable() as well which mimics this behavior

#

but its only used for get_current() on x86

#

(and a few other misc helpers)

#

it uses inline asm for it

#

and by default its always just __seg_gs deref

chilly pond
#

I don't think this is worth it

chilly pond
#

I moved it to an org

#

and split the userspace and kernel to separate repos

golden kiln
chilly pond
#

well

#

I don't think it builds anymore

#

I haven't maintained it

#

my arch abstraction is so shit

#

nothing is designed properly

chilly pond
#

there's currently no way to run the os or build the modules

chilly pond
#

I just hooked up a basic console (just write) (because I don't have a tty) to see if it even worked

#

it does

fiery grotto
#

how can a module be noarch

chilly pond
#

it's for modules that are not for a specific architecture

fiery grotto
#

oh that's odd

#

i would have never thought about that lol

chilly pond
# chilly pond

I don't get why setting process group is failing with EBADF

#

setpgid is succeeding

remote valve
chilly pond
#

oh yeah probably

#

I did dev console

chilly pond
#

the ever-dreaded todo list grows larger every passing moment

chilly pond
remote valve
#

๐Ÿ’€

#

bro gotta pselect6 ๐Ÿฅ€

chilly pond
#

๐Ÿฅ€ ๐Ÿฅ€ ๐Ÿฅ€

remote valve
#

step 1) implement ppoll
step 2) have pselect use ppoll

tame jolt
#

My pselect is a mlibc wrapper ๐Ÿ˜ญ

#

I don't even implement a wrapper in the kernel

#

Oh but this is doing Linux compat right

worn sierra
#

is this such a bad idea

remote valve
#

Nah

polar lance
grand gulch
polar lance
#

good idea

chilly pond
#

I don't have the energy to actually implement this rn

golden kiln
#

just implement poll

#

and convert select stuff to poll stuff

chilly pond
#

I'm not implementing it yet

#

I just stubbed it

chilly pond
#

hmmm I tried running musl and I'm getting a page fault before any syscall is called

#

probably a problem with elf loading

#

yep

#

I was loading interpreter at a wrong address

chilly pond
#

I'm thinking if I should use buildroot and musl instead

#

it's shrimply so much easier

remote valve
#

coward

#

do mlibc

#

join us

#

or well

#

do glibc if youre doing full linux compat

chilly pond
remote valve
#

but thats boooring

#

and doesnt help the community etc

chilly pond
#

I'll try glibc

#

I haven't decided what I'll use yet

remote valve
#

using musl while doing linux compat is an interesting choice :P

chilly pond
#

@polar lance does it

remote valve
#

you can pick between using a complete libc or helping the community and by choosing musl you do neither

chilly pond
#

I think

#

fair enough

grand gulch
chilly pond
#

lol

polar lance
chilly pond
#

I think glibc might need futex

fiery grotto
#

LMAO

#

quality code

golden kiln
#

they can be required only for pthreads

chilly pond
#

glibc just keeps spamming it

chilly pond
#

me when the

grand gulch
#

its optional

chilly pond
#

yeah I figured

#

it's just not in any syscall table or manpage I've searched in :P

grand gulch
#

we've talked about it quite a lot on the maestro's page i think

#

or thread ig

#

its not that bad to implement

chilly pond
mossy tendon
mossy tendon
#

it doesnt show the arguments in the table though it has links to both the manpage and the linux source

chilly pond
#

not a problem

mossy tendon
#

wait i might be stupid

#

Double click on a row to reveal the arguments list. Search using the fuzzy filter box.

#

lol

chilly pond
mossy tendon
#

yea

grand gulch
polar lance
chilly pond
#

I think I have tty basics all implemented

#

I just need to do line discipline and hook up some way to input characters

#

probably from serial

#

having coreutils installed makes bash invoke pipe2

#

I've got to implement that too

#

then clone, futex, ppoll, pselect

golden kiln
chilly pond
#

well the syscall is required

#

I could implement one on top of the another I think

chilly pond
#

insanity

blissful sand
#

that looks like it'll be fun to debug ๐Ÿ˜…

worn sierra
chilly pond
#

wdym why

worn sierra
#

what's this doing

chilly pond
#

different kinds of ringbuffers

#

single/multi producer/consumer

#

for example some things don't need to be atomic depending on the type

#

so it's better optimised like this

broken beacon
#

This is overoptimized tbh

#

Have you profiled and ran into ringbuffers being an issue? I bet not.

chilly pond
#

I haven't even utilised those ringbuffers yet

grand gulch
remote valve
#

20k loc for a hello world trl

grand gulch
#

rookie numbers

chilly pond
#

gotta do sys clone

#

and I still haven't written that tty line discipline thingy

#

and I need to write a proper vmm

#

the one I have currently sucks

#

probably doesn't even work properly

tame jolt
chilly pond
#

to have it?

#

I hear forking is quite useful :^)

tame jolt
#

well, you could just implement fork

chilly pond
#

why when I also need clone

#

and I can implement fork with clone

tame jolt
#

true

golden kiln
chilly pond
#
init: error while loading shared libraries: /lib64/librc.so.1: unsupported version 0 of Verneed record
#

hmmmmmmmmmmmmmmmmmmmmmmmmmm

chilly pond
#

what could cause this?

remote valve
#

Inb4 broken seek

#

Or read

#

Or mmap

chilly pond
#

probably all of them

#

iirc it did a few mmap s before that error

chilly pond
#

I was overwriting the modules memmap

#

(where initramfs was loaded)

#

well I haven't tried running openrc yet

#

I just fixed that

#

yeah still doesn't work

chilly pond
#

I just updated flanterm to the latest commit

#

do I need to add \r or something now

rugged cipher
chilly pond
#

smh

#

why

rugged cipher
#

I just edited my printf/putc to detect \n shove a \r before flanterm

rugged cipher
#

Crap canโ€™t find it wahhgone

#

Canโ€™t even find the commit

limpid jasper
chilly pond
#

I started working on tty line discipline

#

with some "inspiration" from toaruos

#

I just need to do read and write and it should be done

#

oh and ioctl

#

then maybe I'll write a quick ttyS driver

#

can't forget ptys

#

maybe glibc bash after that doubt

#

that needs futexes iirc

remote valve
chilly pond
#

this is the function that's based on it

#

anyway I read the docs so it's ok trl

rugged cipher
blissful sand
chilly pond
#

time to get back to working on tty

#

I had to change a few things before doing read and write

chilly pond
#

okay read and write done

chilly pond
#

// TODO count is 73 and rising

broken beacon
#

TODO count never decreases in any good project trl

chilly pond
#

lol

chilly pond
#

/dev/ttyS0

#

I'm pretty happy with how this turned out

#

whole thing is like 1.3k lines (without any ioctls implemented)

#

excluding any tty drivers like serial or pty

grand gulch
#

Nice

chilly pond
#

glibc found more bugs in my "temporary" buggy vmm

#

but bash works now

grand gulch
#

Damn

golden kiln
chilly pond
#

one of the issues was with that, yes

golden kiln
grand gulch
golden kiln
# grand gulch How ๐Ÿ’€

my vmm was stucking when there's hint on already allocated memory and my unmap just frees all memory which was allocated for this mmap, not part of this

chilly pond
#

getdents works (no fork/clone or exec yet so I just pressed tab)

#

pselect6 as well

#

but I don't really like the implementation

chilly pond
#

I love it when stuff just works

broken beacon
#

Bash port?

chilly pond
#

yes

#

with glibc

#

nothing impressive but I'm just happy

grand gulch
#

Linux compat?

chilly pond
#

yes

grand gulch
#

big

chilly pond
#

hmmm the terminal is incredibly slow when printing from a scheduler thread

#

I don't know why

chilly pond
#

maybe not

#

maybe it's just my scheduler being shit

rugged cipher
#

Do you have a lock on it or somthing?

chilly pond
#

what

rugged cipher
#

Like a spinlock on the terminal?

#

Atleast for flanterm it is not thread safe so Iโ€™m pretty sure you need a lock there

chilly pond
#

initramfs parsing is slow as well, I doubt it's the terminal

rugged cipher
#

Ahhh sorry

chilly pond
#

bruh it booted up fine one (1) time

#

then it went back to being slow

#

damn it was because of smp

#

well, is

chilly pond
chilly pond
#

okay I think I found the real issue:

#

it only happens when I use tsc deadline for lapic timer

chilly pond
#

I fixed some bugs

#

now the scheduler doesn't tick on idle cpus