#Nyaux

1 messages ยท Page 34 of 1

surreal path
#

okay today we are doing the scheduler

#

so for scheduler designs

#

and smp

#

hmmmm

#

lets start by giving each core some per cpu data

#

now

#

should that be in arch/

#

okay each per cpu data should contain

#

the runqueue

#

of threads

#

or like

#

idk what do yall think

#

what other things should i store other then the cur thread and whatever

#

cause like

#

what about other archiectures

#

if i wanted to store something in per cpu data right

#

like a lapic id

#

but thats only for x86

#

how should this be abstracted

molten grotto
#

how I do it is just have arch specific headers and then I add the arch include directory to the compiler search path conditionally based on the arch

surreal path
#

i have an idea

#
struct per_cpu_data {
  thread_t *cur;
  #if defined(x86_64)
  // arch spefic shit
  #endif
}
molten grotto
#

src/arch/x86/include/arch/arch_cpu.hpp: ```cpp
struct ArchCpu {
uint32_t lapic_id;
};

src/arch/aarch64/include/arch/arch_cpu.hpp: ```cpp
struct ArchCpu {
    uint32_t affinity;
};
``` and then I add either `src/arch/x86/include` or `src/arch/aarch64/include` to the compiler include search dir with `-I` based on the arch, then everywhere else I can just do `#include "arch/arch_cpu.hpp"` and its going to include the arch specific header
molten grotto
#

the build system should know what arch you compile for, you don't want to compile all files for all architectures anyway

surreal path
#

yea i cant do that

#

im using a makefile

molten grotto
#

you can use a variable

surreal path
#

i dont know how to write makefiles

#

i stole it from limine c template lol

molten grotto
#
ARCH ?= x86_64

CFLAGS = -I src/arch/$(ARCH)/include
``` or whatever
tawdry mirage
#

you could also do #if defined(__x86_64__) #include "arch/x86_64/..." #elif defined(...) ... #endif

tawdry mirage
#

well adding the include paths is easiest imo

#

also re. the per-cpu data

#

i'd do ```c
struct generic_percpu_data {
struct arch_specific_percpu_data arch;
/* ... generic stuff ... */
};

#

so that arch-specific stuff is at fixed offsets if you need to access it from assembly or whatever (e.g. a self pointer, syscall stack pointer etc)

surreal path
#

i might do it like that then

tawdry mirage
surreal path
#

nothing sorry

#

im gonna have to store the user and kernel stack in the thread struct itself

#

it can be

surreal path
#

arch_specific_thread_data can js store the stackframe for the thread or wtv

tawdry mirage
#

and how does your syscall handler then load the stack pointer

surreal path
#

that would be kinda complicated

#

but it might go something like this

#

hold on

#
syscall_entry:
  mov rsp, [gs:0]
  ; this loaded the kernel stack ptr
#

i made them both pointers

#

the arch structs

#

to which i can just allocate on ze heap

#

tell me if theres anything wrong with this

tawdry mirage
#

why the double-indirection

surreal path
#

then what would u do to be better

tawdry mirage
#

i'd just put the kernel syscall stack pointer in the arch specific struct

#

and update it when resuming a thread

surreal path
#

why tho

tawdry mirage
#

so that the layout of thread_t isn't depended upon by the assembly code

surreal path
#

okay

#

would u make arch_specific_percpu_data

#

a pointer

#

or not

tawdry mirage
#

no

surreal path
#

so no pointer okay

#

and ud have the first thing in arch_specific_percpu_data be the kernel_stack_ptr

#

?

tawdry mirage
#

well you're discarding the user stack pointer

surreal path
#

wait

#

yea

tawdry mirage
#

yeah but you have to save the user's stack pointer on entry in the syscall handler

surreal path
#

oh yeah

#
syscall_entry:
  mov [gs:8], rsp
  mov rsp, [gs:0]
#

this should be better?

tawdry mirage
#

well swapgs before but yeah

surreal path
#

yea ofc

#

and im guessing ill have to update to the current threads kernel stack ptr and user stack ptr as well?

#

when u schedule

tawdry mirage
#

yeah

surreal path
#

okay

flat nymph
flat nymph
surreal path
#

to the current threads user stack?

flat nymph
#

Yes (?)

surreal path
#

why wouldnt i

flat nymph
#

It's part of the user registers

#

You don't update rax when switching tasks

#

Why would you update rsp

#

Just push it onto the kernel's stack and that's it

#

No need to be saving it in the CPU-local kernel data

surreal path
flat nymph
#

Yes

#

For bonus points, you make the structure the same as when you get interrupts

surreal path
#

i have the same structure

flat nymph
#

Then

#

When you have an interrupt, the CPU pushes RIP and stack address

#

With syscall, I think the old RIP is saved to r11

#

Or something like than

surreal path
#

ohhh okay

flat nymph
#

Just store it in the same place as when you have interrupts

surreal path
#

now im very confused

flat nymph
#

And when you return from syscall, take the value from the stack and put it into the rsp

flat nymph
#

How do you do task switching?

surreal path
surreal path
#

i have to?

#

what exactly

flat nymph
#

Push it onto the kernel's stack

surreal path
#

okay

flat nymph
#

Ok I'm not sure about r11

surreal path
#

okay but im using that stack

#

kernel stack

#

by the time i return from the syscall

flat nymph
#

Oh that's not how sysenter works

surreal path
#

i should have just the value right?

flat nymph
#

No

surreal path
#

oh

flat nymph
#

Userspace saves the rip

#

rflags are saved in r11

surreal path
#

i dont understand anything ur saying

#

now ur saying other stuff

#

๐Ÿ˜ญ

flat nymph
# surreal path by the time i return from the syscall

Ugh ```x86asm
syscall_entry:
swapgs

Userspace passes %rip in %r9. %rsp gets saved to %rcx

movq %rsp, %r10
movq %gs:0, %rsp

Construct what would be pushed by CPU

pushq $USER_SS
pushq %r9
pushq $USER_CS
pushq %r11
pushq %rcx

Save registers

...

movq %rsp, %rdi
call syscall_stuff_in_c

Restore registers

...

swapgs
movq (%rsp), %rcx
movq 16(%rsp), %r11
movq 24(%rsp), %rsp
sysretq

#

This way you can also be compatible with syscalls by int

#

Idk if this works, I've made it up just now

#

(my kernel does some cursed stuff)

surreal path
flat nymph
#

Other way around

#

(I'm very used to gnu assembly)

surreal path
#

what are u putting in rcx

#

at the end

flat nymph
#

%rip

#

Wait a sec, this is wrong

#

Oh well

surreal path
#

r11 has rflags

flat nymph
#

Yes

flat nymph
surreal path
#

okay when a syscall happens, rcx has rip, r11 has rflags

flat nymph
#

No

#

rip trashed

surreal path
flat nymph
#

Hmm

surreal path
#

read urself

flat nymph
surreal path
#

not the intel only sysenter

flat nymph
#

My kernel supports both trl

surreal path
#

then

flat nymph
surreal path
#

then what can i do then

flat nymph
#

You have a lot of scratch registers, you can โœจ trash โœจ one of them

flat nymph
surreal path
flat nymph
#

But you don't need to be switching it with processes

surreal path
#

yea because its just a tempory thing

#

only syscall is really gonna be using it

#

to store and read really quickly

#

theres no need to have it switched yea

#

anyways after u save the rsp switch to a kernel stack then push rcx and rflags in a way that would be similar to when a cpu recieves an interrupt what the stack would look like. push all registers to build a interrupt stack frame, then do syscall stuff. then pop all registers, pop rcx and rflags as expected as well as the other stuff. swapgs done

flat nymph
#

Yes

surreal path
#

okay i understand now

#

okay i know what to do but first i must shower

#

then scheduler

surreal path
#
typedef struct {
  pagemap_t *cur_map;
} process_t;
typedef struct {
  struct StackFrame *frame;
} arch_thread_stuff;
typedef struct {
  process_t *proc;
  arch_thread_stuff arch;
  uint64_t kernel_stack_ptr;
  thread_t *next;
} thread_t;
typedef struct {
   uint64_t syscall_stack_ptr_tmp;
   uint64_t kernel_stack_ptr; // this has to get updated when switching threads. its just indirection, so its easier for the cpu to get the kernel stack for syscall
   // other things like lapic id etcetc
} arch_cpu_data;
typedef struct {
  arch_cpu_data arch;
  thread_t *run_queue;
} per_cpu_data;
#

let me know if theres anything else i should change

#

before i start working on this

#

give me feedback

#

like does it make sense

flat nymph
#

user_stack_ptr?

surreal path
#

WHOOPS HOLD ON LEMME REMOVE THAT

#

OKAY IS IT BETTER NOW?

#

@flat nymph

flat nymph
#

Looks fine idk

surreal path
#

okay good

flat nymph
#

Have fun with smp spun

surreal path
#

what problem am i gonna run into

#

lol

flat nymph
#

Load balancing

surreal path
#

yea good point but no load balancing for now

#

might also need to put a lock on process

#

but

#

lets just get some barebones scheduler working

flat nymph
#

So all processes run on the same core?

surreal path
#

no

#

ill just randomly assign for now

#

rdseed

flat nymph
#

So a giant race condition

surreal path
#

how

#

i am literarly assigning a random thread to a cpu core

#

simple

#

dimple

flat nymph
#

When you access queues of other CPUs

surreal path
#

oh no i wont be doing that

#

js in main on the bsp halfmemeright before i start scheduling

#

like FOR NOW

#

til i figure out how load balancing works

#

cause i know nothing

surreal path
#

just replying to them so i dont forget

flat nymph
#

Still, your core pushes/pops processes from its queue

#

BSP core also wants to do that

surreal path
#

threads*

surreal path
flat nymph
#

Doesn't matter

surreal path
#

so no other cores are online atm

flat nymph
#

But then

surreal path
#

then what

flat nymph
#

When they're active

surreal path
#

all cpus js access their respective queue

surreal path
#

and if i get a syscall to open another program

#

when we get to that point

#

we will add load balancing

#

because from what ive heard load balancing is very compelx

#

anyways time to work on scheduler

flat nymph
#

Yeah

#

I still don't do it properly

flat nymph
surreal path
flat nymph
#

Or top

#

Idk

surreal path
#

i like top

#

its easier

flat nymph
#

I can't count

surreal path
#

cause stack grows down

#

it will point to the end of the memory region

#

i.e

#

bottom of stack*

#

okay this should be it

#

OH COME ON

#

this is what i do

#

clang is mad

#

it forced me to make it pointers

#

@tawdry mirage that is not pro

#

so extra heap allocation ig!!

finite summit
#

what

tawdry mirage
#

nothing is forcing you to do anything

surreal path
#

clang did

tawdry mirage
#

except your skill issues

surreal path
#

๐Ÿ˜ก

finite summit
#

if you typedef struct arch_thread arch_thread_t

#

then

#

wait what am I talking about

#

ignore this

surreal path
#

without a pointer it thinks its sizeless

finite summit
#

it's a definitely a skill issue on your part

surreal path
#

how

finite summit
#

I do like exactly what you're doing rn

surreal path
#

structure comes from here

finite summit
#

it works for me on clang and gcc

surreal path
#

these are the structures

#

and i have this function

finite summit
#

there is no such thing as a struct arch_thread_t

#

that's why

surreal path
#

oh

#

so i cant typedef it

finite summit
#

no you can

#

but you need to:

typedef struct blah {

} blah_t;```
#

instead of using an anon struct

surreal path
#

ohhhh

finite summit
#

i.e., one with no name

surreal path
#

makes sense

#

yea that solved

#

well the typedef is pointless

#

๐Ÿ˜ญ

#

but eh

#

anyways no pointers needed

finite summit
#

btw adding _t as a suffix is usually for the typedef'd name

#

not the actual struct

surreal path
#

fair

finite summit
#
// so instead of
typedef struct blah_t {} blah_t;
// you do:
typedef struct blah {} blah_t;
surreal path
#

yea i get the convention

cinder plinth
surreal path
#

its a typedef yea

finite summit
surreal path
#

i turned everything to regular non typedef structs because its still complaining and that didnt solve anything

#

๐Ÿ˜”

#

including all the structures

#

wtf clang

finite summit
#

uhh

#

doubt it's clang's fault

surreal path
#

probs isnt but again

#

issues

finite summit
surreal path
#

IM NOT SAYING ITS NOT MY FAULT

#

๐Ÿ˜ญ

finite summit
#

try gcc

surreal path
#

same issue

finite summit
#

glhf

surreal path
marble surge
#

I'm not sure but it looks like for some reason the type is not defined. Have you checked if you did the include guards correctly?

finite summit
#

always make sure your language server isn't being dumb

#

and saying it's not included

surreal path
#

how is it the language servers fault

#

if ur making it

finite summit
#

language servers make mistakes

finite summit
#

to make sure it's not telling you false stuff

surreal path
#

this should be included

finite summit
#

like __x86_64__ is undefined

#

as it is here

marble surge
#

I'd add an #error and try compiling if I didn't trust the language server

finite summit
surreal path
#

it does

marble surge
#

try compiling

surreal path
#

same thing

#

as well sa that

marble surge
#

then check that file that you include

finite summit
#

gl with this

surreal path
#

its just this

finite summit
#

wish you the best

surreal path
#

thanks

finite summit
#

your kernel is cursed btw

surreal path
#

whats something i dont know\

finite summit
#

the solution to the problem

surreal path
#

this makes sense

#

both depend on each other

#

that cant work

#

cursed but idc

#

would a doubly linked list be better for the run queue

#

because what if the last thread as a next that is NULL

#

how am i gonna go back to the start

#

its either

#

i store the first thread in the queue on a seperate field in per cpu data or

#

idk

#

what do yall think

#

also @finite summit solved ze skill issue meme

#

cirucular depends

marble surge
#

idk if this makes sense (I don't do osdev) but you could also store a pointer to the start instead of NULL and keep track of the last thread so that you can add a new thread using it

surreal path
#

ill just store head and tail

marble surge
surreal path
#

ea

#

yea

#

im writing some code :)

#

is that all?

#

lmao

silver yarrow
#

btw you should store the current thread in gs, not the cpu local

#

there's a race condition I can't remember

surreal path
silver yarrow
#

no

#

don't do that

surreal path
#

why

#

???

#

ur not telling me why ๐Ÿ˜ญ

silver yarrow
#

a race condition

surreal path
#

whats the race condition

#

explain

silver yarrow
#

can't remember

surreal path
#

bru

#

then im storing cpu struct in gs

#

like obos does

silver yarrow
#

you'll prolly end up with a very hard to diagnose bug

surreal path
#

no

#

obos does it

#

his kernel runs fine

#

am i right

#

@finite summit

finite summit
#

wha

#

yes

silver yarrow
#

I'll to find the thread

surreal path
#

yea

silver yarrow
#

or ask mint

#

not that thread lmao

finite summit
#

basically the problem he's trying to describe is:

  • loads cpu pointer from gs_base
  • we now return that value
  • task switch to a new CPU (uh oh)
#
  • we use this stale value to get the current thread of a different cpu
surreal path
#

sorry

#

what??/

finite summit
#

๐Ÿคฆโ€โ™‚๏ธ

#

that was literally me

#
cpu_local* get_cpu_ptr() { return (cpu_local*)gs_base; }```
surreal path
#

yea

#

what about that

finite summit
#

if we then use that like this:

thread* get_curr_thread() { return get_cpu_ptr()->thread; }
silver yarrow
#

#osdev-beginner-0 message

finite summit
#

between get_cpu_ptr() and it's dereference, it is possible for a task switch

#

causing you to move to a different cpu

#

and read the current thread of the cpu you were on before that

surreal path
#

why would 2 cpus share a thread

silver yarrow
#

basically you'll avoid headaches if u store the current thread in gs

finite summit
#

you switch

#

in between the dereference

#

so now the old cpu contains the current thread value of a different thread

surreal path
#

mhm

silver yarrow
#

actually here #osdev-beginner-0 message

finite summit
#

pseudocode:

get_cpu_ptr:
  mov rax, gs_base
  ret ;right here if we switch to a different cpu, we still return the gs_base for the old cpu. despite being on a new one
get_thread_ptr:
  call get_cpu_ptr
  mov rax, [rax+curr_thread_offset]
  ret```
surreal path
#

so ur saying

#

somehow when calling that function

#

u suddenly switch to a different cpu running that code?

#

and ur returning the gs base of the old cpu

#

but how can this be possible exactly

#

and how can it be solved after u explain how it can be possible

finite summit
surreal path
finite summit
#

so on that ret we can receive a timer irq

#

yielding

#

and we then end up on a new cpu

#

while we continue to read from another cpu's gs_base pointer

silver yarrow
#

You could also lower IPL anywhere u want to get thread data

#

but that's painful and a worse solution imo

finite summit
#

the solution: disable IRQs while reading from the cpu local pointer

surreal path
#

but this code isnt being scheduled, this should not be happening. no data should be going between 2 cpus and cant u disable interrupts while task switching

finite summit
#

what is up with the last part

silver yarrow
finite summit
#

yeah

silver yarrow
#

just lower IPL past sched

finite summit
surreal path
#

no 1. i will disable interrupts while scheduling

silver yarrow
#

we'll it's relatively simple to implement but fair enough

surreal path
#

no 2. i dont understand how this makes sense

#

but even though i dont understand the problem

#

i have a solution to it and im js not gonna worry about it

silver yarrow
#

say ur in a syscall, u want to get thread information. u call the fn, u get preempted, ur fucked

#

by far the simplest solution (as mint stated) is to eliminate the race condition

surreal path
#

u mean some other cpu gets preempted

#

which we dont care about

surreal path
silver yarrow
#

wdym same

surreal path
#

ur not changing gs base

#

gs base is a pointer

silver yarrow
#

yes the syscall gets preempted

#

by the scheduler

surreal path
#

oh wait

#

yea

#

thats bad

#

if ur doing a syscall

silver yarrow
#

well not "by" but

surreal path
#

and u get preempted

#

so that thread never got its syscall done

#

yea

#

makes sense

silver yarrow
#

no that's normal and fine in most kernels

#

u can also decide syscalls aren't preemptable but there are drawbacks

surreal path
#

that is what ill do

#

but agian

surreal path
#

but

#

its fine

#

we will just roll with it

silver yarrow
#

it won't be if ur syscalls can't get preempted

#

this race condition can only happen in-kernel and if u can't get preempted in-kernel the race condition doesn't exist

surreal path
#

its fine just disable interrupts for syscall and scheduling

#

done

#

anyways

#

im gonna go write code

silver yarrow
#

fair enough

surreal path
#

OKAY so we've switched threads changed contexts switch to the processes pagemap

#

yea i think the scheduling function is done

#

very simple

#
void sched(void *frame) {
    struct per_cpu_data *cpu = arch_get_per_cpu_data();
    if (cpu->run_queue == NULL) {
        kprintf("Nothing to Schedule.\n");
        return;
    }
    arch_save_ctx(frame, cpu->run_queue);
    if (cpu->run_queue->next == NULL) {
        cpu->run_queue = cpu->start_of_queue;
    } else {
        cpu->run_queue = cpu->run_queue->next;
    }
    arch_load_ctx(frame, cpu->run_queue);
    // for reading operations such as switching the pagemap
    // it is fine not to lock, otherwise we would have deadlocks and major slowdowns
    // for writing anything however, the process MUST be locked
    arch_switch_pagemap(cpu->run_queue->proc->cur_map);
    

}
#

but its good

#

ok fixed that

#

well good thing i have an assertion

#

๐Ÿ˜”

#

happening when trying to access it huh

#

even tho i wrote to it?

#

and qemu says its in there???

#

i set runqueue to null

#

any time i try to access it, it dies

#

so 2e93018 can fit

#

but not the rest

#

is there something wrong with this function?

#

the function is right

#

oh it was the rdmsr function

#

solved it

#

okay address was something

#

then it turned to 0

#

i think its because i save gs in my interrupt ctx

#

lets remove that

#

yep that was the issue lmao

#

it works tho

#

!!

surreal path
#

HERE WE GO CHAT

#

so close

#

SO CLOSE

#

e

#

oh here

#

but i gave it the map?

#

0x0 is the error code

#

what is going on nooo

#

mappings look like this

silver yarrow
#

whats the cr2

surreal path
#

this really looked like a completely valid address

#

thats the cr2

#

and not switching the page map just create more faults

silver yarrow
#

looks valid to me

surreal path
#

yea a 0xd

silver yarrow
#

well something is cooked

#

๐Ÿ˜„

surreal path
silver yarrow
#

error code?

surreal path
#

hold on

#

0

#

thats the error code

silver yarrow
#

eh could be a number of things

surreal path
#

yea no idea

#

could it be that the page tables are fucked again

#

code on github

silver yarrow
#

so the current thread is the start of the run queue?

silver yarrow
#

does ur kmalloc zero things out?

surreal path
#

both slab and

silver yarrow
#

I dont see any glaring issues but your code style makes it a bit difficult to interpret

surreal path
# silver yarrow I dont see any glaring issues but your code style makes it a bit difficult to in...
struct StackFrame arch_create_frame(bool usermode, uint64_t entry_func, uint64_t stack) {
  if (usermode) {
  struct StackFrame meow = {
    .rip =  entry_func,
    .rsp = stack,
    .cs  = 0x40 | (3), // USER CODE
    .ss = 0x38 | (3), // USER DATA
    .rbp = stack,
    .rflags = 0x202
  };
  return meow;
  } else {
    struct StackFrame meow = {
    .rip =  entry_func,
    .rsp = stack,
    .cs  = 0x28, // USER CODE
    .ss = 0x30, // USER DATA
    .rbp = stack,
    .rflags = 0x202
  };
  return meow;
  }
  
  
}
#

that is my create frame function

silver yarrow
#

so you dont have cooperative switching

#

only preemptive?

surreal path
#

yea

silver yarrow
#

since ur context switching on interrupts..

surreal path
#

yea?

silver yarrow
#

probably not the most flexible way to do it but fair enough

surreal path
#

ok but

#

still dunno whats going on

#

i have a feeling the page tables are fucked again somehow

silver yarrow
#

I'd have to run it and debug to really figure out and I dont really feel like making a nix flake

silver yarrow
#

I run nixos

surreal path
#

i dont use nixstrap

#

ohh

silver yarrow
#

๐Ÿ™‚

#

I suppose I could do one as long as u dont use some niche software thats not packaged

surreal path
#

i dont at all

silver yarrow
#

dope

#

will do

surreal path
#

thanks!

silver yarrow
surreal path
#

yea many people run into that issue, what u need to do is js mkdir .git

#

in that cc-runtime folder

#

@silver yarrow

silver yarrow
#

gotcha

surreal path
#

yep

silver yarrow
#

almost got it building

surreal path
#

coolcool

silver yarrow
#

need to figure out what the fucking clang package is again

surreal path
#

u can use gcc if u want to

#

nyaux works on both

#

@silver yarrow

#

:)

silver yarrow
#

ill include both in the flake

surreal path
#

theres also clang_19

#

okayokay

silver yarrow
#

clang_19 yeap but then u also want clang-tools_19

#

nix moments

surreal path
#

truly

silver yarrow
#

whats the flag to use gcc

surreal path
silver yarrow
#

based

surreal path
#

kernel/gnumakefile

#

indeed!

#

clang and gcc are having different behavior with the page faulting (gcc says the page fault handler is a problem in the stacktrace, clang js says none 0x0 a bunch) so theres def some UB going on, dw about that tho js use gcc and im sure ull find the uB and then itll be the same on both gcc and clang

silver yarrow
#

lol

surreal path
#

yea clang

silver yarrow
#

yeah I got it build btw

surreal path
#

vs gcc

#

okayokay

silver yarrow
#
{
    inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
        flake-utils.url = "github:numtide/flake-utils";
    };

    outputs = { nixpkgs, flake-utils, ... } @ inputs: flake-utils.lib.eachDefaultSystem (system:
        let
            pkgs = import nixpkgs { inherit system; };
            inherit (pkgs) lib stdenv mkShell;
        in {
            devShells.default = mkShell {
                shellHook = "export DEVSHELL_PS1_PREFIX='Nyax'";
                nativeBuildInputs = with pkgs; [
                    libisoburn # xorisso
                    nasm
                    mtools
                    curl
                    gnumake
                    gdb
                    clang_19
                    clang-tools_19
                    qemu_full
                ];
            };
        }
    );
}
#

here is the flake for any future nix users

surreal path
#

yea!!!

silver yarrow
#

so funny thing

#

on my machine

#

it goes insane

#

throws tons of exceptions

#

or wait a sec

#

those are just timer interrupts

surreal path
#

yea

#

lmao

#

๐Ÿ˜ญ

silver yarrow
#

oh it does the same for u?

surreal path
#

yea

silver yarrow
#

alrighty

#

are these uacpi errors expected

surreal path
#

yes

silver yarrow
#

fyi there's a faster way to do this but its ok for now

surreal path
#

ik

silver yarrow
#

what header is kprintf in

surreal path
cinder plinth
silver yarrow
#

gs:0

finite summit
#

it's dumb how lea rax, gs:0 just loads zero into rax as the effective address

#

I guess it makes sense

#

but I'm not a fan of it

silver yarrow
#

well

#

lol

cinder plinth
silver yarrow
#

@surreal path afaict something in the struct thread is getting corrupted maybe

#

cpu local *

silver yarrow
#

ugh actually not quite sure

#

this works

#

u only add one thread to each core right

surreal path
#

yes

silver yarrow
#

so that if should technically be a null operation

#

like the whole moving the queue forward

surreal path
#

wdym

#

that should work js fine?

#

that is interesting that this if statement is causing corruption

#

???

silver yarrow
#

this assertion fails

#

afaict it shouldnt

#

if u only add one thread the next should always be null no?

surreal path
#

yea it should

#

only be null

silver yarrow
#

question is.. why is it not

surreal path
#

this line fixes it

silver yarrow
#

ok so im 99% ur kmalloc fails to zero the memory properly

#

yeap

surreal path
#

why is it not properly zeroing out the memory

#

ok adding this

#

solved it

silver yarrow
#

in ur slab

surreal path
#

no need for this no more

silver yarrow
#

this only zeroes the struct

#

not the actual memory

surreal path
#

its okay tho i added a expcit memset

#

so itll work fine

silver yarrow
#

fair

surreal path
#

now question is

#

why isnt it printing hello world

#

i load the context into the frame

#

it should work

finite summit
#

Idk

surreal path
#

lol

#

yea this makes sense

#

we overwrite the ctx with arch save ctx

#

question is

#

how do i fix this with one thread

silver yarrow
#

wdym?

surreal path
#

as in

#

we are overwriting the threads contex

#

xt

#

well maybe

#

instead of setting the runqueue

#

i need to set start of queue only

#

yea

silver yarrow
#

ah cuz the initial

#

I see

#

my solution

surreal path
#

it did not work

silver yarrow
#

I have a dummy thread with its state set to destroy

#

that is "active" when entering the schedule

#

and on the first switch it gets nuked

#

because its state is destroy

surreal path
#

arch load context isnt even being called

#

ever?

#

oh waiut

#

my if statement

#

we got closer

#

happeniung when memcpying

#

the sched rip is just the start

#

for some reason

#

yea not fun

#

cr2 is ffff800003a7df30

#

i pushed my changes to git

silver yarrow
#

: )

surreal path
#

how did u get it working????

#

huh????

silver yarrow
#

init thread

surreal path
#

how????????????????????

silver yarrow
#

u need to add more to ur scheduler to do it properly

#

but in theory

surreal path
#

show me changes

silver yarrow
surreal path
#

@silver yarrow please ๐Ÿ˜ญ

silver yarrow
#

this is just a mockup

#

u need to impl it properly

#

oh I also renamed some ur vars when debugging earlier

surreal path
#

i am lit doing the same thing

#

yet i page fault

#

tf

silver yarrow
#

sec

#

can u send me url of the commit

surreal path
#

i dont have an init thread

#

but

#

i js do that if run queue is null

#

check

#

wait

#

i realized

#

nvm

#

LETS FUCKING GOOOO

#

@silver yarrow LOOK

silver yarrow
#

๐Ÿฅณ

#

btw want me to upstream the nix flake?

surreal path
#

send a pr

silver yarrow
#

I will

#

sec

surreal path
finite summit
#

Whoa

#

Cool

surreal path
#

real!

#

now i have a kentry

#

thats being scheduled

#

cool indeed

#

ok i did the scheduler now chat

#

and now we have a kentry

#

okay so what is next

#

let us check the mint to do osdev list from curated resources

finite summit
#

Wait you are in GMT right

surreal path
#

yes

finite summit
#

Wouldn't that mean

#

If's 1 am

#

For you

surreal path
#

its 2:10am

finite summit
#

*it's

finite summit
#

Go to sleep

surreal path
finite summit
#

It's better for you

#

Less slep you get the shittier code you write

surreal path
#

good point

#

but before i go to sleep

#

lets say what we will do tmrw

#

so

#

we will add an apic "driver" to nyaux

#

im thinking for this time ill do x2apic

#

ive never done that before so might be more fun

finite summit
#

Do both

surreal path
#

why both

finite summit
#

Would be fun

#

Because some machines only have lapic

#

The old one

surreal path
#

actually we will see, after the apic stuff def a vfs

#

anyways nightnight

finite summit
#

Gn

surreal path
#

done

tawdry mirage
#

what's nyax ```
shellHook = "export DEVSHELL_PS1_PREFIX='Nyax'";

silver yarrow
#

lol

#

good

flat nymph
#

In theory you're supposed to be switching kernel stacks

surreal path
#

???

#

i am doing it right???

flat nymph
#

You're supposed to be switching kernel stacks

surreal path
#

kernel stack is for syscall

#

when executing a syscall

flat nymph
#

No

#

You have a page fault, that must block the thread and fetch the data from disk

#

What do you do

surreal path
#

switch to kernel stack

flat nymph
#

No

surreal path
#

then do what u need

flat nymph
#

There's no one kernel stack (unless you're microkernel doing weird stuff, e.g. pmOS)

#

You have kernel stack per process

surreal path
#

why

edgy pilot
#

you mean core?

flat nymph
#

Thread*

#

I thought that's how it worked

surreal path
#

yea i have that

#

and

flat nymph
#

Like when creating a thread, you create a kernel stack

edgy pilot
#

why would you need different kernel stacks for different threads

surreal path
#

kthread is still a kthread, rsp is where its stack is stored

molten grotto
flat nymph
#

But also preemption in general

molten grotto
#

it makes it easier

surreal path
flat nymph
#

Like to handle stuff in interrupts

molten grotto
#

and interrupts yeah

flat nymph
#

You just change the pointer to current thread

surreal path
#

bcs i dont have syscalls yet.

#

and it wouldnt really matter

edgy pilot
#

oh I haven't touched this subject for a long time, my old kernel has per thread kstacks too

surreal path
#

if i allocated one or not

edgy pilot
#

my bad

flat nymph
#

It would

surreal path
#

oh why so

#

im not having syscalls when ur in kernel codfe

#

code*

#

smh

flat nymph
edgy pilot
#

and per thread page fault stack

surreal path
molten grotto
#

it can be the same stack as the syscall stack no?

flat nymph
#

So you can preempt

flat nymph
#

So when you switch tasks, you switch to a new kernel stack

#

Doesn't matter where

flat nymph
#

In syscalls, from timer interrupts, in pf handlers

edgy pilot
#

I remember almost nothing

flat nymph
#

Idk maybe the kernel which I've seen in os class in uni was weird

#

But I thought that was how it was generally done

surreal path
#

ugh

flat nymph
surreal path
flat nymph
#

So

#

You need to have a function, probably in assembly

surreal path
#

i know what to do

flat nymph
#

Which pushes the saved registers onto the stack, saves the stack pointer, switches to a different thread, pops those same registers and returns

flat nymph
#

When you create a thread, you push the return address of a function, which prepares it for the first time onto the kernel stack

#

So when you switch to that thread, that is the first thing that gets called

#

So you switch (kernel) contexts

surreal path
#

look i did it

#

happy?

flat nymph
#

Idk

surreal path
#

bru

#

im giving a kernel stack per core

#

want me to do it per thread

#

will that make u happy

flat nymph
surreal path
flat nymph
surreal path
#

im doing it chill

#

yea thats not correct

#

this should be not 0

#

oh now he mad

#

when i put iretq

#

cringe

#

so why is bro mad

flat nymph
surreal path
#

dw abt it

surreal path
#

forgot the colon

#

but still bros mad

#

sir

flat nymph
#

Why

surreal path
#

dw abt it im js trying to test if it works first off

#

how is this a segment override

#

ugh

flat nymph
#

You're only supposed to be saving general registers here

surreal path
flat nymph
#

And do swapgs if you're coming from userspace

surreal path
#

yes i did

#

stop assuming i didnt lmao

#

sooo

#

why is it saying its a segment override..

#

invalid segment override

#

i dont understnad

#

any master nasm users know whats going on

flat nymph
#

What's the full code

surreal path
#

here

finite summit
#

what line even is it

surreal path
#
isr_stub_%1:
    ; Push a dummy error code if a 2nd parameter has been passed to the macro
%if %0 == 2
    push %2                  ; Push dummy error code
%endif
    test byte [rsp + 16], 0x3; Are lower 2 bits(priv lvl) of CS selector 0?
    jz .skipswapgs1          ; If they are 0 (kernel mode) then skip swap
    swapgs                   ; Otherwise swapgs in user mode
.skipswapgs1:
    push rbp
    push rax
    push rbx
    push rcx
    push rdx
    push rsi
    push rdi
    push r8
    push r9
    push r10
    push r11
    push r12
    push r13
    push r14
    push r15

    ; push gs                  ; Save previous state of segment registers
    ; push fs


    push %1                  ; Push the interrupt number
    call arch_get_per_cpu_data
    test rax, rax
    jz .idk
    mov rsp, [rax:8]
    .idk:
    mov rdi, rsp ; put value of stack pointer into paramter 1 of c interrupt handler
    mov rax, [idt_handlers + %1 * 8]
                             ; Get the registered handler to call
    cld                      ; Required by the 64-bit System V ABI
    call rax
    mov rsp, rax
    add rsp, 8               ; skip int number
              ; Restore previous state of segment registers
    ; pop fs
    ; pop gs

    pop r15
    pop r14
    pop r13
    pop r12
    pop r11
    pop r10
    pop r9
    pop r8
    pop rdi
    pop rsi
    pop rdx
    pop rcx
    pop rbx
    pop rax
    pop rbp

    test byte [rsp + 16], 0x3; Are lower 2 bits(priv lvl) of CS selector 0?
    jz .skipswapgs2          ; If they are 0 (kernel mode) then skip swap
    swapgs                   ; Otherwise swapgs in user mode
.skipswapgs2:
    add rsp, 8               ; Skip error code
    iretq
%endmacro
surreal path
finite summit
#

rax isn't a segment register

#

mov rsp, [rax+8]

#

is probably what you meant

surreal path
#

it kinda worked

#

i just need to extern arch_get_cpu_data

#

well it died

#

to be honest makes sense

#

i need to check if the field is not null too

#

it is not working so far

#

wait it might be working

#

i js need to check if its from cpu 0

#

hold on

#

it died so hard

#

something bad happened

#

i may be accessing the wrong field?

#

somehow??

#

i shouldnt be?

#

arch cpu data is just this

#

if im accessing [rax + 8]

#

and rax has the ptr to per cpu data structure

#

and im deferencing it

#

and adding 8 bytes

#

shouldnt i js get kernel stack ptr??

#

like normal?

#

??

thorn bramble
#

how do you get the value into rax in the first place

surreal path
#

these instructions

#

that is arch_get_per_cpu_data

thorn bramble
#

why not just

#

mov rsp, gs:[8]

surreal path
surreal path
flat nymph
#

You're on the kernel stack already

thorn bramble
#

well, it's the simplest way to grab the value out of the kernel stack

#

i dont think he is

surreal path
#

im not yet

#

no

thorn bramble
#

i think this is supposed to be in his syscall handler

surreal path
#

no

#

this is for

#

switching task and interrupts

#

as mishakov wants

thorn bramble
#

wtf

flat nymph
#

Then you're pushing registers onto the userspace stack

thorn bramble
#

least broken nyaux code

#

sorry

#

that was rude

surreal path
#

bru

surreal path
flat nymph
#

From syscall yes

#

From isr you don't switch stacks

#

You're already on kernel's stack

surreal path
#

bro

#

u told me

#

switch stacks when task switching

#

and interrupts

#

i said

#

"ok"

#

bro

#

๐Ÿ˜ญ

#

๐Ÿ’€

#

yea thanks for confusing me lmao

#

/j

flat nymph
#

You're not task switching when entering kernel

cinder plinth
#

your stack switching on interrupts is done by an IST

surreal path
#

glad ist exists

#

yea so not gonna worry abt that for now

flat nymph
#

The other stuff was fine

surreal path
#

??

flat nymph
surreal path
flat nymph
#

What