#pmOS - microkernel OS for RISC-V, x86, and LoongArch

1 messages · Page 11 of 1

plain jungle
#

for disk + fs

carmine nacelle
#

The IPC is very simple

#

Their discovery is not (at least to me)

#

What do I do once I remount root, discover new drivers, and have to probe filesystems with new drivers, etc.

#

Like what I'm stuck on is how do I probe for partuuid/label for my root partition

#

(since I'm using MBR since limine doesn't support GPT+BIOS)

#

Though I think I can do it the other way around, and probe all partitions with the filesystems that are in my fstab/whatever

#

Not query all filesystems to probe all partitions, and then do with that

#

Maybe I'm overthinking it

left dew
carmine nacelle
#

I think I'll know what I'll do

#
  1. I'll publish all bootstrapd services on pmbus (trl)
  2. Those services will have capabilities, as strings (e.g. filesystem: [ext2, ext3, ext4], filesystem_actions: "probe", "mount")
  3. Each partition will store a set of filesystems that have probed it, and also, on success, the service and the data associated with it, as probing information
  4. The blockd (the point 3 is also inside of blockd) will wait for new filesystems on pmbus
  5. That will also somehow work with /etc/fstab or whatever (I need to think about how I want to do it)
  6. I need to decide who launches the servers, tbh I think I'll just IPC my init server for that
carmine nacelle
#

I think I've kinda implemented 1

#

I'm feeling like I'm going insane

#

This feels overengineered

carmine nacelle
carmine nacelle
#

thonk Do I give up and use Boost for my C++ stuff?

plain jungle
#

how is boost useful for the problems that you're facing?

carmine nacelle
#

It has a UUID class

plain jungle
#

a uuid is just a char[16] with some bits fixed

carmine nacelle
#

I know

carmine nacelle
#

Cool, my broken Rust code broke C++...

carmine nacelle
#

Libraries

modest thistle
#

oh

#

have a link?

carmine nacelle
modest thistle
#

thx

carmine nacelle
#

I don't know if they work in freestanding environment though

modest thistle
#

i'll be using them in my services anyway

twilit talon
#

its probably the most bloated library in existance

#

written by language lawyers

#

i wouldnt touch it with a 10 foot pole

modest thistle
carmine nacelle
#

I guess I'll just use std::vector trl

modest thistle
#

XD

carmine nacelle
#

Does mlibc use it?

modest thistle
#

it is a dependency

carmine nacelle
#

Because I've been thinking about it recently, you wouldn't be using stl in there, for example

#

Cool

#

I think I'll port mlibc after I finish the ext4 thing, and add futex, and fix my IPC (which includes using rights for interrupts, fixing timers, getting rid of send_message_port and adding bounds so Rust doesn't deadlock)

#

So it sounds like never ultrameme

carmine nacelle
twilit talon
#

what libc are u using now

carmine nacelle
#

my own

#

but it's kinda bad and incomplete

#

And libm is stolen from musl I think

#

Idr

carmine nacelle
#

What if I change my C++ async stuff into the same thing as what Rust does now? thonk (I think I kinda grew to like it)

#

(sorry for ping, I meant to disable it)

#

How did I not know about std::as_bytes???

carmine nacelle
#

This is fun

carmine nacelle
#

Cool, my C code is elaborately trolling me

carmine nacelle
#

Oh my god, why do I dislike writing C so much

plain jungle
#

why are you doing it if you dislike it?

carmine nacelle
#

It's a bootstrapd server, which was like the first thing that I wrote, and it's too large to rewrite in C++, and besides, C is kinda fitting there

#

Since I'm using a limited set of libc

twilit talon
#

imagine disliking the best language

hexed knot
carmine nacelle
#

Idk, I like to think that I'm good with it, but I just get fatigue from thinking about manual memory management and writing all of the boilerplate

#

I mean the fact that my lsp is broken is also not helping

twilit talon
#

bro is a js programmer at heart

carmine nacelle
#

I don't know js 💀

#

I like Go

carmine nacelle
#

I mean Rust feels weird, it feels bad writing it, but good after you've done it

carmine nacelle
#

Bruh, I've asked chatgpt to write me args parser, because I can't be bothered with it, and it wrote code with a bunch of double frees...

#

why do I even bother using ai

plain jungle
#

chatgpt is not a proper coding tool

carmine nacelle
#

I know that people use GPT models for coding? It wasn't a complicated problem

plain jungle
#

yes but (1) they don't use the free version which is severly restricted and (2) they don't use the web interface which is not made for coding (and has different tool access/system prompts/etc compared to the actual coding tools)

carmine nacelle
#

My code is really testing me

#

I have heap corruption

carmine nacelle
#

It had managed to change stuff and run it in qemu by itself...

carmine nacelle
carmine nacelle
#

I've enabled footers in dlmalloc, and it's calling abort()

#

This is so anoying

modest thistle
carmine nacelle
#

It's not a syscalls problem

modest thistle
#

i am trying to run a diff program than my hello world

#

and this

#

after arch ctl

carmine nacelle
#

My bootstrapd dies because of heap corruption

modest thistle
#

XD

carmine nacelle
#

And I've no idea where to look

modest thistle
#

pain

carmine nacelle
#

It's 5k LoC

#

And the issue might be anywhere

modest thistle
#

ask claude, lol

carmine nacelle
#

And when it dies everything kinda dies

carmine nacelle
modest thistle
#

are you in school?

carmine nacelle
#

I've installed Codex but it burned through tokens and didn't find it

carmine nacelle
modest thistle
#

then get github for students

carmine nacelle
#

I have it

modest thistle
#

you get free copilot

#

with a bit less models

#

than pro

#

but same request limit

carmine nacelle
modest thistle
#

lol what

#

that's strange

carmine nacelle
#

Oh, I didn't redeem it

modest thistle
#

XD

carmine nacelle
#

Does it have agentic ai stuff?

modest thistle
#

yes

#

not all the claude models tho

#

they got rid of them from the student plan

#

bc they were too expensive

#

you only get haiku from anthropic

carmine nacelle
#

it doesn't matter I guess

modest thistle
#

the included ones are completely free and unlimited

carmine nacelle
#

gpt 5.4 is good

modest thistle
#

even if it is the mini version

#

it still does its job pretty well

carmine nacelle
modest thistle
#

?

carmine nacelle
#

it's scanning my repo

twilit talon
#

thats how agents work

carmine nacelle
#

codex didn't

twilit talon
#

if you tell it how to run qemu its it can even do that

#

even use gdb etc

modest thistle
#

mine had a lot of problems doing that, lmao

carmine nacelle
#

My ns16550 driver is working overtime

carmine nacelle
twilit talon
#

ah

carmine nacelle
#

like I think it's fully working?

#

and right after I said it, it's having a skill issue

carmine nacelle
#

this is embarassing...

#

or not

carmine nacelle
#

On a separate note, I've been thinking about notifications (about rights, tasks/groups deletion, and interrupts), and I think I have a strategy for implementing them in a way that does not allocate memory on sent messages through them

#

So it can work when the kernel is short on memory (which would be when things start dying and these notifications start to be sent)

#

Since at the moment it's either not implemented or doesn't use rights (sends to ports directly bypassing my capabilities system) and allocates every time

#

I feel like I have to work on kernel allocations in general though

carmine nacelle
#

What if it's single threaded

#

(my code is single threaded, this is a filesystem)

twilit talon
#

rust doesnt buy it

carmine nacelle
#

I'll ask clanker trl

#

Also, crate's skill issue

#

I think the ideal solution would be to implement single_threaded or something

#

@torn arrow

#

Clanker did this

#

lol

#

Wtf is ?Send

torn arrow
carmine nacelle
torn arrow
#

wouldn't just removing the trait bound make it optional?

carmine nacelle
#

I have no idea, I'm new to Rust

torn arrow
#

I think I need a single threaded feature

#

basically what's going on is we have Arc<Inner { reader, writer } > so there is concurrent access

carmine nacelle
torn arrow
#

do you have mutexes? I think Arc<Mutex<T>> would fix it

carmine nacelle
#

Yeah, but the runtime is single threaded

#

But like it would be fine I guess?

torn arrow
#

I think there isn't much contention usually?

toxic torrent
#

!Send is not send

torn arrow
#

oh my bad then

carmine nacelle
#

I do have mutexes, probably

#

I have full std

torn arrow
#

also this is in userspace?

#

oh wait this is a microkernel

toxic torrent
#

mfw

carmine nacelle
torn arrow
carmine nacelle
#

I mean I can make rights Send + Sync

#

Idk how

#

But I think they're thread safe

#

My runtime isn't though

torn arrow
#

sorry I'm a little disoriented rn for some reason

carmine nacelle
#

Don't the futures need to be Send + Sync, above all?

torn arrow
#

is your OS async? you could try enabling the sync feature

carmine nacelle
torn arrow
torn arrow
#

Somehow in my setup I just implement directly onto this:

pub struct BlockBuffer {
    dev: Box<dyn BlockDevice>,
    block_size: usize,
}

impl Ext4Read for BlockBuffer...

impl Ext4Write for BlockBuffer...
#

I suppose the difference is block device does async fn write(&self, block_id: u64, buf: &[u8]) -> Result<()>; so I don't worry about mutability

carmine nacelle
#

What runtime are you using in your kernel?

#

Worker I mean

#

Idk I'm new to rust

torn arrow
#

not my kernel entirely, so I didn't design that, but it's custom

#

also I use a monolithic design

#

I just got off a conversation that really confused me about async which makes this even more confusing somehow

carmine nacelle
torn arrow
#

I wonder if you can just remove the Rc<RefCell<

carmine nacelle
#

I can try making it Arc

#

My rights are not clonable

torn arrow
carmine nacelle
#

(or like I can make them, but it will syscall the kernel all the time, which is bad)

torn arrow
#

is there something that needs to be mutable

carmine nacelle
#

no...

#

wait a second

#

will just rc work then?

torn arrow
#

what is a "right" in this context?

carmine nacelle
#

No, right does need to be mutable, I think

carmine nacelle
#

Yeah, I do &mut self.reader.borrow_mut().disk_right

torn arrow
#

I think the issue is a mutability one more than anything

carmine nacelle
#

The mutability should be fine

#

Like with a single threaded runtime it won't be mutating it from different places at the same time

torn arrow
#

true, there could be panics with the refcell

carmine nacelle
#

no

torn arrow
#

as long as you don't await during a borrow you should be fine no?

carmine nacelle
#

yea

torn arrow
#

yeah ok I'll reduce the requirement then

carmine nacelle
#

I mean you might want to keep Sync + Send for a multithreaded async kernel

carmine nacelle
#

I mean I am planning to make my runtime multithreaded eventually, but it will need a bunch of other things to work

#

So eventually is like in a year

torn arrow
#

I'm cooked if two crate in a dependency tree ever depend on different features sets of ext4plus

carmine nacelle
#

Huh?

torn arrow
#

feature sets are additive, but I'm using them as on off toggles. Essentially cargo sometimes merges feature sets for efficiency. This is bad if someone depends on the multi-threaded feature, then you'll get redundant warnings about stuff

torn arrow
#

I'll push up a fix at somepoint. Turns out async_trait requires you to be Send + Sync by default. I can bypass this, but it's not cooperating with me at the moment

carmine nacelle
torn arrow
#

also rip my ability to ensure no breakage across feature flags

torn arrow
carmine nacelle
#

one sec

#

It's 1 am where I live, so I think I'll just ask a clanker to do it

#

It looks like it has compiled

#

Give me a sec, imma implement the missing stuff

#

"Linux is the only OS" strikes again

#

I think I'll finish it tomorrow, it's doing something, and then explodes in mmap()

#

This is fun

#

I think I'll finish it tomorrow...

torn arrow
#

yeah I think that means it's not a valid ext4 disk

carmine nacelle
#

One is not a valid partition, the second one is my ahci driver issue

#

-4 is e2big

carmine nacelle
#

This looks like my wrapper's skill issue...

torn arrow
#

I'll publish a new ext4plus version tomorrow or the day after that with the fix probably

carmine nacelle
#

thx, this is awesome

carmine nacelle
#

btw, is there a way to get fs type? (ext2/3/4)

#

though maybe it doesn't make sense

toxic torrent
#

look at the magic 🔥

kindred venture
carmine nacelle
#

somehow this C/C++/Rust insanity works...

#

Now I just need to implement VFS chad nooo

carmine nacelle
carmine nacelle
#

Lol, I've ran my code through an AI detector, and it (the detector) is so bad KEKW

#

Though idk this whole no AI thing makes me feel so bad

carmine nacelle
carmine nacelle
#

Am I OOPing too hard?

carmine nacelle
#

also wtf, do I leak task groups????

carmine nacelle
#

nice function

twilit talon
#

If u can call it why cant u just delete ptr instead

carmine nacelle
#

it's a virtual function, and I wanted the other struct to push itself into RCU queue

hexed knot
#

i love ub

hexed knot
carmine nacelle
#

I'm somewhat certain it's not

hexed knot
carmine nacelle
#

I had googled it in the past

hexed knot
#

i can try coming up with an example

hexed knot
# carmine nacelle Why ub?
struct Foo {
    int field;

    int bar(bool p, bool q);
};
int Foo::bar(bool p, bool q) {
    int v = field;
    if (__builtin_expect(p, false)) {
        delete this;
    }
    if (q) {
        v = field;
    }
    return v;
}``` consider a definition like this
#

and assume that it's allowed to delete this in this context

#

furthermore, assume that delete unmaps memory immediately (which it may do)

#

then, when Foo::bar(true, false) is invoked, the program crashes on a field read because llvm decided to llvm more harder

carmine nacelle
#

But I'm not accessing any fields

hexed knot
#

thats not really relevant tho

#

its UB if you access 0, 1, or all of the fields

hexed knot
carmine nacelle
#

But it's not always ub trl

hexed knot
#

which part of "undefined" do i have to explain to you

carmine nacelle
#

delete this is defined

hexed knot
#

idk man

#

even if its defined it generates broken code in clang

#

so its as good as useless

carmine nacelle
#

How else are you supposed to do rcu or shit like that

plain jungle
#

yeah committing suicide is not UB in c++ provided that you never access this again ofc

carmine nacelle
hexed knot
#

if it generates wrong code in clang then its as good as useless anyway

plain jungle
#

does it though

#

that'd be surprising since it's indirectly used in a lot of patterns

hexed knot
#

and in general llvm applies dereferenceable to this

#

hmm is this unsound

#

can i turn it into a rust bug

#

would be epic

plain jungle
#

Hm?

hexed knot
#

oh i think rust doesnt apply the attribute to boxes

#

yeah

plain jungle
#

how is this llvm ir problematic?

hexed knot
#

it has a load from the this after loading from the now-deleted object

#
define dso_local noundef i32 @Foo::bar(bool, bool)(ptr noundef nonnull align 4 dereferenceable(4) %this, i1 noundef %p, i1 noundef %q) local_unnamed_addr {
entry:
  %0 = load i32, ptr %this, align 4, !tbaa !33
  br i1 %p, label %delete.notnull, label %if.end, !prof !37

delete.notnull:
  tail call void @operator delete(void*, unsigned long)(ptr noundef nonnull %this, i64 noundef 4) #2
  %.pre = load i32, ptr %this, align 4 ; yeah thats gonna work great
  br label %if.end

if.end:
  %1 = phi i32 [ %.pre, %delete.notnull ], [ %0, %entry ]
  %spec.select = select i1 %q, i32 %1, i32 %0
  ret i32 %spec.select
}
plain jungle
#

what does tail call do?

hexed knot
#

its a normal call

#

with some weirdness im not sure about

#

you can forget the tail qualifier pretty much

plain jungle
#

Hmm

hexed knot
#

the llvm ir transform is legal

#

dereferenceable(4) allows it

twilit talon
#

Yeah im pretty sure its not ub in c++, so this is a clang bug

plain jungle
#

yeah this may be a clang bug

#

you basically need delete this in one way or the other to implement a shared_ptr

hexed knot
#

do you?

carmine nacelle
#

No

hexed knot
#

no you dont

hexed knot
#

firstly, you can obviously hack around it with e.g. unions

#

secondly, the C++ STL can just cheat harder

#

and they can do whatever with a special promise that its actually okay when they do ub

plain jungle
#

I don't think there is anything in the standard that disallows delete this either

hexed knot
#

the rust stdlib does quite a bibt of this

hexed knot
#

i couldnt even find anything about this

plain jungle
#

yeah there is nothing because the this pointer is just treated as any other pointer

#

i guess in practice this does not break because code will always do delete this last

plain jungle
#

the this pointer must be valid at function entry because the call is considered an access

#

but there's nothing that mentions that it must remain valid throughout the function

hexed knot
#

where is this specified?

#

the standard is really opaque :/

plain jungle
#

well, it doesn't say that this has special semantics in this regard, so it doesn't have any

#

the isocpp faq agrees

hexed knot
#

the faq is not normative

plain jungle
#

yeah that's clear

hexed knot
plain jungle
#

i've obviously not memorized the entire standard meme

hexed knot
#

so like, with a reference, having an invalid reference is UB right?

#

which i think would justify this transform if you wrote the method with deducing this

plain jungle
#

also libc++ literally does delete this in shared_ptr

twilit talon
#

libc++ also abuses inactive union members for SSO meme

hexed knot
#

lmao

hexed knot
#

For implicit object member functions, the type of the implicit object parameter is

(4.1)
“lvalue reference to cv X” for functions declared without a ref-qualifier or with the & ref-qualifier
#

so its passed as a reference to the object

#

idk if that affects anything tho

#

The object designated by such a glvalue can be outside its lifetime (6.7.3 [basic.life]).
seems like yes you can have an invalid ref

#

and i guess llvm is just doing a little ub trolling

#

when would it even be legal for llvm to apply dereferenceable then lmao

plain jungle
#

if clang cannot optimize the case where the "delete this" is last because it'd break its own shared_ptr impl, it's good enough for me

carmine nacelle
# carmine nacelle Am I OOPing too hard?

I've finally implemented no-reply notifications from SendOnce rights with this cursed contraption (I need to do SendMany thing as well, but I need to decide how to track multiple rights without it being too slow)

#

But after I moved some stuff around, this was relatively straightforward to do

#

(I just send the right as if it was a message at the end of its life instead of deleting it immediately)

carmine nacelle
#

Omg, I didn't even think about it, but I can trivially implement blocking send_message_right(), and async unblocking notifications (so I can do clean async send with my Rust/C++ runtimes as well), using the same notifications mechanism

#

You just try non-blocking send, if it fails, you wait for a message that it's sendable again, and try again

#

So you just send_message_right().await everywhere, and it won't even allocate any memory

#

I mean at this point, what's stopping me from making memory allocation async as well trl

#

And then I can just make processes page themselves in in userspace trl

carmine nacelle
#

thonk I think I need to do something about the locks situation in my kernel...

#

Fuck, I've just noticed a use after free in there trl

#

actually, no

plain jungle
#

wtf

#

Is that 5 nested locks?

hexed knot
carmine nacelle
plain jungle
#

I think lock depth in Managarm never exceeds two

hexed knot
#

good

#

my kernel's lock depth does exceed two tho

carmine nacelle
#

It should be fine as long as you run kernel with 1 CPU only

#

But yeah, I think this is the longest depth, and it's during a creation of a new right, so nothing should have access to new_right there, and then the other stuff should follow this lock order for the other objects

#

Though I have a different function which locks 7 locks at once

hexed knot
#

so thats 3 locks

#

and you can also take the kernel page table lock which is also 3

carmine nacelle
hexed knot
#

insane

#

what the fuck is that for

carmine nacelle
#

and then it takes 2 more nested locks

carmine nacelle
hexed knot
#

idk i dont have ipc

carmine nacelle
#

message queues

hexed knot
#

ok but why 5 locks lmao

carmine nacelle
#

so that you can send capabilities

hexed knot
#

surely you dont need to acquire every capability lock to do that

carmine nacelle
#

you can send up to 4 extra

carmine nacelle
hexed knot
#

problem solved

carmine nacelle
hexed knot
#

i need to optimize my syscall code so that i dont lock the handle table once for each handle the user includes in direct syscall args

carmine nacelle
#

No, I'm not sure this would be enough

hexed knot
#

idk what your design is like

#

maybe its not possible within it

#

in my design its def possible (maybe because i have refcounted handles?)

carmine nacelle
#

async send sync recieve, multiple sender, both sides can revoke rights

hexed knot
#

oh i dont have revocation too

#

revocation is boring tho

carmine nacelle
carmine nacelle
hexed knot
#

but then your ipc takes 7 locks

#

atp just take a global lock lmao

carmine nacelle
#

I said userspace, not kernel

#

I don't have global lock

hexed knot
#

there is a good chance a global lock would be faster tbh

#

how do you map a buffer if the capability can be revoked?

#

do you just leave it mapped?

#

i.e. you cant revoke mappable objects properly

#

or do you unmap it

#

i.e. you cant safely copy from an mmaped object because you could get rugpulled

carmine nacelle
#

My mappable objects are refcounted

carmine nacelle
#

And I haven't implemented revoking memory objects yet

#

But I think I can just leave them mapped, and the userspace would get EFAULT because the pager has disappeared

#

I need to reimplement pagers first though

#

I had them 3 or so years ago, but basically everything memory and IPC related had changed in the kernel since then

carmine nacelle
carmine nacelle
hexed knot
#

so you can get rugpulled, awesome

carmine nacelle
#

Idk, I don't really have a proper filesystem yet

carmine nacelle
hexed knot
#

idk tbh

#

i mean for pagers its kinda hard i guess

carmine nacelle
#

In userspace

hexed knot
#

thats what wayland does

#

its so awful tho

#

you could require a capability to make pagers

carmine nacelle
#

E.g. if half of the system dies, including all disks, you can just rediscover everything

carmine nacelle
#

Then the stuff like whatever docker is using in Linux is using becomes trivial

plain jungle
#

well, the solution is probably just to do not rely on memory mappings if you cannot trust the remote that handed you the mapping

hexed knot
#

yeah

carmine nacelle
#

You just give capabilities with less permissions

carmine nacelle
plain jungle
carmine nacelle
#

The user can pull the system disk out

#

Linux userspace dies, Windows somehow survives

hexed knot
#

windows hangs userspace requests

#

so it like "survives" but not really

carmine nacelle
#

No, but with Windows to Go, if you accidentally yank the drive out, and quickly plug it back in, it continues as if nothing had happened

#

I guess it just resumes them

hexed knot
#

yeah

carmine nacelle
hexed knot
#

yeah

#

lock acquisitions are not THAT fast

carmine nacelle
#

Sure, you're only holding 1 lock, but for much longer, and this is shared by much more stuff

hexed knot
#

its shared only by other threads

carmine nacelle
#

(Also, I only have spinlocks in kernel)

hexed knot
#

if you are nopreempt thats fine

#

sleeping locks are slower if you dont have preemption to worry about

carmine nacelle
plain jungle
#

sleeping locks are faster on the fast path than spinlocks

#

since spinlocks need to disable irqs

hexed knot
#

oh right

#

well not if your kernel is nopreempt

#

and you dont take locks from the irq handler

carmine nacelle
#

Yeah, I'm nopreempt and never enable interrupts*

#

Or like if you get interrupted, you just don't take locks, problem solved

#

Or don't reschedule

plain jungle
#

well if you just disable preempt but not irqs, you're potentially extending the duration of a spinlock by hundreds of cycles if an irq happens

carmine nacelle
#

I mean paravirt probably complicates everything...

hexed knot
#

irqs are generally rare

carmine nacelle
#

and still, there's stuff like lazy irql

plain jungle
#

it's definitely a trade-off between worst case latency and throughput

carmine nacelle
#

where you'd just bounce back, and do the stuff after the locks are released

#

I think my kernel is very far from being realtime anyway

#

Idk, maybe I can play with atomics instead of locks

#

But this will make it even more complicated

plain jungle
#

I don't know how your locking strategy works but 7 locks sounds excessive

carmine nacelle
#

I take things in particular order

plain jungle
#

you can probably improve this by reworking your strategy

plain jungle
#

what is a right in pmos and why does it needs to be locked for IPC?

carmine nacelle
#

capability

#

it's in rights.hh trl

plain jungle
#

Why do you need to lock it?

carmine nacelle
#

so it can't be revoked before the message is sent

#

I'm writing the notification code right now

#

But it's so that you can recieve a bunch of messages, and then a notification that the right has been revoked (so there can't be any more messages)

#

And that notification has to arrive after everything else

plain jungle
#

There are probably better ways to solve this

carmine nacelle
#

yeah

#

but there are probably better ways to solve everything I have right now

#

So this works and I'll change it when it becomes a serious performance concern

plain jungle
#

FWIW Managarm's IPC also support capability transfer but it never takes more than one lock for the IPC itself

carmine nacelle
#

but managarm's IPC is quite different to mine?

#

Idk, I haven't really looked at it in too depth

plain jungle
#

yes sure

#

I'm not saying that our strategy can be copied over

carmine nacelle
#

The IPC that's sent from kernel won't need to take any locks at all, I think

#

(after I redo it)

#

well, except for the message queue

plain jungle
#

I'm just saying that if you need 7 locks, you should probably rethink it

carmine nacelle
plain jungle
#

making lists lock free is not easy

#

and probably not worth it

carmine nacelle
plain jungle
#

One thing that Managarm does "better" (at least with regards to the locking strategy) here is that inflight capability transfer does not have ownership of the capabilities

carmine nacelle
plain jungle
#

The user is responsible for keeping the cap alive until the transfer completes

#

if the cap is concurrently unmapped, the transfer fails

carmine nacelle
#

So that userspace can reject them if it's not expecting them

plain jungle
#

So the question "how do I keep the cap alive during the transfer" does not come up in the kernel

carmine nacelle
#

yeah

#

but how do you transfer capabilities?

#

I mean I have a different mechanism for it

#

as well

#

Where you can just transfer capabilities between task groups (which serve as namespaces)

#

But this has the issue with the fact that someone can just litter your capability namespace and not tell you about it

plain jungle
#

well, userspace says "i want to sent capability at handle X" and if it unmaps the cap before the transfer is complete, it just gets an error from the transfer

carmine nacelle
#

what does unmapping do in managarm specifically?

plain jungle
#

by unmapping i mean closing the handle

carmine nacelle
#

Are your IDs global?

plain jungle
#

no

#

but capabilities are refcounted

carmine nacelle
#

Or I mean they are -ish

#

I know why I did what I did

#

When you transfer capabilities, you know the source and destination namespaces right away, no?

plain jungle
#

yes

#

well, right away = when the actual transfer happens

#

you don't know the destination at the time of posting the send

carmine nacelle
#

Ok

#

I need to take a look at your IPC I guess

#

Because my threads can choose where to accept the capabilities

#

When receiving

#

But it's the same issue I guess

carmine nacelle
plain jungle
#

i don't have time to explain the full IPC model, you could look at the Managarm paper if you want to understand the details

carmine nacelle
#

Ok, sorry

plain jungle
#

but both send and receive post lightweight message structs to queues without doing any copying of data etc

#

the actual transfer happens when both send and receive are posted

carmine nacelle
#

Yeah, I guess my sync receive a simpler model

carmine nacelle
#

On a separate note, how are you supposed to be doing objdump/addr2line with Jinx?

#

This is fun...

carmine nacelle
#

(I really need to steal Infy's unwinder trl)

carmine nacelle
#

I'll ask clanker to fix it trl

carmine nacelle
hexed knot
#

there is a device for it

#

lol

carmine nacelle
#

behind every assert there is a bug

twilit talon
plain jungle
#

Based on this paper? Probably not but we'll surely have more Managarm talks in the future about upcoming topics

#

Last talk was the one by Geert on syscall cancellation

carmine nacelle
twilit talon
carmine nacelle
#

Idk, very old x86-specific code

#

It's defined in the header, which then calls arch-specific code

carmine nacelle
#

(I just switch the current task pointer, like in bad tutorials)

carmine nacelle
#

Cool, I have notifications about deleted rights working, I think

#

Time to add Rust abstractions nooo

carmine nacelle
#

And I've finally implemented delete port syscall

carmine nacelle
#

I think I'll do futex next...

carmine nacelle
#

Ok, it looks like it's too complicated trl

hexed knot
#

its not that bad

hexed knot
#

you can do futexes 100% in userspace

carmine nacelle
#

I mean it in itself is easy

hexed knot
#

futexes that synchronize between different processes have been deemed by fuchsia to be lame and so you are allowed to not support them

carmine nacelle
#

But I want to move it to kernel

hexed knot
#

why

#

just dont

carmine nacelle
#

It relies on my IPC

hexed knot
#

IPC in process???

carmine nacelle
#

and it's problematic because of priorities

carmine nacelle
#

my recieve is blocking, so it blocks that way

hexed knot
#

how do you implement futexes lol

carmine nacelle
#

i mean it's not quite a futex

#

I did mutex and conditionals with IPC for blocking

#

but I want to have a proper futex

#

so that it doesn't have to allocate (which my IPC always does at the moment)

hexed knot
#

i think you just have a bad impl ngl

carmine nacelle
#

I have plans to get rid of it, but I can't completely get rid of allocations

#

So my mutex works by trying to lock it in userspace, and then when the thread sees that it has been locked by someone else, it blocks on a port

hexed knot
#

the core scheduler API i implement for this is basically ```rs
fn park_prepare() -> ThreadHandle;
fn park_commit();
fn park_wake(handle: ThreadHandle);


with semantics of "if a `park_wake` arrives after `park_prepare`, then the `park_commit` will not block/will stop blocking if it has been entered"
#

you can expose basically this to userspace by making a threadhandle just a tid or something

carmine nacelle
hexed knot
#

and then its a binary semaphore which is trivial

#

and you also need some form of inline lock for synchronizing on the userspace state

#

i have a ttas spinlock because its a kernel mechanism but thats not great for userspace

carmine nacelle
hexed knot
#

if its good enough for webkit (and i think it is) its good enough for you

#

or use an rseq

carmine nacelle
hexed knot
#

ah yeah i guess

#

well you need a kernel-assisted PI lock anyway

#

so yeah take that

carmine nacelle
#

my scheduler has priorities, but I can't use them

#

(tbh, my scheduler also needs work)

#

I have global run queues, and I want to eventually make them cpu-local

#

(except for the threads that are pinned to a given cpu, they have their own cpu-local queues)

#

But I haven't really looked into how to do work balancing and stuff like that yet, and global queues kinda just don't need that

carmine nacelle
twilit talon
hexed knot
carmine nacelle
#

futex on shared memory is trival

#

you just use the physical address as the key

hexed knot
#

i mean true

carmine nacelle
#

if you are in kernel

hexed knot
#

or just use the virtual address and dont futex cross process

#

i think cross process futexes are kinda bad in general

carmine nacelle
#

idk, posix has an api for it, and some ancient program might decide to use it

hexed knot
#

futexes are not posix

#

also the solution is to not cave in to every demand of every broken program but to fix the program

carmine nacelle
#

it could also be nice for stuff like pci, where you need to lock it across drivers

hexed knot
#

if all your drivers trust each other just make them one driver tbh

carmine nacelle
hexed knot
#

a pthread mutex is also complete iirc

carmine nacelle
#

(or put pci in kernel, like managarm did)

#

idk, i feel like mmu will destroy my kernel

#

I need to rework interrupts...

#

there's so much stuff to do nooo

hexed knot
#

go channels are complete too iirc

carmine nacelle
hexed knot
carmine nacelle
#

I mean everyone supports it

hexed knot
#

i mean yes but thats not the point

carmine nacelle
#

So iiuic, with futex I can just add an intrusive list entry to my threads, and then have a hash map of futexes, and push them onto there, which will also work with scheduling and stuff

hexed knot
#

not on all platforms anyway

carmine nacelle
hexed knot
carmine nacelle
hexed knot
#

for example on macos, they hang in a pthread condvar wait

#

on netbsd, its in lwp_park

#

on windows, its WaitForSingleObject

carmine nacelle
hexed knot
#

no

hexed knot
#

sorry an event object

#

which is just a binary semaphore afaict

carmine nacelle
#

what should I do instead of futex then?

hexed knot
#

just do netbsd lwp park apis

#
  • a PI lock
carmine nacelle
#

another issue with my IPC is that it can't timeout

carmine nacelle
#

(though I think I can implement it with my new rights changes now)

hexed knot
#

you know how many levels my kernel has

#

(0 its rust)

carmine nacelle
hexed knot
#

it doesnt need a hashtable but yes

#

it reuses the same info on threads in a process

carmine nacelle
hexed knot
#

wdym

carmine nacelle
#

and you have traits and weirdness

hexed knot
#

a trait is just a class with only pure virtual methods

carmine nacelle
#

like the inheritance is bad because of the virtual functions?
but rust still has that

hexed knot
#

and i dont even have a lot of dynamic dispatch lol

#

i have one case of dynamic dispatch in my rbtree code because of a type system hack

#

a few in my ISA code where its a type system hack and a manual vtable

carmine nacelle
hexed knot
#

one in my object abstraction where its a compile time assertion

#

and thats it

#

and i have dynamic dispatch in my object abstraction but also through a custom vtable

carmine nacelle
hexed knot
#

except i only have one layer of inheritance lol

#

but yeah

carmine nacelle
#

the three levels are there because my rights inherit from messages

hexed knot
#

jank

carmine nacelle
#

so that the kernel can send a right directly, and userspace can read it as a message

#

e.g. I'm planning to rework my timers and interrupts, so that the userspace still recieves the notifications as messages, but internally the kernel just pushes those things onto the message queues

carmine nacelle
#

according to a clanker, lwps are basically threads??

twilit talon
#

thats the idea

#

linux calls (or used to at least) call them that

#

just processes that share the same address space so they're "lightweight"

carmine nacelle
#

I already have something similar to park/unpark then

#

Then what is a normal process?

carmine nacelle
#

So, NetBSD seems to just build a list of waiters, like I do, and then does priority inheritance protections in userspace as well?

carmine nacelle
#

Ok, I think the _lwp_park/unpark and "proper" mutex is more than 1 evening project

#

So what I'm going to do instead is to improve the kernel initialization, and hopefully unify limine and hyper code, and allow to be booted with hyper on x86_64 as well, and maybe I could also port to aarch64 trl

#

And I'm also planning to introduce interrupts rights/redo the interrupt handling in general, so it doesn't allocate memory and hopefully make it faster in general

#

and then I also wanted to do the same with timers (which shouldn't be too difficult (famous last words))

#

and it would also be nice to implement the vfs stuff, but I'm kinda waiting for ext4plus crate to be fixed so it compiles properly with my async runtime, so I'll probably just do it once that's sorted out

carmine nacelle
#

The kernel would have been dual protocol otherwise

twilit talon
#

Why do u even need kaslr

carmine nacelle
#

I don't, but why not have it

#

It works with limine

twilit talon
#

Makes debugging harder, adds relocations

carmine nacelle
#

I can disable it, but idr how galaxybrain

twilit talon
#

idk lol

carmine nacelle
#

My i386 build works

carmine nacelle
carmine nacelle
#

Yes

toxic torrent
#

bru

twilit talon
#

Wdym

toxic torrent
#

i could've told you how to turn it off in limine

carmine nacelle
#

I'm making my kernel truly dual protocol

toxic torrent
#

linux protocol 🗣️

twilit talon
#

I might do that too

#

Because why not

toxic torrent
#

my kernel is protocol independent

twilit talon
#

Dual protocol means u can boot the same binary

toxic torrent
#

yeah

carmine nacelle
twilit talon
#

How did you make it independent exactly

carmine nacelle
toxic torrent
#

it's not working right now, but i made an efi stub that seconds as a limine executable

twilit talon
#

Oh

toxic torrent
#

since limine can take PEs

#

ngl it's kinda pointless

carmine nacelle
#

.......

twilit talon
carmine nacelle
twilit talon
#

Do it

carmine nacelle
#

can I keep this option for ia32 kernel?

twilit talon
#

Docs

carmine nacelle
#

It says "64 bit kernels" so it's confusing if it ignores it or rejects it

twilit talon
#

Wdym

carmine nacelle
#

I guess I just won't

#

Like if I boot a ia32 kernel with allocate anywhere option, will it boot and just ignore it?

twilit talon
#

It cant allocate anywhere since for ia32 its direct mapped to phys 0

#

Iirc it will error out

carmine nacelle
twilit talon
#

Lol

carmine nacelle
#

I don't have disk space to check if ia32 still works...

twilit talon
#

Believe it

carmine nacelle
twilit talon
#

Gpf?

carmine nacelle
#

time to cry in x86

carmine nacelle
#

I just rewrote my ultra protocol init code to not assume anything about ia32

twilit talon
#

Ah

#

Well addr2line

carmine nacelle
#

I don't have it pain

twilit talon
#

How

carmine nacelle
#

Actually, nevermind

#

this tripple faults for no reason

#

I feel like half of the kernel doesn't get initialized or something dumb like that

#

also, what's weird is that it doesn't print anything to serial

#

wtf I forgot to call main function from assembly KEKWgalaxybrain

twilit talon
twilit talon
carmine nacelle
#

It's the largest memory region available trl

#

That fixed a bunch of stuff...

#

Time to add more printfs

#

it works but then it breaks

#

yeah, booting with limine fully works

twilit talon
#

Whats the diff

carmine nacelle
carmine nacelle
#

I'm missing something that I do with limine during the kernel initialization

carmine nacelle
#

Time to fix linking with no lto galaxybrain

twilit talon
#

Just always lto

carmine nacelle
#

I can just drop ultra and not debug trl

twilit talon
#

Objdump

#

Sure lol

carmine nacelle
#

"My 32 bit multiboot kernel finally has a shell!"

carmine nacelle
#

which breaks because I don't use hhdm

#

Let's see if clanker can fix this trl

#

The boot process basically the same though

#

Does ultra do elf relocations?

#

Though i686 build worked with no issues in the past...

carmine nacelle
#

Ok, it's a skill issue with both protocols....

twilit talon
#

it doesnt do any form of kaslr

carmine nacelle
twilit talon
#

not in an EXEC elf

carmine nacelle
#

cool

#

maybe you could implement the other one too though

twilit talon
#

but why?

#

it's only relevant if u wanna do kaslr

#

it's a niche (and not super useful) kernel isolation technique

#

certainly has 0 relevance for any hobby os

#

idk why mint implemented it

carmine nacelle
#

can you do kasl without it?

twilit talon
#

wdym

carmine nacelle
#

kasl + exec

twilit talon
#

can u lie in the elf header?

#

sure its possible

#

should u? probably not unless u can do self relocation

carmine nacelle
#

or what is 0x03?

twilit talon
#

like ld.so

twilit talon
#

PIE or .so is always ET_DYN

carmine nacelle
#

So it's a dyn exec

#

yeah

twilit talon
carmine nacelle
#

what

#

how does relocatable userspace wark then?

#

surely it's not ET_DYN

twilit talon
#

every userspace executable is ET_DYN

#

check any elf u have lol

#

but its not linux doing those relocations, but ld.so

#

another file it loads alongside and hands over control to

#
$ readelf --header /usr/bin/cat
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Position-Independent Executable file)
carmine nacelle
twilit talon
#

yeah but linux doesnt check those types at all nor does it perform any relocations

carmine nacelle
#

this sounds fun

twilit talon
#

they have some cursed code in there for it

#

i thought u had a dynamically linked userspace??

plain jungle
#

same as the kernel elf self relocation code that i posted a while ago

carmine nacelle
#

I wanted to port mlibc so it could be done for me trl

#

Anyway, this is x86_64 + hyper build (fully working)

#

Ultra + Limine dual protocol with the same kernel binary

#

Clanker found a very dumb bug, which was unrelated to boot protocols...

twilit talon
#

lol

#

cool that it works at least

carmine nacelle
twilit talon
#

always blame a bootloader if u have an early crash and uacpi if u have a late crash trl

carmine nacelle
#

I mean both stress memory allocation in their own ways trl

#

but the issue was that I though it was early init code, but it's basically the same between limine and hyper protocols

#

I mean I don't reclaim bootloader memory with hyper yet...

#

It should be trivial to implement though

twilit talon
#

i dont reclaim it yet because i rely on its page tables trl

carmine nacelle
#

I reclaim limine's memory

#

Am I the only OS doing that on this server? trl

twilit talon
#

nah ill be doing it soon

#

i was procrastinating setting up a direct map

carmine nacelle
#

I don't use direct map trl

twilit talon
#

gg

#

but since u support crappy arches its easier not to use it

#

since its the same code for all arches

carmine nacelle
#

Though I think I'll introduce it as an optimization on 64 bit arches

#

Since I use it on loongarch

#

Where you can place it in the canonical gap

twilit talon
#

it's a good optimization since u can map hhdm with gigabyte pages

#

so it's very light on tlb

carmine nacelle
#

It should be trivial to implement

#

All of my code explicitly calls map/unmap already to access physical memory, and I can just short circuit it to return hhdm + addr

#

(like I do on loongarch for no reason)

twilit talon
#

linux has something like that

#

for 32-bit when u go outside of 768 megs

carmine nacelle
#

besides the initialization, where I have to use it

#

Ok, I really want to add multiboot2 and then MIPS

#

Since I assume it should be really easy considering I already support risc-v and loongarch

twilit talon
#

Do big endian power pc

carmine nacelle
#

but booting there is cursed

#

idk, like what bootloader do I use?

#

I have a Wii to test it on though

twilit talon
carmine nacelle
#

I'd need a prekernel nooo

twilit talon
#

Yes

carmine nacelle
carmine nacelle
#

Bruh, this shit is scary

#

my kernel in the nutshell

carmine nacelle
#

Just some locking issues, and an issue with tlb invalidation

#

and some path where I didn't propagate errors correctly...

carmine nacelle
#

Ok, it also found deadlocks in my (pinned) memory objects and page tables, but I think I'll just nuke that, and fully switch to memory object rights, since that subsystem is cancerous anyway

carmine nacelle
#

I think I'll do something similar

#

(I mean I kinda had something like that already in mind)

#

What I'll have is

  1. Root/interrupt management capability (I probably won't bother with it for now though trl)
  2. Interrupt handler capability
  3. Interrupt notification capability
carmine nacelle
#

(plt)

plain jungle
#

Hm?

carmine nacelle
#

plt

#

I don't have dynamic linker

fringe grove
#

hehe

twilit talon
#

h

carmine nacelle
#

Cool, my risc-v port had somehow survived all of my changes

carmine nacelle
carmine nacelle
#

cool, my i686 port tripple faults on boot nooo

#

In this rdmsr...

#

(which I think might be a skill issue with x2apic and smp?)

#

I wonder if that's the same issue as what's been stopping this from booting on that macbook...

#

Yeah, it almost fully works if I disable SMP trl

#

And of course it works on risc-v, because every time I look at its code, I'm amazed how good it is

carmine nacelle
#

Yeah, no, it's still broken on that macbook

twilit talon
#

i686 dies on macbook?

carmine nacelle
#

no, smp

twilit talon
#

lol

carmine nacelle
#

I haven't tried i686 because I can't get EFI to work in Hyper

#

(probably because I'm compiling it wrong)

carmine nacelle
#

and I would assume x86_64 would be as well

#

(My apic/interrupts code is shared between the two)

twilit talon
carmine nacelle
#

idk, qemu was refusing to boot it

#

you can try compiling pmos for yourself trl

twilit talon
#

refusing how

carmine nacelle
#

(It compiles llvm and rustc in the process, which takes several hours on my laptop)

carmine nacelle
twilit talon
#

what does that mean

carmine nacelle
#

says "failed to boot" and tries to boot from pxe

twilit talon
#

huh

carmine nacelle
#

I have't gotten into edk2's menu though

twilit talon
#

screenshot?

carmine nacelle
#

no

twilit talon
#

definitely works fine for me & ci

carmine nacelle
twilit talon
#

probably means theres no BOOTX64.EFI on there

carmine nacelle
#

there should be

twilit talon
#

u can wait for it to drop you into edk2 cmd and type dir to see

carmine nacelle
twilit talon
#

maybe like 30 seconds

#

try spamming escape or something

carmine nacelle
twilit talon
#

yeah that looks fine

#

BOOTAAARCH64

#

lol

carmine nacelle
#

what does it need to be?

twilit talon
#

AA64

carmine nacelle
twilit talon
#

definitely not 3 A

carmine nacelle
#

It doesn't matter, I don't have an arm port anyway

twilit talon
#

do it trl

carmine nacelle
carmine nacelle
#

I wanted to unfuck my interrupt management first

twilit talon
#

yeah u will need it for arm

carmine nacelle
#

Nothing in boot/efi

twilit talon
#

gg

carmine nacelle
#

though having both would be better

twilit talon
#

how does it help your interrupt management

carmine nacelle
#

it doesn't

twilit talon
carmine nacelle
twilit talon
#

i was replying to the thing directly above my message lmfao

carmine nacelle
#

classic discord moment

twilit talon
#

lol

carmine nacelle
#

Ok, I've managed to get it to work

#

I seriously need to stop using copilot

#

Because I make a lot of mistakes myself already, which I can't see

#

And the fact that it autocompletes my shitcode with even more plausible-looking weirdness, but absolutely wrong stuff is bad...

twilit talon
#

what was the problem?

carmine nacelle
twilit talon
#

ah

carmine nacelle
#

and also mcopy didn't like that I've given it multiple arguments?

#

idk

#

but hyper with uefi boots instantly

twilit talon
#

lol u had bootx64.elf

#

lmao

carmine nacelle
twilit talon
#

arm has insanely complex interrupt hierarchies

#

and interrupt controllers

carmine nacelle
#

And I guess I can then handle that stuff transparently in kernel

#

All userspace would get is an interrupt source, and a right to recieve interrupts from it

#

But yeah, I'm having trouble with it even on x86...

twilit talon
#

btw if u want the boot to be faster u can do --strip-info-logs=on when building it

#

those are especially slow on bios kvm