#OBOS (not vibecoded)

1 messages · Page 36 of 1

devout niche
#

you'll be wanting to do userspace

#

dhcp clients are usually using PF_LINK sockets (which are for directly dealing with ethernet frames) due to their particular requirements

flint idol
#

was readin the TCP spec

#
IETF Datatracker

This document specifies the Transmission Control Protocol (TCP). TCP is an important transport-layer protocol in the Internet protocol stack, and it has continuously evolved over decades of use and growth of the Internet. Over this time, a number of changes have been made to TCP as it was specified in RFC 793, though these have only been documen...

#

why tf is it so long

short mortar
#

nah it's easy

flint idol
#

mhm...

#

I'm going to start TCP soon

#

later today maybe

#

just need to finish something

haughty abyss
#

TCP is long because of all the stuff that was added i think

thick jolt
short mortar
#

what, it's just a sliding window and sending acks and naks when you feel like it

flint idol
#

yes definitely

flint idol
flint idol
#

It seems like obos' r8169 driver just works™️ on the r8139

sterile sparrow
#

Well the 8169 is just a 1000mbps version of the 8139, right?

flint idol
#

Idk something like that

thick jolt
#

boo

timid elk
#

8139 being more generic and 8169 is a fork of it or something

#

i don't think OBOS does anything where that would matter tho

sterile sparrow
#

Ah lmao

#

I've seen drivers that work with both so idk

flint idol
#

I haven't been able to figure out how to communicate with obos when it runs in qemu

#

So until then

proper trellis
#

what networking mode did you specify to qemu?

flint idol
#

-nic user,model=r8139

proper trellis
#

iirc you have to port forward

#

or use a tap device

#

smth like ,id=net0,hostfwd=tcp::2222-:22

thick jolt
vale nymph
#

You can even port forward on your router and have someone connect to obos

timid elk
#

or just support ipv6 lol

#

you can probably do bridge networking to give qemu an entire ipv6 address

#

if you can't then add that to qemu

flint idol
#

bah qemu networking stoobid

timid elk
#

qemu is stupid roll your own emulator

#

obemu

short mortar
#

At that point just roll your own isa

flint idol
#

fun fact: virtualbox does not have _S3

#
            pg->pagedCount--;
            MmH_DerefPage(pg);```
#

I just found

#

the stupidest lines of code

#

in obos

uncut narwhal
#

congrats

flint idol
#

I love it when bash segfaults:

[  LOG  ] User thread 7 SIGSEGV (rip 0x0, cr2 0x0, error code 0x00000014)```
thick jolt
flint idol
#

bash is driving me nuts

#

it keeps segfaulting

leaden carbon
#

bashes fault

#

4am debugging goes crazy

flint idol
#

yes definitely all bash's fault

#

I implemented a mount syscall

#

(the mount command is some makeshift one I made myself in 5 minutes)

flint idol
#

added a umount command

flint idol
#

damn obos rewrite 5 old days

#

still have those same logs

thick jolt
thick jolt
#

idt OK

#

cpu OK

#

printf OK

timid elk
#

actually some bsd's coreutils would be interesting

flint idol
flint idol
flint idol
#

yeah ikr-

[  LOG  ] User thread 7 SIGSEGV (rip 0x0, cr2 0x0, error code 0x00000014)```
flint idol
#

I've been working on adding better cross compilation support to obos-strap

#

as well as host and target packages

proper trellis
#

what happend to tcp?

timid elk
#

e.g. build is the machine that builds, host is the mschine that runs and target is the machine that host compiles for

flint idol
#

yes

flint idol
devout niche
#

obostrap pictured

flint idol
flint idol
#

these new changes to obos-strap have caused me to rebuild gcc thrice today

#

anyway so now host packages (like the bootstrap gcc binaries) are all built under build_root/host_pkgs whilst target packages are built under build_root/pkgs

flint idol
#
In file included from /home/oberrow/Code/obos-pkgs/host_pkgs/lib/gcc/x86_64-obos/14.2.0/include/syslimits.h:7,
                 from /home/oberrow/Code/obos-pkgs/host_pkgs/lib/gcc/x86_64-obos/14.2.0/include/limits.h:34,
                 from /home/oberrow/Code/obos-master/src/oboskrnl/external/nanoprintf.h:65,
                 from /home/oberrow/Code/obos-master/src/oboskrnl/klog.c:38:
/home/oberrow/Code/obos-pkgs/host_pkgs/lib/gcc/x86_64-obos/14.2.0/include/limits.h:210:15: fatal error: limits.h: No such file or directory
  210 | #include_next <limits.h>                /* recurse down to the real one */
#

bruh what the hell

#

what why would it want mlibc's limits header

flint idol
#

rebuilt gcc

#

works now

torpid wigeon
#

i'm currently on my 12th compile

timid elk
#

it's part of my routine now

#

i wake up

#

change stuff in mlibc

#

rebuild gcc (twice, bootstrapping it from the compiler that compiles the compiler)

#

then breakfast as it compiles

#

then repeat

flint idol
#

I've been debugging the sleep command in coreutils

#

because it just like doesn't work in obos

#

(it hangs indefinitely)

#
    memzero(Core_GetCurrentThread()->context.extended_ctx_ptr, Arch_GetXSaveRegionSize());
    if (obos_expect(Arch_HasXSAVE, true))
        __builtin_ia32_xrstor(Core_GetCurrentThread()->context.extended_ctx_ptr, __builtin_ia32_xgetbv(0));
    else
        __builtin_ia32_fxrstor(Core_GetCurrentThread()->context.extended_ctx_ptr);```
#

idk why but I feel like doing this to reset extended context state is wrong

#

well I tried looking at astral

#

it only uses fxsave

#

The XSAVE header of a newly allocated XSAVE area should be initialized to all zeroes before saving context. An
operating system may choose to establish beginning state-component values for a task by executing XRSTOR from
an XSAVE area that the OS has configured. If it is desired to begin state component i in its initial configuration, the
OS should clear bit i in the XSTATE_BV field in the XSAVE header; otherwise, it should set that bit and place the
desired beginning value in the appropriate location in the XSAVE area

#

from intel sdm

#

volume 3 chapter 15

#

section 5.4

white mulch
flint idol
#

don't think so

#

this is before an execve call passes control to userspace btw

#

I also don't even touch fcw

white mulch
#

you are supposed to set the initial state to match what the sysv abi specifies

flint idol
#

I see

#
static __attribute__((target("xsave"))) __attribute__((target("avx"))) void reset_extended_state()
{
    asm volatile("fninit");
    memzero(Core_GetCurrentThread()->context.extended_ctx_ptr, Arch_GetXSaveRegionSize());
    static const uint32_t mxcsr = 0x1f80;
    *((uint32_t*)(Core_GetCurrentThread()->context.extended_ctx_ptr + 24)) = mxcsr;
    *((uint16_t*)(Core_GetCurrentThread()->context.extended_ctx_ptr)) = 0x33f;
    if (obos_expect(Arch_HasXSAVE, true))
        __builtin_ia32_xrstor(Core_GetCurrentThread()->context.extended_ctx_ptr, __builtin_ia32_xgetbv(0));
    else
        __builtin_ia32_fxrstor(Core_GetCurrentThread()->context.extended_ctx_ptr);
}```
#

this is in an effort to get bash to stop segfaulting

#

and I think it worked

#

jinxed it

#
[  LOG  ] User thread 7 SIGSEGV (rip 0x0, cr2 0x0, error code 0x00000014)
#

yeah bash likes to segfault

#

I think it's a bug with fork

thick jolt
#

hey ive come to check on progress with obos

#

it seems your encountering a bug with

#

fork()?

#

yep

flint idol
#

It's a bug somewhere

#

I think it's a bug with fork

thick jolt
#

understandable

#

well maybe i could help like look through the code myself

#

i wont write anything cause yk cast

#

but

#

ill try to look for it

#

can i see ur fork code

#

if thats okay omar

#

@flint idol

flint idol
#

Ye sure

#

Hope you heal well btw

thick jolt
#

thanks omar

flint idol
thick jolt
#

from what im looking at

#

the only thing im suspecting is this line

#

hold on

#

wait

#

no

#

it looks valid

flint idol
#

it could also be a bug elsewhere

#

adding printfs seem to delay the bug happening

white mulch
#

💀 those are the worst kinds of bugs tbh

flint idol
#

if it is a memory manager bug, it's probably a use after free of a physical page

thick jolt
flint idol
#

I guess an easy way to figure that out is by examining each use of struct page

#

and making sure each one references it and dereferences it at the appropriate times

#

which I am doing now

#
static bool sym_cow_cpy(context* ctx, page_range* rng, uintptr_t addr, uint32_t ec, page* pg, page_info* info)
{
    info->prot.present = true;
    if (pg->refcount == 1 /* we're the only one left */)
    {
        // Steal the page.
        info->prot.rw = true;
        info->prot.ro = false;
        MmS_SetPageMapping(ctx->pt, info, pg->phys, false);
        pg->cow_type = COW_DISABLED;
        return true;
    }
    page* new = MmH_PgAllocatePhysical(rng->phys32, info->prot.huge_page);
    new->pagedCount++;
    memcpy(MmS_MapVirtFromPhys(new->phys), MmS_MapVirtFromPhys(pg->phys), info->prot.huge_page ? OBOS_HUGE_PAGE_SIZE : OBOS_PAGE_SIZE);
    info->prot.rw = true;
    info->prot.ro = false;
    info->phys = new->phys;
    MmS_SetPageMapping(ctx->pt, info, new->phys, false);
    pg->pagedCount--;
    MmH_DerefPage(pg);
    return true;
}
#

this is the actual CoW handler

main girder
#

it handle cow?

flint idol
#

which at a glance doesn't seem to do anything stupid

flint idol
main girder
#

what guards the decrement on pg->pagedCount--

#

that is not atomic

flint idol
#
    _Atomic(size_t) pagedCount;
#

it's implcitily atomic

main girder
#

that doesnt uh

#

i dont think that works

flint idol
#

I think

main girder
#

no

#

i do not believe that will necessarily cause a lock prefix on x86 or for an ll/sc sequence to be generated on riscs or whatever

#

you should check and see what its emitting

flint idol
#

good idea

#

the compiler generates a lock sub instruction

main girder
#

inchresting

#

what if you compile it for like risc-v

flint idol
#

I don't support risc-v

#

but I could try m68k

#
void MmH_RefPage(page* buf)
{
    buf->refcount++;
    printf("refed page %p (now at %d)\n", buf->phys, buf->refcount);
}
void MmH_DerefPage(page* buf)
{
    printf("derefed page %p (now at %d)\n", buf->phys, buf->refcount - 1);
    if (!(--buf->refcount))
    {
        if (~buf->flags & PHYS_PAGE_MMIO)
            Mm_FreePhysicalPages(buf->phys, ((buf->flags & PHYS_PAGE_HUGE_PAGE) ? OBOS_HUGE_PAGE_SIZE : OBOS_PAGE_SIZE) / OBOS_PAGE_SIZE);
        // printf("removed page from tree (refcount %d)\n", buf->refcount);
        RB_REMOVE(phys_page_tree, &Mm_PhysicalPages, buf);
        Mm_PhysicalMemoryUsage -= ((buf->flags & PHYS_PAGE_HUGE_PAGE) ? OBOS_HUGE_PAGE_SIZE : OBOS_PAGE_SIZE);
        Mm_Allocator->Free(Mm_Allocator, buf, sizeof(*buf));
    }
}```
#

this is probably correct...

#
    mov eax, Sys_ProcessStart
    mov rsi, rbx
    mov rdx, 1
    syscall
    mov r14, rax

    // Get the PID
    // TODO: Can this be a race condition if the process ends fast enough?
    mov rdi, r14
    mov eax, Sys_ProcessGetPid
    syscall
#

this is my fork code in userspace

#

maybe through some miracle that race condition happens

#

and somehow breaks all

white mulch
# main girder no

Built-in increment and decrement operators and compound assignment are read-modify-write atomic operations with total sequentially consistent ordering (as if using memory_order_seq_cst).

main girder
#

you have been fooled by atomic into thinking it will save you from all of your sins

#

even if those incs and decs are atomic im p sure this is broken

flint idol
#

elaborate?

main girder
#

do you ever call DerefPage at a time where the refcount may be 1 and some other guy may still have a pointer to the page?

#

but has not yet called RefPage himself

flint idol
#

I'd hope not

#

it is possible

main girder
#

how do you deal with putting pages on like standby/modified/whatever list

flint idol
#

I looked into that

#

I forgot to reference the page 💀

flint idol
#
[  LOG  ] User thread 7 SIGSEGV (rip 0x0, cr2 0x0, error code 0x00000014)```
#

hmm

#

what if

#

it's calling a weak function

#

in mlibc

#

a weak sysdep specifically

#

I would expect mlibc to check for that as it usually does

#

and return ENOSYS

#

the error code passed by the cpu

#

so 0x14 means executing a non present page in user mode

#

it's executing nullptr trl

#

no

#

since the execute bit is set in the error code

#

and cr2=0

#

that means the program tried to execute 0x0

white mulch
#

address

#

its always address

flint idol
#

no

#

wrong

#

yeah no stack corruption

#

is the cause of the bug

#

but if that were the case

#

that would also mean rbp is broke

#
  4b8381:       5d                      pop    %rbp
  4b8382:       c3                      ret

that's what I get looking into the function bash calls before dying

white mulch
flint idol
#

yeah this PF is happening likely right after a ret statement

#

wait if the stack is corrupted then so is the popped rbp

#

(likely)

white mulch
#

well I guess it depends

#

it could be that only stuff starting at the ret addr would be corrupted

flint idol
#

possibly

#

just in case I will stub out sys_mkdir

#

yeah no it persists

#

but the thing is it doesn't always happen

white mulch
#

how much stack space do you give to the thread?

weak kestrel
#

isn't that a bit much

flint idol
#

Idk

#

Btw I saw what you deleted

white mulch
#

yeah I deleted it because I realized that this probably doesn't happen when just running bash and not doing anything in there?

flint idol
#

No it only happens in bash afaik

white mulch
#

does it happen if you just run plain bash

#

like when you don't type anything to there

flint idol
#

It only happens after typing a command

#

And it only happens when fork has been called at least once

#

Occasionally a SIGSEGV happens before that

#

And that segfault is because of a GPF

#
     293 text files.
     293 unique files.                                          
       0 files ignored.

github.com/AlDanial/cloc v 2.02  T=0.24 s (1200.9 files/s, 205999.5 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                              136           2591           3004          28549
C/C++ Header                   143           1799           2360           9889
Assembly                         9            226            124           1241
CMake                            5             72             35            372
-------------------------------------------------------------------------------
SUM:                           293           4688           5523          40051
-------------------------------------------------------------------------------
#

OBOS LoC update

#

I need to get rid of 51 un needed LoC

#

to get it to exactly 40k meme

flint idol
#

I want to port obos to i686 /srs

#

I will start in a bit

#

anywhere from 1-2 buisness days

#

it will be my 3rd port

#

it will use the same drivers as x86_64

#

and interrupt controller stuff

#

stuff like that

#

not much will be different except for paging, gdt, and idt code

#

and syscall abi

#

and probably some other stuff that I can't think of off the top of my head

#

thread context info stuff

#

I will also probably shift away from using the HHDM

flint idol
#

and signal code

#

I would also be adding PIC and PIT support

#

which actually might be tricky considering how my abstract IRQ interface works, but I think I'll be able to find it out

#

it should be fun, but until then...

#

actually I should poll what arch I should port to next

#

#polls message
pls vote

mortal dock
#

1 vote risc-v 64 😭

timid elk
flint idol
#

Good idea

#

It's almost as if I never tried to do that

flint idol
flint idol
#

time to start itanium port

#

uh so this will be fun

#

I guess I'll start with compiling an ia64-gcc toolchain

#

on gcc 15

#

or gcc 13.3

#

since I want a tarball release I will go with 13.3

real pecan
#

how do u boot on m68k atm?

#

did u roll something for that

flint idol
#

I stole @ornate ginkgo's limine stub

#

hmm could I just use debian's packaged ia64 binutils and gcc

real pecan
#

add support for ia64-be

flint idol
#

I'll do that one day

#

itanium surely has ACPI, right?

#

I know it has EFI, iirc it was made for itanium (or with itanium in mind)

ornate ginkgo
#

It has acpi

flint idol
#

based

#

I will be the first to test uacpi on itanium

#

probably

ornate ginkgo
#

GL with the port, itanium looks interesting

flint idol
#

thanks

#

I need debports it seems

#

for that package

#

oh nvm

real pecan
#

not even hw reduced

flint idol
#

waow

#

this should be fun

real pecan
#

yeah

flint idol
#

(famous last words)

#

currently compiling ia64-elf binutils

#

and ia64-elf-gcc

#

compiled ia64-elf binutils

#

it was able to assemble and link some random ass program I found online

#

wait I haven't linked it yet

#

was able to link it

#

I think gcc just finished compiling

#

this took way too little time

#

it's compiling libgcc now

#
checking for suffix of object files... configure: error: in `/home/oberrow/Code/obos-pkgs-ia64/bootstrap/bootstrap-gcc/ia64-elf/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
flint idol
#

libgcc isn't compiling

#

it's compiling about some libc headers

#

couldn't care less about libc headers

#

so I'm ignoring it

flint idol
flint idol
#

@dim bolt know of any itanium emulators?

dim bolt
#

if you hate yourself

flint idol
#

I'm making an itanium port, so of course I hate myself /j

#

this?

dim bolt
#

ya

flint idol
#

kthx

#
../configure: line 5959: syntax error near unexpected token `-Werror=implicit-int,'
../configure: line 5959: `AX_CHECK_COMPILE_FLAG(-Werror=implicit-int, CFLAGS="$CFLAGS -Werror=implicit-int", , -Werror)'
#

bruh

#

ok whatever

#

I got it to configure

#

yay it compiles

flint idol
#

Ok I was able to get a basic itanium while loop running

#

Literally no firmware

#

No bootloader

#

Just while loop

honest citrus
#

oberrow on his way to write the entire boot stack, including the firmware, up to OBOS just to flex ultrameme

dim bolt
flint idol
#

I'm using simics now

dim bolt
flint idol
#

yeah this makes no sense

#

itanium would be a lot more fun

#

if there were good emulators

#

so I might not do it

main girder
#

port OBOS to R3000 Jazz

flint idol
#

No.

main girder
#

why

flint idol
#

don't know what it is

main girder
#

32 bit mips dev board that hasnt existed since 1990

dim bolt
main girder
main girder
#

it could also boot OBOS.

upper tulip
upper tulip
main girder
#

by like 2x

#

but if u did mips youd probably want to do it on something that exists physically outside of a museum

flint idol
#

since Itanium is proving to be difficult

#

I will port to something else

#

stay tuned™️

dim bolt
upper tulip
honest citrus
#

fall back to the 2nd closest option in the polls, PPC :)

real pecan
devout niche
#

No one really knows about it besides a few devotees

upper tulip
upper tulip
short mortar
#

You can run PPC port on game consoles and old Macs ultrameme

short mortar
#

There are newer ones

#

(I have many)

upper tulip
short mortar
#

Yeah, 2MB flash and 16MB RAM

upper tulip
#

Plenty of room meme

short mortar
#

But even openwrt requires 64 now

#

(I wanted to do powerpc power meme)

upper tulip
short mortar
#

There are a lot of weird arches in routers

upper tulip
ornate ginkgo
#

now that would be an interesting port

short mortar
#

(I have both)

short mortar
#

But Wii U is ultrameme

#

And very cursed

#

(also, there is a normal Wii)

white mulch
#

or ps2 with mips64 KEKW

short mortar
#

@upper tulip how is your bootloader doing?

upper tulip
honest citrus
#

I'm also in close contact with the dev of linux-wiiu

#

porting to either one would be hilarious, and you have the ultimate advantage in doing so

short mortar
#

pmOS should be portable, but I don't want to figure out how to boot on it

#

(sorry for wrong thread)

flint idol
#

N

#

p

barren merlin
#

d

flint idol
#

I'm going to keep the platform I'm porting to a secret

#

Only posting screenshots occasionally

#

Won't push anything to GitHub either

#

I will have a local git server just in case™️

white mulch
#

I should also port my kernel to something, though I am still in the middle of deciding what I want to do about things like gpu drivers (I could possibly manage to nih intel fully including accel render stuff but some other gpus like nvidia are very much likely even bigger pain because there are no proper specs and only nouveau)

#

its why I have been mostly working on the separate nt thing for now

honest citrus
#

imagine oberrow ports to the Xbox 360 (the 5 people with modded consoles can run it)

real pecan
#

ps4 port

short mortar
#

X86 that's not a PC

timid elk
#

port it to the lego ev3

short mortar
#

so ppc, just as I though

flint idol
#

You'll see what it is.

#

Maybe I'll do two ports

#

(this will be a hell to maintain NGL)

short mortar
#

why

#

I have 3 ports and it's ok

flint idol
#

Idk

#

I would then have 4 ports

#

I want to be the one with the most ports on the server, that would be cool

short mortar
#

thonk then I need aarch64 urgently

#

and armv6

#

(since I have physical hardware where I can test it)

#

pmOS already supports device trees so it shouldn't be too difficult... (famous last words)

torpid wigeon
white mulch
#

I have a 32-bit arm tablet

flint idol
#

I will say one thing, I am not porting to aarch64

#

Rn

white mulch
#

but the thing is that I think 32-bit arm is pretty much annoying, especially considering that its 32-bit so using hhdm is not a good idea

flint idol
#

After these ports, I want to get mlibc running on m68k

#

For obos

#

And just a userspace in general for m68k

#

Should be fun

real pecan
#

Does obos support i686

timid elk
#

so you can port to lego ev3

short mortar
#

I mean not almost, I just want to add PAE before I merge it to main branch

white mulch
#

well actually maybe its not that annoying if you abstract hhdm away into some kind of phys mem range accessor that just uses the hhdm if its available and else temporary mapping

short mortar
#

that's exactly what I have

white mulch
#

yeah I were thinking that if you'd have to just get rid of every use of the hhdm completely and unconditionally replace them it would be annoying and would cause unnecessary mapping on arches where you can have a hhdm

#

maybe I should try to do a 32-bit port too

short mortar
#

Wouldn't compilers optimize it to the same code if you have HHDM anyway?

white mulch
#

with the phys mem range accessor using hhdm if its available yeah, that was an unrelated though that I had before I realized that

#

like if you'd get rid of the hhdm on all arches

short mortar
#

I didn't have it in the first place

flint idol
timid elk
#

does obos support lego ev3

real pecan
#

unbased

timid elk
#

i am in need of a hybrid kernel with advanced driver loading for my lego ev3

uncut narwhal
#

while at it can we get lego nxt support? I need a new kernel for mine

#

lmao

flint idol
short mortar
#

Does it have MMU?

devout niche
#

concerning ports

#

i have no objection to a powerpc port of OBOS

timid elk
#

and there's a debian based distro ev3dev that runs a closer-to-mainline kernel

#

NXT is sadly a microcontroller

#

spike is also a microcontroller

#

lego ev3 is so funn

#

like the dpad lights are controllable with sysfs

#

and you can play doom on it. with sound

#

it has audio, monochrome LCD, a dpad, a host USB port (with an official wifi dongle but in ev3dev you can use any wifi dongle or ethernet adapter or flash drive or keyboard or mouse), bluetooth, a micro usb port that you can use for usb tethering to get internet through a laptop

#

and most importantly it has lego mindstorms connectors for sensors and motors

#

so you can make a robot that passes you butter

flint idol
#

Found OBOS while watching football clips

flint idol
#

I got logging to work

#

on the mysterious target

short mortar
#

i686, I see

flint idol
#

no

#

it is 32-bit though

short mortar
#

thonk powerpc instructions are 4 bytes long...

flint idol
#

it's a mystery platform

short mortar
#

and mips

#

I need to see more stack traces

flint idol
#

anyway I need to get an IRQ controller working on this

short mortar
flint idol
#

IRQL might be annoying to get working

#

PPC is after this port.

#

probably

timid elk
flint idol
timid elk
#

no it's arm version 5 with thumb and jazelle

weak kestrel
honest citrus
#

which version(s) of PPC do you plan to target

#

ppc64le? ppc64be? ppc32be?

short mortar
#

why not all?

real pecan
#

ppc128

#

in middle endian mode

timid elk
#

MIDDLE ENDIAN

#

middle eastern mode

#

ppc64me, middle eastern mode

honest citrus
#

hype overload

flint idol
#

I got the IRQ controller working probably

#

time to get scheduling working

honest citrus
#

I really wonder what platform this could be

flint idol
#

I can't tell if you're being sarcastic or not

honest citrus
#

so many options

#

there's tons of 32-bit architectures lmfao

#

you could literally be doing anything

#

ARM, MIPS, SPARC, RISC-V, etc

#

since it's not i686, or 32-bit ppc

#

but there's still tons

flint idol
#

I'll tell you guys soon

timid elk
#

it's r3000 jazz

#

or lego ev3

flint idol
#

I got thread context switching done

flint idol
#

turns out I overflow the goddamned stack

#

I'm going to get MMU code in now

#

I fucking hate 32-bit address spaces

#

I will identity map 0x1000-0xc0000000

#

then any physical pages > 0xc0000000 will be mapped at a fixed address

#

this fixed address will be protected by a spinlock, and should only be accessed at IRQL_MASKED

#

you might be like "but but identity map bad angr "

#

I don't care.

short mortar
#

are you not planning on having userspace?

flint idol
#

KPTI

short mortar
flint idol
#

only minimal kernel pages will be mapped in user contexts

#

like I do on x86-64

short mortar
#

how do you copy things from user? Onto stack?

flint idol
short mortar
#

Isn't it kinda very slow?

flint idol
#

for large IO, I use a separate function

#
// Maps user pages into the kernel address space. This can be used in syscalls to avoid copying large amounts of memory.
// returns OBOS_STATUS_PAGE_FAULT when a portion of the user memory requested is not mapped.
// NOTE: The returned address is not aligned down to the page size.
OBOS_EXPORT void* Mm_MapViewOfUserMemory(context* const user_context, void* ubase, void* kbase, size_t nBytes, prot_flags protection, bool respectUserProtection, obos_status* status);
flint idol
#

I refuse to elaborate.

sweet compass
#

this is how I do it:

        .globl __memcpy_from_userspace
        .type __memcpy_from_userspace, @function
__memcpy_from_userspace:
        .cfi_startproc
        jmp usercopy_common
        .cfi_endproc
        .size __memcpy_from_userspace, . - __memcpy_from_userspace

        .globl __memcpy_to_userspace
        .type __memcpy_to_userspace, @function
__memcpy_to_userspace:
        .cfi_startproc
        jmp usercopy_common
        .cfi_endproc
        .size __memcpy_to_userspace, . - __memcpy_to_userspace

        .globl __usercopy_pagefault_address

        .type usercopy_common, @function
usercopy_common:
        .cfi_startproc
        xorq %rax, %rax
        movq %rdx, %rcx
__usercopy_pagefault_address:
        rep movsb
        ret
        .cfi_endproc
        .size usercopy_common, . - usercopy_common

        .globl __usercopy_fixup_address
        .type __usercopy_fixup_address, @function
__usercopy_fixup_address:
        .cfi_startproc
        movl $EFAULT, %eax
        ret
        .cfi_endproc
        .size __usercopy_fixup_address, . - __usercopy_fixup_address

        .globl __userstrcpy_pagefault_address

        .globl __strncpy_from_userspace
        .type __strncpy_from_userspace, @function
__strncpy_from_userspace:
        .cfi_startproc

1:
__userstrcpy_pagefault_address:
        lodsb (%rsi), %al
        stosb %al, (%rdi)

        testb %al, %al
        jz 1f

        decq %rdx
        jnz 1b

1:      xorq %rax, %rax
        ret

        .cfi_endproc
        .size __strncpy_from_userspace, . - __strncpy_from_userspace
haughty abyss
#

holy shit what

flint idol
#

that's cool and all

sweet compass
#

basically it's just memcpy but with special handling for page faults

flint idol
#

but I'm playing minecraft

haughty abyss
#

this is probably like 3 lines of asm total

sweet compass
#

and 50 lines of GCC black magic

haughty abyss
#

also

haughty abyss
#

imagine having strcpy from userspace

#

so cringe

torpid wigeon
#

free cve spawner

haughty abyss
#

theres literally no reason to have it

#

just get a size

#

and copy that amount of bytes

sweet compass
#

but yeah

#

I agree, somewhat

haughty abyss
#

easy

sweet compass
#

explicitly sized buffers are better

haughty abyss
#

all you need is copyin and copyout

#

and the only thing they differ in is the direction

#

and they can share an extable entry

#

or whatever you use as an equivalent

#

they can share a page fault recovery location thingy

sweet compass
# torpid wigeon wtf

oh... you haven't seen my pagefault handler

static pagefault_status_t
handle_pagefault_in_vm (unsigned long addr, unsigned int error_code)
{
        struct pagefault_info fault;
        fault.addr = addr;
        fault.access_write = (error_code & PF_WR) ? 1 : 0;
        fault.access_exec = (error_code & PF_ID) ? 1 : 0;

        irq_enable ();
        pagefault_status_t status = vm_handle_pagefault (&fault);
        irq_disable ();
        return status;
}

extern char __usercopy_pagefault_address[];
extern char __userstrcpy_pagefault_address[];
extern char __usercopy_fixup_address[];

static inline bool
is_usercopy_addr (void *rip)
{
        return rip == __usercopy_pagefault_address
                        || rip == __userstrcpy_pagefault_address;
}

static bool
handle_usercopy_fault (unsigned long addr, struct entry_regs *regs)
{
        if (usercopy_ok ((void *) addr, 1) != ESUCCESS)
                return false;
        if (regs->error_code & PF_ID)
                return false;

        if (handle_pagefault_in_vm (addr, regs->error_code) != FAULT_HANDLED)
                regs->rip = (unsigned long) __usercopy_fixup_address;
        return true;
}

void
handle_PF_exception_k (struct entry_regs *regs)
{
        unsigned long addr = read_cr2 ();
        note_pagefault (addr, regs->error_code);
        if (is_usercopy_addr ((void *) regs->rip)) {
                if (handle_usercopy_fault (addr, regs))
                        return;
        }
        panic ("x86: Page Fault in kernelspace!  (rip=0x%lx  ss:rsp=%lu:0x%lx)",
                regs->rip, regs->ss, regs->rsp);
}
flint idol
#

that's the entire thing?

sweet compass
#

no. but that's the part that dispatches faults to vm

#

and changes the return rip to the fixup addr

haughty abyss
#

lol linux is like 10x more

sweet compass
flint idol
main girder
sweet compass
flint idol
#

lol (uh oh)

#

I'll fix it eventually

main girder
#

It is broken in numerous ways

flint idol
#

ye

#

also I

haughty abyss
#

btw

flint idol
#

am playing minecraft

#

so talk to you later ig

haughty abyss
#

in two different ways!

flint idol
#

is that not guaranteed to be read-modify-write?

haughty abyss
#

first, no

#

and gcc WILL hunt you down

#

also it will emit a single or instruction

#

which may or may not work

sweet compass
#

OBOS kernel pwn as a CTF challenge when?

flint idol
haughty abyss
#

also a valid way to lower that loop is c if (!(HBA->ghc & BIT(31))) { while (1) { HBA->ghc; OBOSS_SpinlockHint(); } }

sweet compass
flint idol
#

I had thought about rewriting this kernel a few times, but never said anything about it

weary hound
sweet compass
weary hound
#

iirc linux limits it to PATH_MAX for fs stuff

flint idol
sweet compass
# weary hound iirc linux limits it to PATH_MAX for fs stuff

this is what I do:

static errno_t
get_path_from_userspace (char *kbuf, const char *user)
{
        kbuf[PATH_MAX - 1] = 0;
        errno_t e = strncpy_from_userspace (kbuf, user, PATH_MAX + 1);
        if (e == ESUCCESS && kbuf[PATH_MAX - 1])
                e = ENAMETOOLONG;
        return e;
}
#

and callers of this function:

SYSCALL6 (void, stat, struct stat *, buf, size_t, buf_size, const char *, path,
                int, dirfd, struct pathwalk_info *, info, size_t, info_size)
{
        char kpath[PATH_MAX];
        struct stat kstat;
        struct pathwalk_info kpathwalk_info;

        if (info_size > sizeof (kpathwalk_info))
                syscall_return_error (E2BIG);

        memset (&kpathwalk_info, 0, sizeof (kpathwalk_info));
        errno_t e = ESUCCESS;
        if (info_size)
                e = memcpy_from_userspace (&kpathwalk_info, info, info_size);
        if (e != ESUCCESS)
                syscall_return_error (e);

// ...
haughty abyss
weary hound
haughty abyss
#

because of the same "volatile is stupid and bad" rpoblem

sweet compass
#

(aka static struct pci_driver driver = { ... }; register_pci_driver (&driver);)

flint idol
#

no(t yet)

white mulch
# sweet compass obviously lol.

I don't have any limits for userspace buffers in my kernel troll you can literally cause an oom just by using some syscall like syslog that takes in a pointer + length and if you give a bogus large length and a nullptr the kernel is going to die (or more like the specific cpu core is going to die, the others might still function depending on how the locking works, idr if I keep the alloc lock in the fail case)

short mortar
#

(except that it gets back to the same context, and handles pagefaults from there ultrameme)

flint idol
haughty abyss
#

the loop one

flint idol
#

bruh

#

now if only I remembered what bit 31 did

#

ah yes that makes sense now

sweet compass
#

I can recommend watching (and rewatching) the many cppcon talks about atomics recorded and posted on youtube.

haughty abyss
#

volatile is stupid and bad

#

or the idea is okay

haughty abyss
#

but the semantics are stupid and bad

white mulch
#

it should really be a property of the read/write and not the pointer

haughty abyss
#

the real fun problem is that a volatile store doesnt place any ordering constraints

#

on anything

#

so like. the compiler can just remove stores you make

sweet compass
#

tbh _Atomic is also stupid and bad (albeit in less ways than volatile)

white mulch
#

because like that would very likely break linux

haughty abyss
#

but yeah it can reorder nonvolatile stores past volatile ones

#

volatile stores dont impose ANY ordering constraints

sweet compass
#

(but that doesn't help much)

haughty abyss
#

do they

#

yeah probably

white mulch
#

hopefully

haughty abyss
#

but the value a load loads is not an input to the AM

#

only that a load occured

#

btw the rust people have come up with a """"""""fix""""""""" for this problem

#

get ready

#

volatile atomics!

#

please dont think about it

white mulch
#

atomics on hw regs 💀 (that's not even really allowed)

haughty abyss
#

sanity is optional in rust land

haughty abyss
#

idk i think its for like some handoff stuff

white mulch
#

it doesn't really matter, the pointer is volatile its going to be just fine

haughty abyss
white mulch
#

you have to accept the ub

haughty abyss
#

no you dont

#

you can read and write in asm

flint idol
#
#pragma GCC optimize("-O0")```
haughty abyss
#

lol

flint idol
sweet compass
#

it'd be very bad if the compiler could transform something like:

*(volatile uint32_t *) (base + IOREGSEL) = 0x22;
*(volatile uint32_t *) (base + IOWIN) = 0x00000040;

into

*(volatile uint32_t *) (base + IOWIN) = 0x00000040;
*(volatile uint32_t *) (base + IOREGSEL) = 0x22;

suddenly you're writing bogus into a bogus register in the IOAPIC

haughty abyss
#

which solves this issue

white mulch
#

I mean yeah but like still, at some point you just accept the ub

haughty abyss
#

nahhh you dont you can write UB-free os code

white mulch
#

its not really necessary tho

haughty abyss
#

lets maybe start with not including data races :^)

sweet compass
#

there's no UB in asm galaxybrain

haughty abyss
#

compiler go brrr

timid elk
haughty abyss
#

please dont think about how this sort of reordering is insanely cringe and stupid

#

and also these semantics make no sense

flint idol
#

so having macros like:

#define MMIO_WRITE1(addr, x)
#define MMIO_READ1(addr)```
sweet compass
flint idol
#

iirc linux does something like that

timid elk
haughty abyss
#

i have ```c
#if defined (aarch64)

#define arm64
#define arch_uses_fdt
#define arch_little_endian
#define arch_asm_read8 "ldrb %w[value], [%[address]]"
#define arch_asm_read16 "ldrh %w[value], [%[address]]"
#define arch_asm_read32 "ldr %w[value], [%[address]]"
#define arch_asm_read64 "ldr %[value], [%[address]]"

#define arch_asm_write8 "strb %w[value], [%[address]]"
#define arch_asm_write16 "strh %w[value], [%[address]]"
#define arch_asm_write32 "str %w[value], [%[address]]"
#define arch_asm_write64 "str %[value], [%[address]]"

#elif defined (riscv64)

#define rv64
#define arch_uses_fdt
#define arch_little_endian
#error TODO: riscv arch_asm_*

#else
#error unknown platform!
#endif

#define rmw_func(size, typ)
static inline typ read##size(usize address) {
typ value;
asm volatile(arch_asm_read##size : [value] "=r" (value) : [address] "r"(address) : "memory");
return value;
}
static inline void write##size(usize address, typ value) {
asm volatile(arch_asm_write##size :: [value] "r" (value), [address] "r"(address) : "memory");
}
static inline void set##size(usize address, typ value) {
write##size(address, read##size(address) | value);
}
static inline void clear##size(usize address, typ value) {
write##size(address, read##size(address) & ~value);
}
static inline void mask##size(usize address, typ clear, typ set) {
write##size(address, (read##size(address) & ~clear) | set);
}
static inline typ writeread##size(usize address, typ value) {
write##size(address, value);
return read##size(address);
} \

rmw_func(8, u8)
rmw_func(16, u16)
rmw_func(32, u32)
rmw_func(64, u64)

real pecan
haughty abyss
#

but thats the same thing basically

timid elk
#

also allows you to translate between archs

#

m68k asm compiled to riscv

haughty abyss
real pecan
#

can be derived from just u##size

haughty abyss
#

oh yes

#

that is true

#

doesnt matter tho

sweet compass
#

imo the only sane way to deal with volatile/atomics is to have

  • a library of things used commonly, eg. nmi-safe atomic list, spinlock, mutex, rwmutex, semaphore, atomic refcount
  • some helper functions for hardware register bitbashing
    and then only use those.
main girder
# real pecan how

Toctou on the page access checks, and the accesses to the cpu local data are racy

haughty abyss
sweet compass
haughty abyss
timid elk
haughty abyss
timid elk
#

ah

#

it's ok then

#

tbh that shouldn't be an arch thing, I could boot x86 with FDT if I really wanted to

#

it's more like, default to compiling FDT support for this arch right?

haughty abyss
#

no

#

its more like

#

"compile in fdt shit"

#

right now i have one platform (arm64 with linux boot) and that has FDT always anyway

#

ill fix it later tho

#

maybe

#

or maybe not

timid elk
#

opinion: keep build configuration out of headers, even a Kconfig like linux or uboot would be fine

timid elk
haughty abyss
timid elk
#

at least the raspberry pi 5 edk2 port mentions it

flint idol
#

I think I will pause porting for a bit

timid elk
haughty abyss
#

yeah

#

you cant not

timid elk
#

cool

#

is it like, almost empty

haughty abyss
#

yeah

flint idol
#

to fix this MMIO read/write "problem" thing

timid elk
#

or is it anything useful

white mulch
# white mulch I have this <:meme:575445094589661215>

I actually like this (credit for idea goes to managarm), you have register/bitfield types ```cpp
namespace regs {
constexpr BitRegister<u64> GCIDR {0};
constexpr BitRegister<u64> GCR {0x10};
constexpr BasicRegister<u64> MCVR {0xF0};
}

namespace gcidr {
// bitfield of u32 type in bits 32..64 on an u64
constexpr BitField<u64, u32> COUNTER_CLK_PERIOD {32, 32};
}

void hpet_init() {
auto fs_in_tick = SPACE.load(regs::GCIDR) & gcidr::COUNTER_CLK_PERIOD;
auto ns_in_tick = fs_in_tick / 1000000;
auto ticks_in_s = NS_IN_US * US_IN_S / ns_in_tick;
}

timid elk
#

does it like

haughty abyss
timid elk
#

that's how I would have done it

haughty abyss
#

pretty much

#

yeah

timid elk
#

pass RSDP in FDT

#

ah

haughty abyss
white mulch
#

no its not

#

its nice

haughty abyss
#

did you copy it from managarm?

white mulch
#

then you don't have to think about shifts/masks

#

yes

haughty abyss
#

i see i see

white mulch
#

or well not copy but the idea is from there

haughty abyss
#

clearly copied :^)

white mulch
#

I also included it in uhda

haughty abyss
#

uhda is C++?

white mulch
#

yes

haughty abyss
#

hmm actually this is an interesting question

#

can i complain to infy about UB

#

ah no

#

i cant

#

its implementer ub

white mulch
#

actually the uhda impl does volatile loads/stores with an added launder

#

not the arch specific asm that I have in that other copy of it

white mulch
#

as long as it works 🤷

#

though ig I might consider adding the asm impl but that would be the only arch-specific part in there

flint idol
#
#if defined(__x86_64__) || defined(__i686__)
#   define MMIO_WRITE1(addr, x) do { asm volatile("movb %1, (%0);" : :"r"(addr), "r"(x) :"memory"); } while(0)
#   define MMIO_WRITE2(addr, x) do { asm volatile("movw %1, (%0);" : :"r"(addr), "r"(x) :"memory"); } while(0)
#   define MMIO_WRITE4(addr, x) do { asm volatile("movd %1, (%0);" : :"r"(addr), "r"(x) :"memory"); } while(0)
#   define MMIO_READ1(addr) ({ uint8_t x = 0; asm volatile("movb (%0), %1;" :"=r"(x) :"r"(addr) :"memory"); (x); })
#   define MMIO_READ2(addr) ({ uint16_t x = 0; asm volatile("movw (%0), %1;" :"=r"(x) :"r"(addr) :"memory"); (x); })
#   define MMIO_READ4(addr) ({ uint32_t x = 0; asm volatile("movd (%0), %1;" :"=r"(x) :"r"(addr) :"memory"); (x); })
#elif defined(__m68k__)
#   define MMIO_WRITE1(addr, x) do { asm volatile("move.b %1, (%0);" : :"r"(addr), "r"(x) :"memory"); } while(0)
#   define MMIO_WRITE2(addr, x) do { asm volatile("move.w %1, (%0);" : :"r"(addr), "r"(x) :"memory"); } while(0)
#   define MMIO_WRITE4(addr, x) do { asm volatile("move.d %1, (%0);" : :"r"(addr), "r"(x) :"memory"); } while(0)
#   define MMIO_READ1(addr) ({ uint8_t x = 0; asm volatile("move.b (%0), %1;" :"=r"(x) :"r"(addr) :"memory"); (x); })
#   define MMIO_READ2(addr) ({ uint16_t x = 0; asm volatile("move.w (%0), %1;" :"=r"(x) :"r"(addr) :"memory"); (x); })
#   define MMIO_READ4(addr) ({ uint32_t x = 0; asm volatile("move.d (%0), %1;" :"=r"(x) :"r"(addr) :"memory"); (x); })
#else
#   error Define for your architecture!
#endif```
#

ok just did this

#

time to use them

#

for MMIO

#

ig

#

before that, I will add:

// thanks a lot for this, pitust.```
haughty abyss
#

lmao

#

you're welcome

real pecan
haughty abyss
#

nah i was wondering if uacpi has UB

#

but no

real pecan
#

somethign specific?

haughty abyss
#

yes

#

volatile is basically always UB

real pecan
#

i use volatile in like one place, just to prevent reorders iirc

haughty abyss
#

not sure if thats enough

#

you should use atomics

real pecan
#

probably

haughty abyss
#

definitely

real pecan
#

its followed by an atomic cmpxchg on the same memory location

haughty abyss
#

is it to prevent cross-thread reorders?

real pecan
#

so its enough

haughty abyss
#

so what is it for then?

#

for peripherals?

real pecan
#

its the firmware global lock

haughty abyss
#

ah

#

yeah no thats UB

real pecan
#

i load it and then cmpxchg

haughty abyss
#

its a data race

real pecan
#

cmpxchg is atomic tho

haughty abyss
#

but the volatile load is not

#

data race, straight to UB land

real pecan
#

bruh

haughty abyss
#
uacpi_status uacpi_system_memory_read(void *ptr, uacpi_u8 width, uacpi_u64 *out)
{
    switch (width) {
    case 1:
        *out = *(volatile uacpi_u8*)ptr;
        break;
    case 2:
        *out = *(volatile uacpi_u16*)ptr;
        break;
    case 4:
        *out = *(volatile uacpi_u32*)ptr;
        break;
    case 8:
        *out = *(volatile uacpi_u64*)ptr;
        break;
    default:
        return UACPI_STATUS_INVALID_ARGUMENT;
    }

    return UACPI_STATUS_OK;
}
``` this is UB too
#

or at least

real pecan
#

on paper yes probably

flint idol
trim bay
#

using a relaxed atomic load would compile to the same thing and not be ub

haughty abyss
#

actually no

#

infy's usage is real UB

real pecan
#

what

haughty abyss
#

the obos one is stretching semantics

#

this is straight UB that can blow your arm off

uncut narwhal
haughty abyss
#

idk

real pecan
#

the compiler doesnt know anything

haughty abyss
#

probably not

uncut narwhal
#

oh wait thats the internal one my bad

#

im so used to seeing that pattern in the old kernel raw one lol

real pecan
#

the write is behind a mutex from

#

a different place

flint idol
#

wait infy removed uacpi_kernel_raw_memory_*

#

???

sweet compass
real pecan
#

like a month ago

haughty abyss
uncut narwhal
#

yeah that was a while ago lmao

haughty abyss
#

but its probably exposed to aml

#

and so ub

flint idol
haughty abyss
#

:^)

#

though admittedly

#

this wont break

real pecan
#

it points to stuff returned via kernel_memory_map

sweet compass
#

it's only as UB as the firmware devs are braindead

uncut narwhal
#

it just always does map -> normal vmem access -> unmap now

haughty abyss
sweet compass
#

:p

real pecan
#

use SystemIO exclusively to be safe meme

uncut narwhal
#

lmao

haughty abyss
#

a relaxed atomic load is fine here

real pecan
#

id need a relaxed atomic load

haughty abyss
#

yes

#

which is free

real pecan
#

which on x86 is the same

haughty abyss
#

and on arm

#

and riscv

#

lol

real pecan
#

arm and risc-v are hw reduced acpi anyway

#

they dont have a global lock

haughty abyss
#

ah yeah

#

please dont use volatile

#

especially here

real pecan
#

here being?

haughty abyss
#

the global lock one

real pecan
#

ah

#

yeah

haughty abyss
#

those loads and stores are UB too though

trim bay
# haughty abyss also a valid way to lower that loop is ```c if (!(HBA->ghc & BIT(31))) { while (...

I don't think this is true?

An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore, any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.4
I interpret this as saying that the compiler cannot assume that the value hasn't changed between the two condition checks

real pecan
haughty abyss
#

hmmmmmmmmmm

#

interestingggg

real pecan
#

they refer to stuff mapped via kernel_map, which, as long as AML is correct stores this exact type it puns into

trim bay
#

it's more so that the compiler is allowed to use any instruction it wants to effect the reads/writes, as well as being allowed to split said reads and writes

#

that's problematic because some instructions are not allowed to be used for MMIO

#

for example, a while ago I got bitten by clang trying to use some bit manipulation extension for setting the ioapic registers

real pecan
#

lol

#

what im gonna do for mmio is have optional read_memory/write_memory kernel hooks that operate on virtual addresses

#

to combat that

trim bay
#

sounds like a good idea

haughty abyss
#

can you reproduce?

#

or was it a normal read/write and not a volatile one?

trim bay
#

this was like >1 month ago, i don't remember the commit it was on

haughty abyss
#

ah

trim bay
#

it was def volatile though

haughty abyss
#

damn i would love to see how to do that lol

#

i thought only GCC engaged in this flavor of brain damage

trim bay
#

i was using -march=native -mtune=native

#

didn't happen when targeting x86-64-v1

haughty abyss
#

yeah doesnt matter tho

#

whats your -march?

trim bay
#

znver3

haughty abyss
#

ah

#

oh yeah!

#

damn

#

ah

#

clang enjoys this flavor of brain damage too TIL

#

ah maybe its GCC that didnt? idk

#

either way good to know

trim bay
#

managed to repro it on the last commit before i switched to inline asm mmio

#

doesn't happen with gcc

#

the offending instruction is bextrl %eax, 0x10(%r12, %rbx), %edx

haughty abyss
#

ah yeah

#

i can get it to produce a normal or lmao

#

basically the TLDR is

#

you cannot, ever, use volatile for MMIO

#

because it straight up produces broken code

trim bay
#

yep

trim bay
#

and rbx is 0

haughty abyss
#

thats only broken on qemu right?

trim bay
# trim bay yep

unless the "mmio" is really just a different kind of ram, e.g. when writing to a framebuffer

trim bay
#

but i would assume that on actual cpus the instruction doing the mmio doesn't matter

#

then again on amd cpus you're only allowed to interface with ecam if you use mov to/from eax so what do i know

haughty abyss
#

WTF

#

cursed

trim bay
#

it's not actually enforced, doing it with some other register works fine on modern cpus

haughty abyss
#

ahhh

#

okay

trim bay
#

but it's in the bios and kernel developer's guide

haughty abyss
#

lmfao

trim bay
#

so it presumably was necessary on some previous generation

short mortar
flint idol
#

To confuse

#

people who are new to system dev

haughty abyss
#

pretty much tbh

real pecan
#

preventing compiler from assuming the value, preventing reordering

haughty abyss
#

the latter, no

#

you arent preventing reordering anyway

real pecan
#

reordering with other code, yes

#

at least at code gen level

haughty abyss
#

which you cant observe anyway

real pecan
#

yes

haughty abyss
#

and also it doesnt prevent it i think

real pecan
haughty abyss
#

idk maybe it does?

real pecan
#

it does

#

linux abuses it for READ_ONCE/WRITE_ONCE

haughty abyss
real pecan
#
/*
 * Prevent the compiler from merging or refetching reads or writes. The
 * compiler is also forbidden from reordering successive instances of
 * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some
 * particular ordering. One way to make the compiler aware of ordering is to
 * put the two invocations of READ_ONCE or WRITE_ONCE in different C
 * statements.
 *
 * These two macros will also work on aggregate data types like structs or
 * unions.
 *
 * Their two major use cases are: (1) Mediating communication between
 * process-level code and irq/NMI handlers, all running on the same CPU,
 * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
 * mutilate accesses that either do not require ordering or that interact
 * with an explicit memory barrier or atomic instruction that provides the
 * required ordering.
 */
haughty abyss
#

the "strong prevailing wind" comment does NOT inspire confidence

#

i also would call it blatant UB

real pecan
#

how is it ub lol

haughty abyss
#

it isnt preventing refetching

#

afaik

#

it can also produce torn writes without causing UB

#

actually it can produce a lot of things

real pecan
#

yeah idk

haughty abyss
#

its blatant UB reliance

real pecan
#

language lawyering stuff can be counter productive

haughty abyss
#

true

#

in this case the correct thing is an atomic

#

or an assembly load

#

but anyway the point is you cant use it to stop reordering cross-cpu

#

because that requires actual barriers

real pecan
#

i mean yeah

haughty abyss
#

and it doesnt stop reordering vs literally any other memory op you make

real pecan
#

thats not its purpose tho

haughty abyss
#

to do THAT you need a c11 signal fence

#

like yeah i know its stupid and rather lawyery but unfortunately that is the spec

#

and in practice the compiler can do many very bad things with volatile that preclude it being used for mmio anyway

flint idol
#

was investigating a crash in obos-strap
only for it to be in cJSON

#

at first I thought I passed something invalid to the function

#

like nullptr or smth

#

No.

devout niche
#

i like those managarm bit field things

#

it shows off C++'s merit as a systems language

flint idol
#

Ngl I feel like making a new obos rewrite along this one

#

Like I work on both

#

Like some sort of OBOS2

zinc root
#

why not just make this current version OBOS 1.x.x and make the rewrite OBOS 2.x.x

main girder
#

i copyrighted the number 2

#

unfortunately

flint idol
#

What will I ever do now

zinc root
flint idol
#

Because I would want to make a separate repo for the rewrite

#

This rewrite got a bit far in userspace, but the kernel is kind of not amazing

#

The memory manager is my biggest concern really

#

Also when I designed the driver interface, for example, I designed it not amazingly

#

Not to mention all IO is done synchronously

devout niche
devout niche
#

i started a sort of keyronex rewrite but now i'm folding in as much of what i worked on there back into keyronex

real pecan
flint idol
#

Also I kinda hate the naming convention lol

devout niche
#

as while current keyronex is messy in many areas and there are new ways of doing things i want to introduce, there is no call for a blanket throwing out of everything

flint idol
#

It might not happen

real pecan
#

what would u change

flint idol
#

Driver interface is a big one

#

And VFS

#

The VMM isn't amazing rn

lean glen
#

do like gaia2

#

start a rewrite

#

and don't work on it

flint idol
#

lol

lean glen
#

doesnt help that i started the project just when classes started

flint idol
#

And when did you start it lol

lean glen
#

like a month ago at this point lol

#

and it's still basically a limine hello world + kernel debugger

flint idol
lean glen
#

at least I'm doing somewhat productive stuff in my free time so