#Zinnia

1 messages · Page 24 of 1

hybrid island
#

oops

#

fixë

near tartan
#

also you might need to update the readme if you delete a task

#

(not that big of a deal but it might be confusing)

hybrid island
#

ok i updated that too

near tartan
#

is the gpt overhead always the same value?

hybrid island
#

Yeah that's a fixed property of GPT-formatted things

near tartan
#

ah

hybrid island
#

One block MBR, 33 at start and end for GPT

hybrid island
#

lmfao how am i meant to respond to this

near tartan
#

67 blocks

#

you tried that it actually creates a working image right?

hybrid island
#

Well you don't exactly put anything into /boot for me to test it

near tartan
#

yeah i do

#

:S

#

the kernel and servers are installed to /boot

hybrid island
#

system-root/boot is empty for me

near tartan
#

did you install the packages

#

oh right you don't have the aliases

#
alias xbi 'xbstrap install'
alias xbib 'xbstrap install --rebuild'
alias xbibt 'xbstrap install-tool --recom'
alias xbic 'xbstrap install --recon'
alias xbict 'xbstrap install-tool --recon'
alias xbit 'xbstrap install-tool'
alias xbr 'xbstrap run'
alias xbrt 'xbstrap runtool'
alias xbu 'xbstrap install --rebuild --reset -u'
alias xbut 'xbstrap install-tool --recompile --reset -u'
#

xbstrap has fish and bash completions

#

i use xbic for reconfigures and xbib for rebuilds

#

for host-tools you need to append a t

hybrid island
#

It says nothing to do and it's still empty

#

for xbstrap install

near tartan
#

you need to give it a package

#

so zinnia and zinnia-servers

hybrid island
#

I just did all

near tartan
#

that also works

#

says this for me

hybrid island
#

Ran with QEMU, seems to work

#

I did however forget to rename one thing, pushed the working ver now

near tartan
#

is this 3 line spacing some default formatting or something?

#

it's a very very very minor nit

hybrid island
#

I like to put additional newlines to visually separate parts of my code

near tartan
#

esp up here

#

maybe you could move the constants to the top

hybrid island
#

Yes that's intentional

near tartan
#

so they're easy to see

#

that's my last comment on this

#

otherwise looks good

hybrid island
#

I moveth

near tartan
#

emma vs spamming git reset HEAD~1 && git push -f

hybrid island
#

No

#

I just git commit -a --amend

#

Way easier

near tartan
#

or that

hybrid island
#

But yes the force pushes looke like a battlefield

#

cool

near tartan
#

damn

#

okay works on my end

#

it is noticably slower though

somber solar
#

you can disable force pushes on github

near tartan
#

why would i do that

hybrid island
somber solar
hybrid island
near tartan
somber solar
#

well yeah I have it disabled on master

hybrid island
#

But this isn't our main branch I was force pushing

near tartan
#
marvin@aquaduct ~/r/z/build-x86_64 (main)> time xbr make-image
xbstrap: Running the following plan:
    run            make-image
xbstrap: run make-image [1/1]
xbstrap: Running ['@SOURCE_ROOT@/tasks/make-image.py', '@SYSROOT_DIR@', '@BUILD_ROOT@/zinnia.img'] (tools: [])
mke2fs 1.47.3 (8-Jul-2025)
Discarding device blocks: done                            
Creating filesystem with 1015799 4k blocks and 253952 inodes
Filesystem UUID: 1f832505-9515-4adb-b4f1-606c6c29f29d
Superblock backups stored on blocks: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736

Allocating group tables: done                            
Writing inode tables: done                            
Copying files into the device: done
Writing superblocks and filesystem accounting information: done 

Creating image from 2 partitions:
    "EFI part", type 0x0700, size 134217728, offset 17408
    "Root part", type 0x8300, size 4160715264, offset 134235136

Creating new GPT entries in memory.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.
262144+0 records in
262144+0 records out
134217728 bytes (134 MB, 128 MiB) copied, 0.0632966 s, 2.1 GB/s
8126397+0 records in
8126397+0 records out
4160715264 bytes (4.2 GB, 3.9 GiB) copied, 1.34642 s, 3.1 GB/s

________________________________________________________
Executed in    2.61 secs      fish           external
   usr time  633.20 millis    0.75 millis  632.45 millis
   sys time  968.36 millis    2.21 millis  966.15 millis

#

it's not the end of the world but idk if this scales well when you have a ton of files

hybrid island
#

I have no idea why sgdisk takes long but it always has

#

Even for tiny disks

near tartan
#

also, is this unconditionally copying over things?

#

or does it actually check files to be present already

#

actually no it can't

#

bruh

#

yeah this is going to be a problem

hybrid island
#

This is what you get for non-sudo. To my knowledge you can't do this without sudo but also copy files incrementally.

near tartan
#

mmmmmmmmmm

hybrid island
#

The tools could be made but don't exist in mainstream distros.

near tartan
#

this isn't really going to work tbh

#

i like this, but like

#

not mounting stuff is going to be horribly slow

#

and will kill iteration speeds

#

bc imagine you have an actual gcc + libc + maybe X11 in the sysroot

#

that's a shit ton of data

#

if you have to copy everything again on EVERY kernel/server recompile, it'll take infinitely longer

#

(the python script is a good idea regardless)

#

but not using mount is a mistake imo

hybrid island
#

The clanker tells me you can use debugfs to copy data in and out

#

And it's right of course

#

But can you rsync like that I wonder

near tartan
#

never heard

hybrid island
#

debugfs is a standard tool, any distro has it

near tartan
#

experiment with it as you please

#

if it works out, it's fine in my eyes

#

but i don't see it being a viable replacement

hybrid island
#

Apparently there's FUSE impls of ext2 as well

#

Which shouldn't require root

near tartan
#

those are RO iirc

hybrid island
#

Actually I wonder

#

What happens if I dump 1GiB of trash in the image

#

How slow

near tartan
#

try

hybrid island
#

Ok I added 2.6 useless GiBs lets see

#

This was not as slow as I thought but it still took a bit

#
real    0m19.380s
user    0m2.225s
sys     0m15.831s
#

Most of that was actually the dd from the filesystem blob into the final image

#

2.7G image

near tartan
#

i do a lot of recompiles when developing, and 20 seconds every time sounds like a nightmare

hybrid island
#

:/

#

Then I can't make it work without sudo without either spending a shitton of time making something

near tartan
#

imo it's fine if you only put sudo in that one mount

#

the rest should work without (?)

hybrid island
#

This wouldn't even be a problem if I could more efficiently copy into the final image from the root part

#

Because then you'd only spend like 4 seconds

near tartan
#

well managarm and menix for example only do rsyncs while it's mounted

#

it's very efficient for partial updates

hybrid island
#

yeah i get that

near tartan
#

you can also use it to write to real block devices

#

the speedup vs dding a fresh image is insane

hybrid island
#

But ehhh if you can't live with it potentially being slow here you're gonna just have to revert

#

Because the old way did work

#

It would be nice if there was a standardised non-root way to mount like this, because it can be done safely

near tartan
#

yeah

hybrid island
#

But that's just not a thing

near tartan
#

i would actually keep the python script, but just adapt it back

#

i.e. replace the bash scripts with python because i do not trust the fragile integer logic of bash

hybrid island
#

fair

#

Still will need some uhm shenanigans

#

I'll see what I can do but it's a shame we can't get rid of sudo here

#

Actually what I can do is make an incremental mode that does that based on an env var if you're ok with adding export IDKSOMETHINGLOL=1 to your .bashrc

#

Then nonsudo for me, incremental for you

near tartan
#

do you hate sudo that much?

#

you can make a no sudo task

hybrid island
#

I'm allergic to sudo in my build pipelines because I had to fix build folders owned by root one too many times in the past

near tartan
#

xbstrap tasks can take argv and env

#

you can just pass it there

#

like make-image-nosudo

hybrid island
#

Also for some reason this keeps crashing the python LSP

near tartan
#

yeah happens for me too lmao

hybrid island
#

BTW the with sudo version is basically exactly your thing but it's in python now

#

Every single sudo is required in that old script

near tartan
#

still better than bash

#

oh

#

really?

hybrid island
#

Only the rm -rf tmpdir can be nonsudo

#

Because root doesn't need to own the tmpdir

near tartan
#

not even the rsync?

#

ah i guess it's mounted for root

hybrid island
#

I'll check the rsync but you still have the root inode's permissions to contend with

#

Actually probably yeah you can

near tartan
#

yeah and you have to copy files with absolute control over uid/gid

hybrid island
#

Well normal installation everything is owned by root, and mapping 0<->1000 means that you should get that with a normal rsync

near tartan
#

hm

#

not everything is owned by root

#

case in point /home/foo

#

that's also part of the image

#

i had a really cursed idea for IPC

#

what if we used printf format strings to specify serialization formats trl

hybrid island
#

OK eh, we will just run the entire python script with sudo at that point because then literally every operation we want is root anyway

hybrid island
#

Maybe with debugfs

#

Is /home/foo really part of the image? Doesn't the installer normally make those files?

near tartan
#

what installer

#

this is a rootfs basically

#

afaik no hobby os has a proper installer

hybrid island
#

uhm

#

Then as soon as we start actually checking UIDs, this cannot possibly work because /home/foo will be owned by root

#

Like either way we did won't work

near tartan
#

what's "this"? the current way or the old way

hybrid island
#

We need to start chown ing

#

Which didn't happen at all

#

in the past

near tartan
#

well rsync does the permissions

hybrid island
#

Yeah but it clones the perms from the sysroot dir

#

And all the UIDs in there are from whoever built it

near tartan
#

fuck

#

that is an issue indeed

hybrid island
#

So we can forget about the nonsudo approach in the first place as soon as we actually check uid and gid

near tartan
#

rip

#

i think managarm does it by mounting /home/user for uid 1000

#

and the rest for uid 0

hybrid island
#

If it's just like 2 files we can get away with a super fugly call to debugfs to change the owner uid and gid

#

But much more becomes real ugly real quick

near tartan
#

nah it'll be a ton of files

hybrid island
#

Everything in $HOME I take it?

near tartan
#

yeah basically

hybrid island
#

mmm

#

shit

#

Well I guess we might end up removing the non-sudo approach later because I... Don't want to invoke a debugfs command where argc=2000

near tartan
#

yikes

hybrid island
#

I'll fix something up for the incremental crap tomorrow, for now I think it's approaching sleepytime

near tartan
#

🛏️

#

eep time

#

i will do more ipc memes and do some cleanup

hybrid island
#

ts is why all of our sleep schedules are fucked meme

near tartan
#

later today i want to start doing the initd connection broker

near tartan
#

will review after lunch

near tartan
#

@hybrid island could you auto format the script?

hybrid island
#

What's wrong with it

#

I guarantee you autoformatting it will make it look uglier

near tartan
#

i have format on Dave on

#

*save

#

lol format on dave

hybrid island
#

It doesn't even change anything when I format it

near tartan
#

huh

hybrid island
#

Looks like I don't have a python formatter

#

(hint: you're supposed to tell me which formatter you use)

near tartan
#

uhhh

#

i think black

#

i can check in a bit

#

im almost done with lunch

hoary cave
#

black is the based one

#

it's what managarm uses too

hybrid island
#

bruh it changes so much of the file it's a 95% rewrite now

#

here have your shitty formatted python script but don't ask me to update something that looks like THIS again

hoary cave
#

lol

near tartan
#

bruh

#

how bad does it look

hybrid island
#

terrible

near tartan
#

let me see

hybrid island
#

Formatting is nice and all until you have one that doesn't agree with you on how code should look

storm bobcat
#

Why is it called black

#

lol

near tartan
#

cuz it doesn't work

#

you can customize it (e.g. i use clang-format files for C/C++)

storm bobcat
#

I like clang format

near tartan
#

yeah

storm bobcat
#

Idk why some people hate it

near tartan
#

coping

hybrid island
near tartan
#

fair point

somber solar
hybrid island
#

formatting isn't related to the functionality I changed here anyway

hybrid island
#

and you accepted the last one without it

storm bobcat
#

There's a website that makes it easy

somber solar
#

yea

hybrid island
storm bobcat
#

I don't really care about the formatting style, I just want it to be consistent

#

I think I use the Linux one but with 4 indent tabs

near tartan
#

nothing worse than inconsistent style

#

managarm has this problem sometimes

#

inconsistent tab vs space indents

#

reeks of gnu

hybrid island
#

If you have the align assignment on and put a compound initializer afterward you get this fugly bullshit:

int        alongname = 2;
struct foo bar       = {
          .a = 1,
          .b = 2,
      };
#

It looks so ugly to me I have actually shuffled code in e.g. Lily-CC many times to avoid this clang-format bug

near tartan
#

// clang-format off meme

hybrid island
#

compound initializers should probably be exempt entirely from the assignment alignment but you can't tell it that.

near tartan
#

i only use it once for the IDT macro thing

hybrid island
near tartan
#

i just don't use aligned assignments

#

i only align macro defs

hybrid island
#

Aligned assignments look so pretty though

near tartan
hybrid island
#

what

#

where did the 6 seconds come from

near tartan
#

that's what i'm asking

#

it's suddenly really slow

hybrid island
#

burh

near tartan
#

im krilling myseld

hybrid island
#

This is basically just your way but now using sgdisk instead of parted because I don't know parted

near tartan
#

ok fuck the formatting

#

do it how you think it's best

#

but can you try using parted

#

it's much quicker

#

maybe we should restore the empty-image task

#

becasue it looks like creating the disk takes the longest time

#

when it only needs to mount the image and rsync

storm bobcat
near tartan
#

i do

#

because C

storm bobcat
#

Well I use C too

near tartan
#

what do you use then

storm bobcat
#

When do you need compound initializers?

#

Apart from like globals

near tartan
#

when i create a new struct

#

i may not understand the question

storm bobcat
#

I mostly initialize members one-by-one

hybrid island
#

Problem is I can't get parted working

near tartan
#

huh

hybrid island
#

I just don't know how to use it ok

hoary cave
#

maybe you should ask claude

near tartan
#

the bash script should work

#

💀

hybrid island
#

Yeah but you wanted it to be the fancy fucking python script and I need to set specific offsets

near tartan
#

hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

hybrid island
#

If I still want the nonsudo thing to exist

#

also the clanker doesn't know parted either

near tartan
#

let me try on top of the current diff

#

ok no something is horribly wrong with this code

#

it's so much slower even with parted

#

wth

hybrid island
#

For some reason setting the name of the partitions is failing but the rest is not

hybrid island
#

I use rsync and everything

near tartan
#

yeah im so confused

#

let me try doing the bash script again

#

i doubt that it's that

#

oh i know what it might be

#

there was a reason why the empty-image task was split

hybrid island
#

Is every single sudo just making it ultraslow?

near tartan
#

dont think so

#

let me try splitting this off

hybrid island
#

This is so fucking stupid

#

parted exits with code 0 if you give it invalid arguments

#

At this point I see literally no reason to not just revert the whole python script idea

near tartan
#

sure

#

im sorry

hybrid island
#

ts pmo

#

I hate touching userland and disk images

near tartan
#

yep

hybrid island
#

They're all SO FUCKING UGLY

near tartan
#

now you know why i never touch anything 😭

#

once it works "fine" i leave it at that

hybrid island
#

there you go

near tartan
#

wth why did it open it as an edit view

hybrid island
#

idk

near tartan
#

was that intended

hybrid island
near tartan
#

whatever

hybrid island
#

Well that was a solid waste of like 8 hours of my time

#

I could've been making something actually useful like VMM

#

Can we hop in VC in a bit to set up clangd

near tartan
#

okay

near tartan
#

i have time rn

marble salmon
#

it's arguable nicer than black

#

(but it's relatively new)

marsh holly
#

Wruff

eternal wharf
#

ruff is pretty nice we use it at work

#

its also nice in that it replaces black, isort and flake8

marble salmon
#

yeah and it's way faster than black

hybrid island
#

@near tartan I see struct spinlock contains a single bool, but you can't do lockfree atomics on a single byte in RISC-V (without helper functions at least)

#

I suggest making it an atomic_int instead

#

Also you can make it an rwlock if it's an int

#

Which may turn out useful later

near tartan
#

yeah that should be fine

#

most structs will force it to be aligned to sizeof(uintptr_t) anyways

hybrid island
#

And it has to be naturally aligned

lofty copper
#

What's the issue with doing 4 byte atomics on 1 byte type?

#

besides it being slow

near tartan
#

has to be naturally aligned

lofty copper
near tartan
#

and how does that work if it's only one byte

lofty copper
#

CAS or whatever risc-v uses

#

Idr

#

if bytes around it change, you repeat

near tartan
#

that seems like unnecessary overhead when you can just make it 4 bytes

lofty copper
#

yeah

#

but it is possible

near tartan
#

didnt say that it wasn't

hybrid island
#

BTW I also fixed the code style of the doubly-linked list to match the rest of the structs

#

So that'll be struct dlist when I PR this

#

BTW @near tartan where do you want me to put user API stuff (e.g. PROT_*)

#

Since that's a common thing between the kernel and userspace

near tartan
#

if it's used for syscalls, include/zinnia

hybrid island
#

ok

near tartan
#

mem.h has some flags that are basically PROT_*

#

// Virtual memory flags.
enum zn_vm_flags {
    ZN_VM_MAP_READ = 1 << 0,
    ZN_VM_MAP_WRITE = 1 << 1,
    ZN_VM_MAP_EXEC = 1 << 2,
    ZN_VM_MAP_SHARED = 1 << 3,
    ZN_VM_MAP_FIXED = 1 << 4,
};
hybrid island
#

I see

near tartan
#

maybe the _MAP_ can be dropped

#

so it's just ZN_VM_READ

hybrid island
#

It's probably best to 1. not use an enum like this for compatibility reasons and 2. split prot and map flags because POSIX demands that anyway

near tartan
#

compatibility with what?

hybrid island
#

(MAP_* and PROT_* are technically required to expand into integer literals)

#

AFAIK

near tartan
#

but this is the syscall interface

#

libc/posixd handles the conversion from posix arguments

#

i.e. the actual PROT_* and MAP_* are part of the mlibc ABI

#

those bits would go in servers/posixd/include/uapi

hybrid island
#

ok

#

The current struct vmo shenanigans don't really match how UVM does stuff so I'll be replacing that as well

#

Mainly the part where I want vtable to be separate from the pointer so you can make a pager for random object handles without having to suddenly make them a struct vmo

near tartan
#

but isn't that implied?

#

a vmo is a mappable memory object, regardless of the backing data

hybrid island
#

No I mean

#

You use a thin pointer

#

I will be using a fat pointer

#

Just like UVM, which uses fat pointers for this purpose

near tartan
#

will you be keeping the functions mostly the same tho?

#

I don't care about the impl details, but i find being able to write directly to a vmo without mapping it very neat

hybrid island
#

I'll be keeping the basic idea of a pager the same

hybrid island
#

Hmmm

#

I suppose that would mean we need a bit more than just a single fat pointer to a pager

#

I'll see what I can do.

#

Because I get why you want to be able to do that to VMOs

near tartan
#

what's the issue?

hybrid island
#

Well it would be a semi-significant difference from how UVM handles things

#

However I should be able to work with struct vmo with some minor changes:

  1. I need more protection for the page returned by get_page (it could currently race if you concurrently read and flush writes for example)
  2. I need a way to reference-count the struct vmo to correctly implement vmm
near tartan
#

i mean yeah vmos should be refcounted anyways

hybrid island
#

Do you have any refcounting infra at the moment?

near tartan
#

no

hybrid island
#

ah

#

Guess I am also making that

near tartan
#

remember when i crashed out over not having an Arc meme

#

that's where i left it

hybrid island
#

I mean we could just steal rc_t from Lily-CC and rename it struct arc meme

near tartan
#

just call it struct rc

#

or refcount

hybrid island
#

Also

#

I could add a weak counter to it pretty easily when we decide we want it

near tartan
#

@lofty copper how good/bad is working with plain C headers for IPC?

#

since pmos doesn't use generated bindings

hybrid island
#

Depends on what exactly you mean by that

near tartan
#

i mean exactly what i said

hybrid island
#

Like writing everything by hand?

near tartan
#

yeah

#

pmos' ipc doesn't look too complicated

hybrid island
#

Oh I thought you meant in terms of working, rather than being a PITA or not to write

#

nvm me im rarted trl

#

BTW go join the invite link I sent u already

storm bobcat
near tartan
#

💀

#

that makes sense

near tartan
near tartan
#

@grave peak

#

using TCG

#

kvm is a bit better here

#

but no idea why it's so god damn slow tbh

somber solar
near tartan
#

yeah

somber solar
#

real

near tartan
#

mfw no CoW

#

i would really like to know what is making it so slow

#

maybe the fact that it has to do a syscall to get the current time?

somber solar
#

didn't you have vdso

near tartan
#

i can imagine that the scheduler is also horribly unoptimized

near tartan
#

too much effort to maintain

#

maybe i can provide the timer as a shared memory object

grave peak
near tartan
near tartan
#

i guess i can try using a bump allocator on a preallocated region to see what is causing the performance issues

#

because i doubt that it's the mlibc allocator itself, rather than the kernel

marble salmon
#

You can swap out the allocator in mlibc for sharded_slab

#

We should do that anyway as it's faster

near tartan
#

I think the issue is that i have to do 2 syscalls atm to allocate anon memory

#

so there's already a bit of overhead

#

can i instruct mlibc to preallocate a certain amount of bytes at once?

near tartan
#

i can just map the ZERO_VMO as non-shared

marble salmon
#

mlibc (or rather frigg) allocates in chunks of a specific super block size

#

iirc that is 256k

near tartan
#

hm then it shouldn't be a syscall issue

#

that's weird

#

maybe my scheduler is just very slow?

marble salmon
#

Actually, it probably calls one per size class into the kernel allocator though

modern hamlet
#

allocate and change protection or

modern hamlet
near tartan
near tartan
#

and zinnia is a microkernel so it kind of makes sense to run in user mode

hoary cave
#

write faults on the zero vmo should not be possible

#

even if it's mapped private

#

the idea i thought you had with it is the same as managarm, which is just have a singleton vm object which you can map and have it provide a single zero page

#

i guess you could combine that + CoW but you still need to create a new vm object so atp you can just create a separate one instead

#

or i guess that's how anonymous shared memory works in managarm, CoW on top of ZeroMemory

near tartan
#

then im curious how proxima got such a high score

hoary cave
#

who cares about the score make it run xorg bruh

near tartan
#

bruh

#

ok

hoary cave
#

hell yeah

near tartan
#

i did some tinkering with ipc

#

without dsl

marble salmon
#

And has no op spinlocks and mutexes

#

And a single threaded allocator that is not thread safe

near tartan
#

ok that's a bit unfair

marble salmon
#

i pinged infy about it multiple times meme ¯_(ツ)_/¯

near tartan
#

ig now my next goal is to comnect multiple servers via initd

#

no idea how I'm supposed to do that though

marble salmon
#

(spinlocks and mutexes are no ops)

#

(specialized single threaded allocator with no locks)

storm bobcat
marble salmon
modern hamlet
marsh holly
#

Time to add an uacpi thread to astral to make benchmark go up

#

And then making a special purpose allocator for it

vast lotus
#

but yeah it's not something you should compare other implementations to

marble salmon
#

Ah

#

true, sorry

near tartan
#

@marble salmon in managarm, can there be multiple senders on a lane?

#

basically, im trying to figure out how to establish a messae channel betwen a new server and the init server

#

i could allocate a channel with multiple senders and initd on the other end, but I'm not sure if that's a good idea

#

another idea would be to notify initd of a new channel via ipc from the kernel

marble salmon
#

Managarm has this concept of offer/accept that allows you to spawn new streams in an ad-hoc way

#

In general, lanes are not thread bound on Managarm

#

but that doesn't mean that you can just pass a lane to many processes and expect it to work

#

Streams in Managarm are not general purpose byte transports

#

you can read the Managarm paper to understand how it works

#

senders and receivers on corresponding lanes must respect a common protocol (i.e. send compatible requests in the right sequence)

#

Otherwise, both sides fail

#

with kHelErrTransmissionMismatch

#

This IPC system is quite unique to Managarm though

near tartan
#

okay then speaking in general, it's not a mistake to send messages from different peers to a common endpoint, right? (assuming the messages are designed for this, e.g. containing a peer handle/id)

marble salmon
#

I'd say the existence of a peer handle is questionable

near tartan
#

sure

hoary cave
#

you should not have multiple things send stuff to the same channel

#

because then you end up not knowing who sent what

#

unless you add some sort of reply_handle to recv

#

or peer_handle

near tartan
#

that's why i said the thing in parentheses

hoary cave
#

ah

near tartan
#

ofc sending generic messages from an unknown peer will cause some chaos

marble salmon
#

With peer handles you're adding an unnecessary complication

#

And it opens up more questions than it answers

#

Like, what's the lifetime of a peer handle, how does access control work etc

near tartan
#

what's the alternative?

#

i need a way to establish connections between servers that only know each other by name

#

the current idea is
srv0 -> initd "i want srv1"
initd -> srv1 "new connection, give me an endpoint"
srv1 -> initd "here's an endpoint to talk to me"
initd -> srv0 "here's a connection to srv1"

lofty copper
lofty copper
near tartan
#

also need to think about how to provide privileged data from the kernel to the servers

#

my current idea is (e.g. to get the RSDP)

  • kernel starts initd
  • kernel publishes the address as an object by writing a message to the initd channel
  • kernel starts acpid
  • acpid establishes connection to initd
  • acpid requests the RSDP object
  • done
#

im not sure if initd should store the bytes itself, or keep a connection open over which the bytes can be sent

storm bobcat
#

you send a "send-once" reply port right

storm bobcat
near tartan
#

hm

#

the question is how i pass it over

storm bobcat
near tartan
#

yeah HOW

#

map the boot info fixed to 0x1000 galaxybrain

storm bobcat
#

No just pass the parameter to init

#

Like in its main function

near tartan
#

in argv?

storm bobcat
#

you can have a third parameter

near tartan
#

@hybrid island any progress so far?

hybrid island
#

on vmm you mean?

near tartan
#

yeah

#

i'm holding off on big edits before those changes are in

hybrid island
#

Yeah I've decided the final struct layouts to use already

#

The renaming is also finished

#

Now I wanted all the VMOs to be refcounted so there will be an API change there

#

Once I integrate that change it should be good for the interim so you can call the API in the new form (though the impl will still be the old one)

#

If you want I could make such an interim PR

near tartan
#

yes

hybrid island
#

After that PR I'll likely have to take a break from programming for a bit since turns out I haven't had a week without any programming in the last year

near tartan
#

let's stop programming for ever

lofty copper
#

(I'm doing it by passing a list of stuff from kernel, mapped into the process, and giving the address in one of the argument registers, but I think I'll replace it with auxvec)

near tartan
#

true i could do it via auxvec

lofty copper
#

wait, what ipc do you have at the moment?

near tartan
#

only sync messages and shared memory

lofty copper
#

and you want to do async?

near tartan
#

no

#

where did you get that from?

near tartan
#

that doesn't have to be async

#

how do named ports work

#

in pmos

lofty copper
#

I don't have sync ipc (but that's kinda irrelevant)

#

My init server stores the ports, and then anyone can ask it

#

Like named port -> right to it

#

I had it in the kernel initially, but moved it to userspace

#

So basically spiritually similar to mach

near tartan
#

my idea is to have servers register themselves with the init server, providing a handle to talk with it

lofty copper
#

And since it's an init server, you can control the permissions and stuff

near tartan
#

do you have a mechanism to share data between multiple servers?

lofty copper
#

Wdym?

near tartan
#

if i understand managarm code correctly, mbus can store generic data and share it using names

near tartan
#

I've seen managarm use it to e.g. discover devices on pci bus

#

so a driver can query objects on mbus

lofty copper
#

Yeah

near tartan
#

does pmbus do that too?

lofty copper
#

But it's just ipc, you get an mbus handle and talk to it

lofty copper
#

I mean it's kinda not fully implemented yet

near tartan
#

lol

#

ig my question is whether this object store should store the object in the server itself, or just forward the request to a server that provides the data

lofty copper
#

Both

near tartan
lofty copper
#

I thought it was more of a discovery mechanism? So you store the stuff like PCI/ACPI ID there to be able to match the drivers, and then talk to PCI server or whatever to setup interrupts and whatnot

#

That's how I wanted to do it

near tartan
#

yeah kind of

#

for the pci example

#

ig you'd do

struct pci_device dev = get_pci_device(0, 0x80, 0x14, 2);
if (dev.vendor != 0x8086)
    return;

run_driver(&dev);
...
#

and that would be passed using attributes

#
struct obj dev = obj_create("pci/0000:80.14.2");
obj_add_prop(&dev, "vendor", cfg_space->vendor, sizeof(uint16_t));
obj_add_prop(&dev, "segment", 0, sizeof(uint32_t));
obj_add_prop(&dev, "bus", 0x80, sizeof(uint32_t));
...
hybrid island
#

gamging PCI

near tartan
#

in my mind this makes sense

#

and that would allow the kernel to also publish some objects from its side

#

i wonder how i can restrict access to physical addresses

#

like conceptually

#

@lofty copper you have a pcid, right?

#

nvm you dont

#

you have devicesd

near tartan
#

@hybrid island sorry to pester you, but do you mind making the PR anytime soon? i want to start writing a lot of code now and don't want to destroy your work

hybrid island
near tartan
#

two things so far

#

this is missing a newline

#

and this is not needed

#

there is a CONTAINER_OF macro in common/utils.h

#

if you want you can move the static assert into there (and you can use the actual static_assert spelling because of C23)

#

actually, if you want you can replace my CONTAINER_OF with the one you wrote

#

it looks better

#

tho idk if you need the #ifndef, i think you could just do #else there?

#

could be wrong

hybrid island
near tartan
#

oh

#

i thought that can be #if a && b

#

then it's fine

#

but yeah this seems more robust than my impl

hybrid island
near tartan
#

maybe __builtin_types_compatible can be just abstracted via common/compiler.h

#

there you can make it eval to a noop if it's not defined

#

i already do it for __builtin_unreachable for example

hybrid island
#

Problem is that __builtin_types_compatible isn't really something you should do as a hint

#

So I'd advise against that

near tartan
#

hm?

#

sure ig

#

it's not that deep anyways

#

if i ever add support for another non gnu-like compiler i'll refactor it

hybrid island
#

Well that's the point

#

This will work on a nongnu compiler

near tartan
#

is this the same as {0}?

near tartan
#

unlike linux where it's all scattered across the codebase behind 10 levels of macros

hybrid island
near tartan
#

okay

#

i see you prefer not using macros for generic containers

hybrid island
#

No, all my generic containers just assume you know what type should be in there. As do most implementations of C containers I know of.

near tartan
#

hm

hybrid island
#

I'm not against having these convey type information but I already had these and personally don't want to spend the time reinventing them

near tartan
#

you don't have to

#

i'm just saying that it might be best to not do it for all containers

#

for intrusive linked lists it's totally fine

#

but i'd not do this for a vec or hashmap

#

(i say that as i am already not doing it lol)

hybrid island
#

I fixé the CONTAINER_OF now

#

And I also added the missing newline

near tartan
#

thanks

#

LGTM

#

it still has the old mapping impl right?

hybrid island
#

all actual impl still old

#

Only renamed some of the things

near tartan
#

right

#

ok merging

#

okay that was surprisingly painless

#

just had to change one thing in main.c

#

great

hybrid island
#

Actual API will look quite similar by the end

#

Though you will of course pass a struct rc * of a struct vmo

#

Instead of struct vmo *

near tartan
#

yeah

hoary cave
#

weird

near tartan
#

what is

hoary cave
#

passing around a struct rc*

#

lol

near tartan
#

yeah true

#

i would just put the rc in the object itself

storm bobcat
#

yeah ^

#

passing a random struct rc sounds type unsafe and a bit weird

hybrid island
#

hm

#

I don't see why not

#

Wouldn't be a big change to the refcount impl

near tartan
#

type safety is something i am very cautious about

#

that's why i like using macros

hybrid island
#

IME the biggest type unsafety bugs I've had was my old vector impl I'm still wondering how to replace in Lily-CC

near tartan
#

do you have a link?

hybrid island
near tartan
#

what the helly

hybrid island
#

This is VERY old btw

#

It's just copied into Lily-CC

near tartan
#

😭 i scrolled down and the args increased even more

hybrid island
#

Yeah

#

And that's the reason this thing sucks

near tartan
#

atp writing a few macros seems like heaven KEKW

storm bobcat
#

why is this like 300 lines

hybrid island
hybrid island
#
// Clear all elements without freeing memory.
#define VEC_CLEAR(vec) ((vec)->length = 0)
#

This sounds like leaks waiting to happen @near tartan

near tartan
#

wtf i forgot to impl it

near tartan
#

ok nice i changed the channel impl so that the kernel can also act as a peer now

#

for physical memory access, does it make sense to "claim" physical memory?

#

for example, the acpi server would try to claim the acpi tables region and any other servers trying to access that physical memory would get an EPERM

hybrid island
#

I think it would be more reasonable to have whatever spawns drivers get elevated permission to map arbitrary physical memory and have it divy it up to the individual servers

storm bobcat
lofty copper
storm bobcat
#

you own an handle to some range of physical memory

near tartan
#

yeah i mean that

storm bobcat
#

but you can share it

#

if you want

near tartan
#

but to create such a handle i mean

vast lotus
#

what I'd do:

  • the root bus (acpi or devicetree) server has full access to the physical memory space excluding kernel-managed ram
  • the root bus server manages resource conflicts and gives out handles to physical memory/io ranges that each device owns
storm bobcat
#

the init server would start with a handle (or multiple) ranging over the entire physical memory (minus the kernel), it would then carve it up and give it to the servers

lofty copper
#

You also have to think about IO ports...

storm bobcat
#

yeah like monkuous said

hybrid island
#

IMO the kernel should magic an initial set into existance based on e.g. RSDP or DTB

near tartan
#

i disagree

vast lotus
#

also when you design your DMA and pager interface make sure you do it in a way that allows you to implement iommu support later

lofty copper
storm bobcat
#

how?

#

you just give the init server a handle

lofty copper
#

What if the memory is not contiguous, etc.

storm bobcat
#

ok fine then just the entire physical memory

near tartan
storm bobcat
#

you dont

near tartan
#

just everything that was launched via initrd?

vast lotus
#

init gets a handle to the entirety of physical memory (except requests to map kernel managed ram are denied)

#

init gives this handle to acpi/devicetree then does nothing else with it

lofty copper
#

Also, when you launch a driver for the device, you can give it access to that memory (and set up iommu in your PCI server or whatever else)

hybrid island
#

Seems most reasonable to me

storm bobcat
#

yeah thats what i said

hybrid island
#

Esp since our ACPI is gonna be userspace

lofty copper
#

But ACPI server can be trusted

near tartan
#

that sounds counter intuitive

lofty copper
#

Why not. It's just a design decision

vast lotus
#

yeah iommu is probably better fit for the kernel

lofty copper
#

Some kernels (minix?) have userspace control page tables

vast lotus
#

because (among other reasons) it's involved in interrupt remapping

near tartan
vast lotus
#

another reason is that with userspace iommu drivers you'd need three context switches for each pagein/pageout (set up mapping, perform io, remove mapping)

hybrid island
#

I should look up what IOMMU actually gets used for

near tartan
#

my understanding of what an iommu does is probably wrong

lofty copper
#

Yeah, I guess it should be in kernel then

vast lotus
lofty copper
#

But still, you can just ask someone to map memory for you

vast lotus
#

even if you don't care about security or high cpu counts the iommu is important because it lets 32 bit devices DMA to 64 bit memory without bounce buffers

lofty copper
#

I mean, at this point, everything can just access everything in my os

marble salmon
hybrid island
#

Definitely a kernel thing, IOMMU

marble salmon
#

see the Managarm system bus reconfiguration issue

lofty copper
#

I have a flag to allocate memory in userspace into lower 4GB

hybrid island
#

So the IOMMU creates a virtual address space shared by all DMA devices?

#

Or one each?

vast lotus
marble salmon
#

the TLDR is: cores (e.g., kernel framebuffer or kernel uart output) can concurrently write to PCIe BARs while decoding is being disabled to discover the BAR size

vast lotus
#

usually the iommu id is derived from the bus location, for example in pci it's just bus:device:function (although bridges can complicate this)

marble salmon
#

i.e., BAR enumeration and the kernel writing to its framebuffer/uarts

near tartan
#

i don't remember, do you need to read the bar size or isn't this something that can be done lazily

marble salmon
#

the problem doesn't go away if you do it lazily

lofty copper
#

Just don't have a framebuffer driver in kernel

vast lotus
#

or does it just not

marble salmon
#

Linux doesn't do anything special afaict

#

maybe it doesn't write to the boot framebuffer from APs

#

not sure

#

in any case if this happens on real hw it causes essentially a full system hang because the bus timeouts are so long

vast lotus
#

maybe they rely on the initial pci bar enumeration (which would contain all boot resources) being done during an init phase where nothing else is running or generating interrupts?

marble salmon
#

maybe. APs start earlier than PCIe enum but maybe there's nothing interesting scheduled to them yet

near tartan
#

tho i wonder why this only happens on my laptop

#

is that purely impl specific?

marble salmon
#

it's a race, right?

#

so it's expected that it doesn't happen everywhere

hybrid island
#

Long live the hardware jank

#

And the software needing to work around it

near tartan
#

i'll figure something out when the time comes

near tartan
#

i need to move the thread creation logic to mlibc though, otherwise it will keep crashing because of missing TLS data

near tartan
#

made it so i can use standard C11 threads using mlibc

#

i can't really use plain syscalls to create new threads because that leaves me without thread local data and breaks a lot of things

lofty copper
#

Doesn't mlibc handle TLS?

near tartan
#

if i only use plain syscalls to create a thread it works until you call some libc function

#

but if i do it via mlibc then it obviously works

#

ig I'll also need a way of waiting for a thread to finish

lofty copper
#

Huh

near tartan
#

i mean is this surprising?

#

mlibc preallocates a Thread Control Block and passes it on the new thread's stack

lofty copper
#

Yes, but what are you doing before it?

hoary cave
#

wdym before it

lofty copper
#

I just don't get it, if mlibc does it for you, why do you have to worry about it

#

Or why can't you use that

#

Sorry if it's a dumb question

near tartan
#

I didn't implement it before

#

in mlibc

near tartan
#

implemented futexes and can block on threads now

near tartan
#

last thing i did before bed

#

servers can now find each other via initd

marble salmon
#

nice

#

what design did you settle on now?

near tartan
#

the mach design

#

it sends a new channel handle back to the requester provided recv_handle

marble salmon
#

ah wait

#

so not sender IDs?

#

but the same capability mechanism that is also used for everything else?

near tartan
#

the find request contains a name and an answer channel

#

the client creates a channel and immediately moves an endpoint over

marble salmon
#

ah

#

yeah that makes sense

#

now just make it async, remove any buffering (if it exists) and compress it to a single syscall to obtain Managarm IPC

near tartan
#

then i could just work on thor rs or freya

marble salmon
#

btw speaking of freya @hoary cave what if we make freya a library

#

and spawns ld.so on a separate thread

#

and then handles the posix supercalls for that separate thread

hoary cave
#

what the fuck

#

but also

#

that sounds fun

marble salmon
#
Thor
|
| spawns                |---------------------------|
↓             spawns    |                           |
Freya ----------------> |          loads            |
  ^                     |   ld.so ------> server    |
  |---------------------|                           |
     handles posix      |---------------------------|
#

where freya + ld.so + the server are all in the same address space

#

but ld.so and the server are on separate threads from freya

hoary cave
#

only thing im concerned about is how it would handle filesystem requests

near tartan
#

wont that increase startup delays?

hoary cave
#

wow

#

tragic

#

for all the 5 servers that are started

#

keep in mind this is only for servers

near tartan
#

😭

#

oh

hoary cave
#

did anyone mention that already

near tartan
#

korona only mentioned running before ld.so

hoary cave
#

yeah, freya -> ld.so -> server

#

servers are dynamically linked

grave peak
#

whats freya

hoary cave
#

nothing yet, but soon to be a library that handles posix calls from servers

grave peak
#

like a generic one?

hoary cave
#

it was supposed to be a server manager

marble salmon
#

ig thor could map all "files" (or the whole initrd, that was suggested by qookie) into freya and pass the address to that (or of some description struct) in rax (or similar)

grave peak
#

also why is it called that?

hoary cave
# hoary cave nothing yet, but soon to be a library that handles posix calls from servers

currently there are some things which are implemented as "supercalls", im not sure on the details but i know that supercalls from servers are handled by the kernel, idk if the posix server handles them for normal userspace programs - that's because you can't call into posix from posix itself, since servers are dynamically linked and use the same libc.so as userspace you end up with this circular dependency which is satisfied by the kernel

hoary cave
marble salmon
#

yeah posix handles supercalls of all apps

#

all application threads are owned by posix

hoary cave
#

i came up with that name for the init server in my rust kernel that was inspired by thor :^)

grave peak
#

oh interesting

hoary cave
#

tbh the kernel used the eir boot protocol and implemented the hel api

grave peak
#

so its going to be like a managarm project that all osses can use?

hoary cave
#

i don't think so

#

it was supposed to be so we can move server management out of the kernel

#

it's not like a userspace service manager like systemd or whatever

grave peak
#

ah ok

#

cause ur discussing it in this thread lol

#

so i thought it was

hoary cave
#

yeah kind of off topic lol

near tartan
#

hm

#

i just noticed my channel ipc is suboptimal

#

i queue an unspecified amount of messages

#

something tells me that is a bad idea

#

actually i'm not even sure about that

#

@marble salmon maybe?

#

on every write to a channel i allocate a message buffer in the kernel

marble salmon
#

allocating an unbounded amount of kernel memory is obviously a bad idea

near tartan
#

yeah sure

#

my question is whether i should be queueing messages with more than 1 slot

storm bobcat
#

If everything is synchronous do you need a queue?

near tartan
#

probably not

marble salmon
near tartan
#

isnt managarm ipc very unique anyways

lofty copper
#

every ipc is unique I guess

near tartan
#

not mine because i'm boring

vast lotus
lofty copper
marble salmon
#

this (what monkuous said). also, i'd probably use a utcb like concept to do it in a single copy for small messages

vast lotus
lofty copper
#

but if you have to context switch anyway

marble salmon
#

what Managarm does for large messages is it copies in the sender's thread to a page, sends the page to the receiver thread and the receiver copies out of it

#

this involves two copies of course

#

but there can be multiple in flight pages, so at least it's pipelined

marble salmon
lofty copper
#

it sounds very similar, you still have some memory buffer that's being moved (?)

near tartan
#

i wonder how well just shared memory + futexes would work for this

marble salmon
lofty copper
marble salmon
#

shared memory can achieve zero copy or single copy very easily

#

but it has a high setup cost

near tartan
#

shrug can't be that bad

#

let me give it a try

marble salmon
#

so it's worth it for persistent connections between servers

#

but not for one-off messaging

lofty copper
marble salmon
#

no, this is two copies

near tartan
marble salmon
lofty copper
marble salmon
#

with shared memory, you can achieve one copy (sender -> receiver), or zero copy (sender writes to buffer that receiver uses in-place)

#

On Managarm, mlibc and POSIX do not exchange any significant amount of data

near tartan
#

not even on write()?

lofty copper
#

does managarm have kernel memory objects or something?

#

how does it even do shared memory?

near tartan
#

i guess there's one problem with shmem only, handles can't be transferred safely

near tartan
#

how is that supposed to work

#

handles are only valid for the current namespace

hybrid island
#

Like any other handle transfer?

near tartan
#

??

#

it's shared memory

#

there's no kernel involved

#

you could do some dumb shit like *buf = translate_handle(handle)

hybrid island
#

You cannot create shared memory without kernel involvement

near tartan
#

...

#

you can't send handles

hybrid island
#

What kind of microkernel doesn't allow you to send handles?

lofty copper
near tartan
#

omfg

hybrid island
#

That doesn't make any sense

lofty copper
#

between processes

near tartan
#

bro

hybrid island
#

When you create the shared memory you get a handle

storm bobcat
hybrid island
#

And you share the handle to another process, which then maps it

near tartan
#

that's not at all what i am talking about

#

i'm talking about sending handles to another namespace

#

that works with channels because the kernel translates it to the other namespace

storm bobcat
#

No you can't send handles through shmem like that

storm bobcat
#

You have to do it with the other messaging scheme

lofty copper
#

just move the handle to that namespace, write its id to the shmem

near tartan
#

so shmem is purely data only

hybrid island
#

of course it is

lofty copper
#

I do that during the process initialization

hybrid island
#

But most of the IPC you'll want to do in reality will be data-only

#

In terms of total bytes sent

lofty copper
#

but what about reply handles

vast lotus
#

if you have ipc exclusively via shmem what i'd do for handles is make it so you can have a handle to a different namespace and use a syscall to 'copy' a handle from that namespace into yours (or another), then have a shared namespace in addition to a shared memory area

#

so senders would first copy a handle from their own namespace into the shared one, then write the shared handle into the shared memory area

vast lotus
#

ah ok

near tartan
#

i'll try this

vast lotus
#

but for what it's worth i don't think having shmem-only ipc is worth it

#

sure it might be for stuff like posix<->libc but that's not the only ipc

lofty copper
#

my ipc is just buffered in kernel

vast lotus
#

for a lot of things ipc will be a oneoff and setting up shared memory for that would be cumbersome

lofty copper
#

"dead simple"

marble salmon
#

just have a capability space that is a capability itself

#

such that you can attach it to two processes and let them copy in/out

#

although ofc copying in/out still needs a syscall

lofty copper
#

cheri trl

lofty copper
#

but yeah

near tartan
#

ig channels for small messages and shmem for big data

storm bobcat
#

It's common to have regular synchronous IPC and async shared memory

lofty copper
#

i mean handles is just another resource, like memory or io

marble salmon
#

we did access remote address spaces in the past but then switched to this mechanism because it reduces locking etc

#

But now we have better locking mechanisms in place and we should be able to do remote page faults in a lock-free way so maybe it's time to re-evaluate this

lofty copper
#

but you still need to walk paging structures, map it somewhere, etc.

marble salmon
#

you don't map it but access it from the direct map

#

but yeah, this needs proper benchmarking

#

it could very well be slower than the pipelined copy that we do rn (since that lets the cpu do the page walk etc)

#

I do know that Managarm is not bottlenecked on large transfers

#

since if I bump copy chunk sizes in the kernel, microbenchmarks do improve while macro benchmarks (like mlibc compilation time or glxgears fps) don't

lofty copper
marble salmon
#

wdym by "so that the page tables can also be disposable"?

#

That's unrelated to remote copy afaict

#

But a separate mapping is almost certainly slower

lofty copper
#

it is unrelated, but it might be faster to get it from there than from page tables?

hoary cave
#

that sounds like a skill issue

marble salmon
#

the problem with separate mappings is that you need to do shootdown etc

#

which is very expensive

#

you can easily copy a few pages in the time it takes to do a shootdown

near tartan
#

speaking of ipc with mlibc

#

does it make sense to create a new thread for every connection of mlibc <-> posixd in posixd?