#EvalynOS
1 messages ¡ Page 3 of 1
yeah yeah
How did this not break đ
i have 0 clue LMAO
do u have commands like hexdump and stuff so we can try breaking it :))
In my kernel or my system
Sadly no
i should be able to make this take arguments when starting the thread right?
i am not entirely sure
or i can have some external vars you fill in and then start it
and then mutex it so it can only be changed once its consuimed it
i do it with the other vars
i could have args there
and then have a var that gets written to once its safe to start another thread and change thoes args
And if itâs not ready spin because it wonât take that long
Like fuckin maybe 500 cycles of spinning at worst
xD
Can always make it a hlt spin anyways
Maybe
May not even need any locking if itâs sequential too
No no it is a thread
Ehhh whatever
I mean whatâs a better solution
I have to pass data from one thread to another
doin tis is better
And a shared varrible with a spin lock is quick and dirty especially for somthing like this
True true
But it also makes me get infra for mutexes and other things
Which is good
And itâs not the most cursed thing
Because I have to manually craft the stack
So args might be a pita
pita?
Pain in the ass
XD
yeah
o h
Yeah đ
Thatâs how making the thread works
and all user threads are kernel threads in a trenchcoat
that
is
kinda not safe
so i need a generic this with the argument of the path to load the executable
The kernel thread sets up userspace and then jumps to it for its context
And then itâs always running inside of user space
oh
See here?
I can probslt strip run once with a infinite loop or having it signal to free itself
Wait is there a way to make a new instance of a static function to call?
Because I donât think freeing would work with this if the thread itâs self donât know which thread it is
hmmmmmmmmmmmmmmm
@devout path maybe I can pass a pointer to it that has a structure of all the data it needs?
But how do I construct the stack for that
Wouldnât that be a register argument in SYS-V too?
Which I have to put into the right thing on the stack
Because the zeros I set I think are the registers
this should be the stuff popped off the stack into registers
for (int i = 0; i < 15; i++) {
*--stack = 0x0 + i;
}
so i could slide a pointer into here
u don't need an instance btw, they share em right?
every thread needs some seperate context right
yes yes
hmm i think you dont needa craft a stack manually...
yeah actually
yes. this is what tells the CPU how to jump to userspace
it uses the crafted stack to jump to the entry point
like u can use kmalloc containing the args, pass the pointer there and the thread reads the data?
in theory should work? not as messy
yup and then the kernel part of the thread would use that
yes
oooh
the GPRs and RFLAGS
So I should just be able to slide in that sneaky pointer to pass in the function
is using xchg possible for context switches?
yeah and wat if you craft the initial stack of your new thread so it looks like it paused inside da thread switch
Just put in in RDI I assume
What
would u like me to explain it in tech jargon or in simple terms
can i use xchg?
The stack is useful here no?
I mean what pausing?
yea its pretty useful after i read your code, the only risk is bad code which causes a program to use a ton of stack which means if the memory below the stack is not mapped you get a #PF when switching threads
wat reference are u using?
Wikipedia
so ig its better to map memory below the stack, maybe
the pros of using the stack method is that i only need to store rsp in a program's PCB
so uuh u wanna switch thread a to thread b right? u can pause the stack by doin mov [rdi], rsp
Guard pages are pretty important too so that can be used in combination
as you've mentione here
I mean when crafting the stack
Where RDI should be in the push and pops
I put in that pointer instead of a 0
So you would have memory that the kernel can use but the user program would PF right below the stack if it were to overflow
And then you can detect that
huh im confused a little ;-;
i don't have much context
wait gimme a moment to read
Iâm confused too?
These represent registers
I set them to 0
So when I execute ret it fills the registers properly right
If I make the one that equals RDI to the pointer
According to the sysV abi
Thatâs the first argument
Which means when it starts up and that gets pushed into the stack it should be given to the kernel thread
Let me do a demo
i will make them all 1s
and it wont crash
gimme a moment to reread this LMAO
yep
this is exactly what i was thinking
man i swear
what the fuck
aight my badlmao
uuuuuuuuh
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuh
wdym?
every register should be becoming that value
LMAO
leme do a panic for a register dump
wait what value exactly?
like the value itself when you set it?
the value i set on the stack
oh
my reg dump may not be accurate 
heh
later 
because i aint either rn
i have a headache
wat
do you see it
was it about hte rdi
that was a reminant of debugging ages ago
heh xd
I stg these kinds of mistake are so common in programming đ
@devout path it diddnt send this here
But we are all good
noice
Now I can malloc a structure and get it passed in there
yeaaaaaaaaaah
And then it can operate on that to know how to do things
Like telling the scheduler to end its self
heh
Or even then pass this on to userspace for a sub set of things
But the system call handler can probslt check the current thread
So that wonât need this
yeaah
LMAO
ngl
for some weird reason
i love programming on crt monitors more than my oled screens
oh damn
@devout path
WAT DA HEEELL
Iâd maybe pickup a decent 75hz bussness IPS display for coding?
i THOUGHT I NEED GLASSES BUT THAT'S JUST BAD LMAO
And keep the oled for gaming
yeaah
Itâs what like 100 200 bucks for a decent one?
yup
Cheaper than glasses 
actually glasses here are cheaper LMAO
LMAO
imma just add my old crt monitor on my desk atp
I really wana get a CRT to play deltarune
The game is a pixel art RPG and itâs 4:3
u can get one for idk 20 dollars secondhand online XD
And Iâve seen videos of it played on CRT and holy shit itâs good
Yeh yeh
Yet my friends would still clown on me for emulation and not using a regular controller 
I want that steam controller
Looks so nice for pc gaming
its like a steamdeck without the screen
@devout path it seems to crash when running both at once
its triggering a page fault
if they run alone thry work though
If I run mandelbrot first
And then bad apple
Bad Apple wonât execute
But mandelbrot restarts
Well I managed to fix some other things
They both now âproperlyâ fault when executing them because a bad variable name
And I got AVX and other things working to accelerate the code
For the userspace apps
Itâs fine lol
i feel like you need to add extra space between two lines because its all squished
bro cast to (uint8_t)
No I mean itâs not properly dumping registers
Itâs inaccurate
Why
i was talking in general ngl its pretty hard to read if all text is white and squished together
My registers are color coded and I can read it fine and it also dumps into the serial port on QEMU
you are writing one byte to the stack and C treats 0x1 without a cast as a normal int unless you end it with ULL or UL or something like this
how many pixels between row 0 and row 1?
Thatâs intended
I am meant to be pushing 8 byte values
They are the registers
cast to uint64_t or end with ULL
Part of building the stack
0xFULL means (uint64_t)0xF
That + i was the invalid thing too btw
Itâs meant to set them to zero
Let me read this again
The stack is cast to a uint64 already
So when I operate on it it should be 8 byte values no
the 0x1 is a debug value to set registers too
like the + i was
but if this wasnt working all threads would be fucked
not just user threads
and one user thread works
its an 8x8 font used in flanterm
its one px it seems
Why not use the default one?
Too smol
more text on screen
not for me
Do you take the screenshots with QEMU Full-screen?
an all the stuff comes on seriel
what
Ctrl+Alt+F then take a scrnshot?
or do you take it with qemu windowed?
i use my got ket win + s to take it while windowed
i know how to make it full screen but that dosnt matter?
usually qemu stretches screen when you fullscreen, idk why it doesnt update the resolution but it is what it is
because the guest os dosnt get notified
qemu resizes?
yes the qemu window gets a new resolution
but the guest os dosnt
it would have to request the new video mode
or have some kind of guest additions things
ig its usually handled with a gpu driver
even with a GPU driver it might not know etc
so its usually polled
uhuh. if i were to open a linux vm it probaly wouldnt change unless i change it in video settings
maybe it was changed
makes sense you cant stretch a monitor irl 
Look are you here to talk pedantics about font sizes and qemu screenshotting and giving bad advice about stuff when you donât have the full code context or are you here to talk about this project in a meaningful way to have it actually progress?
saying that the font is kinda unreadable if i were to use the kernel
Because I donât think this convo is going anywhere
Then? Donât use the kernel?
The font works for me
And you can easily change it in the source code if you wanted to work on it
it was just a suggestion
I can even make it a compile option for the font
-DBIGGER_FONT
I think there are bigger issues afoot than the font?
The font thatâs working
There is the case of the userspace failing spectacularly
Chill xd
what did i just come back to
I donât know XD
Anyways @devout path howâs it going
I just wrapped up one of the parts of another project while you talked here
ooh im doin alright
finals exam week so haven't been doin anythin
Ooo
noice
Honestly my os might go on hold until I can fix this 
But I am working on some cool thing for my internal services and might be good for others
Making some proofs of concept for the major 3 bits I need to mix
My threadpool works nice
And it can generate this fractal using all my cores in 12 seconds
ooh noice
i had more code after this patch i just threw out
but i found the problem
my stack pointer was being set to zero
i think i am setting up user threads poorly
i should make a better bootstrap function for them in the firstplace
that sets up a proper stack etc for userspace
@devout path i think i got this
i dont think anything is wrong with my switching logic
global thread_switch
global thread_switch_user
global switch_to_user
section .text
thread_switch:
pushfq
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push rbp
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
mov [rdi], rsp
mov rsp, rsi
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rbp
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
popfq
ret
USER_STACK_TOP equ 0x0000000080000000
switch_to_user:
mov ax, 0x33
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push 0x33
mov rax, USER_STACK_TOP
push rax
pushfq
pop rax
or rax, 0x200
push rax
push 0x2B
push 0x4000
iretq
why are you pushing all those regs?
Itâs for preemption right
I have a fixed load address in userspace for programs start function and a fixed stack address top
0x33 seems so strange there
Thatâs the RFLAGS thing needed for ring3 right?
show your gdt
my gdt is:
null
kcode
kdata
ucode32
udata
ucode64
I donât have any kind of 32 bit at all
But I have null kcode kdata tss ucode udata
Is that bad
well, you have to swap ucode and udata
shouldn't be
why
Why does ordering matter there?
it doesnt
syscall msrs
they dont use syscall
yes but its irrelevant here
This patch when applied to my repo should get you to where I am at btw
I am quite vexed
@hazy saddle maybe the missing [] here?
What does the [] even do again
i think it gets the value from the pointer
basically deref
Aswell wouldnât this brick kernel threads too
yes
thread_switch(&previous_thread->rsp, current_thread->rsp);
btw @viral bison you on my source tree from github or the patchset
yes
it gets loaded here
fs_read("/badapple.bin", (void *)0x4000, num_pages * page_size);
im gonna de hard coder it later
would be easy too
i use a somewhat custon binary format
il do static elf loading later
ENTRY(main)
SECTIONS
{
. = 0x4000;
.text :
{
KEEP(*(.entry))
*(.text)
}
.rodata :
{
*(.rodata)
}
.data :
{
*(.data)
}
}
it gets hoisted like this
its implied by my loading
when fs read is told to read more bytes than there are in the file it dumps nulls
eg 0
int main() __attribute__((section(".entry")));
int main() {
this hoists my main function to the start if the binary
gcc -ffreestanding -fPIC -nostdlib -fno-asynchronous-unwind-tables -fno-stack-protector -c badapple.c -o badapple.o
ld -nostdlib -T badapple.ld -o badapple.elf badapple.o
objcopy -O binary badapple.elf badapple.bin
cp ./badapple.bin ../../initramfs
cd ../../../
that RIP happens when i press enter
and this will extract the binary
huh
how
i used git diff > whatever.patch
that's to generate the patch
yeah so it should be good
crash it with badapple again or run panic
wdym?
Thatâs what I somewhat expect
Well I shouldnât expect it
But yeah
This is using FPU code btw
where is badapple compiled to
But it will crash the same way if you have an infinite while loop
So it wonât do anything
found, thx
That gets called by another shell script thatâs executed by the makefile
Also I lowkey wana use some c++ in my kernel for instantiating classes for some drivers to be easier
oof, i can't addr2line the .bin
Should be able to objdump it and spesify x86-64
and how do i tell it?
still says not recognised
Maybe drop the -S
nope
objdump -b binary -m i386:x86-64 -D ./badapple.bin this works now
207: 48 8b 45 f0 mov -0x10(%rbp),%rax
it dosnt know the offset so subtract 0x4000
Why would I know đ
wait a sec
you never map the user pages
in the thread pagemap
you only map to the kernel pagemap here
@hazy saddle
i save the currently executing thread pointer in my cpu struct
so i can access it on the local cpu
the thread then contains a ref to its process
what if i pass the pagemap pointer as an argument to the thread?
and the process contains the pagemap
you already do tho
huh
but the actual thread dosnt have that
huh?
i need to get it passed in here?
you need to get the thread struct there

or well, thread pointer
yeah i can do that
which one on the stack should the pointer be again
when cracfting the stack
it's way easier
what
write the cpu struct to the kernel GS base msr
so you can use it in other places too
i dont have a CPU struct
make one
not rn
nah i got this
you could use an unused register then
ive been awake like more than 24 hours i need to just do this easily
using the msr is the easiest way tbh
nahhh fuck it we ball
FUCK
it works technicaly
to every register
bruh
so i cant possbily be wrong
that is a bad idea

just write it to like r15
i need to conform to SYS-V
in theory you should just need to set 6 registers
where is this code
scherdular.c
if the thread exits it returns there and loops
still fucked
well, are you mapping the memory?
i need to sleep lowkey but i cant sleep knowing its broke
changing 1 reg there means nothing if you don't use it
i am
show the updated mapping code
bruh
what did i do this time 
what reg did you pass the thread to?
it executes properly the first time tho
yeah, that's very strange
it shouldn't even execute
bc that mem is not even mapped
before i meant
ok, well, i see 1 problem there
the 0x0 to 0x4000 is mapped to the kernel
it doesn't have the user flag
so it will throw a pagefault
tho i'm not even sure that's the cause
because thoes pahes shouldnt be used rightr
then why map those at all?
and idk why tf it is mapped tbh
my entire VMM is stolem
i dont think anything SHOULD EVEN BE MAPPING IT
wait, in create_thread, i see you are using malloc to create the stack
yes
but do you then map that stack to add the user flag or no?
Thatâs the kernel stack right
This allocates another stack in userspace
Which I am having right now
And Iâm about to falls sleep
Is there anything else you need
Because I dunno what to do
maybe try to debug a bit
Idk what I should even be debugging
I think text messages is too inefficient to debug this lmao
yall need to do some pair programming
Setup one of those stupid IDEs that lets you edit code at the same time together too lmao
And honestly Iâm so fucking burnt out from this one bug
fuck windows
is all Ill say
but they did recently start shipping windows binaries I believe too
meh
they have great agent features
I dont use them personally
I get a bad taste in my mouth from anything that wants to integrate Ai
If I want AI il goto AI
xd
I use KATE
I mean u can turn off the agent panel with one setting if you wish
unfortunately today its basically expected to have AI stuff builtin
If they are going to bend to the will of AI I donât wana use it
I should be switching to libre wolf soon too because of the Firefox crap
Even fucking VIM has a sponsor for AI
JFC
it is futile to escape it
I just pick the best editor for me
an extra feature I turn off doesnt hurt me
Been going fine for me
But yeah anyways
@viral bison wana VC and pair program later when I wakeup
I cant quit google
in how much time btw?
My parents try and wake me up and they think Iâm dead đ
XD
huuh
@hazy saddle
i might have found exactly where it crashes
the second or third execution of this loop
when calling allocate_page
hi
how are u
dam i was outside earlier
hm interesting
thats from my friends code
maybe its running out of pages to give?
but hm
and if i give the PMM more bitmap pages and give it from 512mb to 2gb memory it still shits its self
I wonder what causes it inside this function
And by shits its self I mean it wont panic at the very least
So itâs giving âvalid pagesâ
I know the code is doing some integer division
Could it be accidentally giving physical pages that already have been allocated

@hazy saddle what ide do you use to code?
KATE
How do I do this btw
And not make things explode like they are
I can probably get it on cachyOS
The flatpak should be fine too anyways if I have a terminal open elsewhere
K
It is 2am rn tho
What would happen if I replace it with a bump allocator maybe
8Am here
And see if that will keep it working?
bump = VERY bad
Just to see if thatâs the real issue
Oh I know. But to see if the PMM is the issue
My friend said the VMM was fucked
But every time I made a VMM it always caused issues

wtf
so it's already at the first time that it returns a null page??
but somehow it still works
@hazy saddle how do i make your printf print an address in hex?
Should be the same as standard normal printf
I am using nanoprintf
virtually no mem needed, and it's instant
basically you add blocks (that represent free pages) in a linked listr
you store those blocks inside the free pages
then, when a block is used, if a block is multiple pages wide, you just shrink that
else, you nuke that block from the list and overwrite the data on that page
so it basically uses no mem
So a link list of free page ranges?
yes
When I take pages I break off from it
yes
And when I free pages I add to it
at the start
not if you don't require more than you have on the first block
when you find a block of the size you need, you stop
that's why you add freed pages at the start
And I can take a block and a part of another?
Why would I need it to be contiguous?
DMA sometimes need it like that
Whatâs it licensed under?
You could cc0 the linked list stuff
Iâm planning on having a repo with a bunch of small shit I made to be public domain
i tought gpl was good, will prob change it
anyway, here is the code: https://github.com/Diamantino-Op/HorizonOS/blob/main/src/libs/hos-base/src/LinkedList.hpp
it's made with c++
so you might have to adapt it
GPL means I would also have to be GPL
even with permission?
sec, lemme go and change that
it was the best way for c++
Yeah
MIT still needs credit for when the source is open
But itâs a lot more flexible
oh cool
Also dosnt a linked list need a malloc
well, yes
tho it can be made without
the one i sent was made to work with malloc
but if you go in my PMM file
you see the implementation without
found my PMM?
Not yet rn
Or rather any extra threads
wdym
It should push all GPRs switch stacks and then restore GPRs
Works for kernel threads
yeah i saw, but i don't see it looping i think?
when it reaches the end of the queue it will take a nullptr, no?
Iâm pretty sure the list is setup so the last element links to the top
@viral bison I wonder if itâs possible to gdb the user apps too?
I assume you can have external symbols generated
It will compile the elf too
But it dosnt load the elf
Itâs elf -> binary blob
The linker says the load address
So it should be fine
Linker script says 0x4000 I put it there
Also for not using malloc on the PMM
What if I used a bootstrap bump allocator? Once I have malloc working I can then use that properly
Or I just reserve the first page for the PMM?
yep, you reserve the first page
and point the first pointer to that
or well
first page of every mem region
limine gives you a memmap
use that
oh wait
debugging the app is useless rn
it never even reaches that point
lol
Isnât the page fault under CPL3 mode?
how do i see that
I dump the bits of the error code
For a page fault when bit3 is set it means CPL3 right
idk
Thatâs pretty useful for debugging though innit?
how tf is it failing on CPL3 if it never even reaches main

seems like it's skipping main entirely
So what the fuck is going on
What
oh no
tought you were loading the new pagemaps too erarly
bc what if it's not the new thread thta's pagefaulting
but the old one
this would make more sense
But I only run on one core tho
Maybe you can add a hook to the PF to log the current thread ID?
try
Sorry
Let me add some logging to that
the exact part it fails on
and if i make it use less pages it does the same
Interrupt Frame:
IP=0x0000000000004203 SP=0x000000007fffffa0
SS=0x0000000000000033 CS=0x000000000000002b
FLAGS : 00000000 00000001 00000010 10000111
how the fuck is it failing in 0x4000
wtf
race condition prob
but what if its settings things wrong
like these logs
with qemu debugs info mem
the memory map is bad
@viral bison we may need an expert to help us?
this is so fuckin strange
idk
someone that is available rn
something is trying to access a phys address
i think i'm getting close
it happens only when i run badapple

interwsting
i cannot thank you enough
i dunno if i could of even debugged this far without you
to get that error, i fixed this function:
this should also remove the garbage from the new pagemap
yes
they are in the kernel pagemap
ig its some kind of just random non zero memory?
but you zero it
also, that a address
huh
oh, where are you allocating it
yep
fuck
that's why it is pagefaulting now XD
and that's what i think is breaking the second badapple
should i have that just grab the current thread from the schedular
ITS DOING IT
i'll pass you the code i have
the XMM registers arent preserved
it has some more fixes
so they kinda sync up
yeah well
but it works
i forgor how to do that ngl
where do you enable it
wait im not using any FPU
still works with this
i think they all run tho
leme add a systemcall to DENGEROUSLY print a string
umm 
the threads need to know thier ID maybe
btw
