#SnowOS
1 messages · Page 6 of 1
This is a bit of a rabbit hole ?
You could also use a ticket lock which ensures fairness etc
And is pretty simple to make
started working on a minimal debugging shell
i just parse my own elf
and then use the bootloade to tell me where i was loaded
Okay, was guessing I might have to do something like that
ah, that means I'll need stuff to read a PE 
idk what namespace that would be under, I guess a ldr namespace
You can also add linker symbols
Arround every section that needs special perms
Then read the addresses of those etc
But that’s less cool imo
Though it is common
You also don’t need full elf/pe loading
Just parsing of the sections and address ranges and there perms
I mean I have to write PE header parsing anyhow so might as well do it this way 
ye I know :3
Exactly
Also you can probably make it in userspace first
Then port it
(Or be cool and make it a single header portable library)
I've made a PE parser before already, so shouldn't be too hard
actually no probably not today
I still have to work on slab
maybe tmrw or the day after tho :3
limine_file *yukiImage = hal::retrieveYukiImage();
ke::print("Physical Address of Yuki 0x%llX\r\n", reinterpret_cast<uintptr_t>(yukiImage->address) - hal::retrieveHhdmOffset());
💀
pretty sure I need executable address here not executable file:p
thx! Even if I'm not that far along lol
yeah still but making an OS is hard
i had my pain with mlibc

speaking of which, I need to look at mlibc's source and see if it's worth trying to port or not
i mean you just have to config
and compile
and it will generate a libc
the issue is I'm not POSIX* (natively)
so I get the feeling it isn't that simple
but you will need syscalls for that
This was such I stupid mistake I dunno how I missed that 🥀
anyhow it's fixed now :3
[binaries]
c = 'clang'
cpp = 'clang++'
c_ld = 'lld'
cpp_ld = 'lld'
strip = 'true'
[built-in options]
c_args = ['-target', 'x86_64-unknown-windows', '-ffreestanding', '-mno-red-zone', '-mno-mmx', '-mno-sse']
cpp_args = c_args
cpp_link_args = ['-target', 'x86_64-unknown-windows']
[host_machine]
system = 'uefi'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
there is no nasm decleration on the pushed repo
The Meson build system
Version: 1.3.2
Source dir: /home/constantine/SnowOS
Build dir: /home/constantine/SnowOS/build
Build type: cross build
Project name: SnowOS
Project version: 0.1.0
meson.build:1:0: ERROR: 'nasm' compiler binary not defined in cross or native file
A full log can be found at /home/iaintleakingmyuserbro/SnowOS/build/meson-logs/meson-log.txt
okay, I presume all you have to do is add nasm = 'nasm' under [binaries]
yeah i willl lol and test it out
The Meson build system
Version: 1.3.2
Source dir: /home/myusernamestartswithc/SnowOS
Build dir: /home/myusernamestartswithc/SnowOS/build
Build type: cross build
Project name: SnowOS
Project version: 0.1.0
Nasm compiler for the host machine: nasm (nasm 2.16.01)
Nasm linker for the host machine: clang ld.lld 18.1.3
meson.build:1:0: ERROR: Unknown C std ['gnu23']. Possible values are ['none', 'c89', 'c9x', 'c90', 'c99', 'c1x', 'c11', 'c17', 'c18', 'c2x', 'gnu89', 'gnu9x', 'gnu90', 'gnu99', 'gnu1x', 'gnu11', 'gnu17', 'gnu18', 'gnu2x', 'iso9899:1990', 'iso9899:199409', 'iso9899:1999', 'iso9899:2011', 'iso9899:2017', 'iso9899:2018'].
A full log can be found at /home/myusernamestartswithc/SnowOS/build/meson-logs/meson-log.txt
it was not that only 😭
18.1.3
ah
sudo apt installed 18.1.3
ye you might wanna update clang, tho you may also be able to change it to gnu17 since I technically use little to no C in the OS
ah wait, does 18.1.3 support c++23/26? 😭
nuhuh@mintpc:~$ clang++ -std=23
clang++: error: no input files
nuhuh@mintpc:~$ clang++ -std=26
clang++: error: no input files
okay I think that version should support c++23 but not c++26 
anyhow, back to working on slab :3
I also think I will implement object caching 
for properness
I should implement a doubly linked list in userspace first tho
no
sorry
I meant a circularly linked list lol
allocation works (with small slabs), now I have to do freeing
uhh, I'm guessing I need a tail pointer
otherwise I don't think I have anyway of finding the end of the list
admittedly I don't really know why it has to be a circular linked list
oh wait, no I don't :p
who says it has to?
if you were looking at my kernel I use circular linked lists because they're branchless
Bonwick apparently 
where
of all its slabs.``` Under 3.3 Freelist Management
despite that, yeah I don't think it has to be a circular list 
It's an implementation detail
Circular lists are basically normal linked lists, with the exception that the nodes are connected to the head instead of nullptr at the end, which makes it a little bit faster
(since you don't have to do nullptr checks and stuff like that)
We're you doing your kernel in C++?
yeah
aight, back to working on slab >:3
this is acceptable right? 
typedef struct _SLAB {
typedef struct _BUFCTL_SMALL {
_BUFCTL_SMALL *next;
} BUFCTL_SMALL;
// External Bufctl
typedef struct _BUFCTL {
_SLAB * slab; // Pointer to the slab of which this bufctl belongs to
_BUFCTL *next;
} BUFCTL;
_SLAB *prev;
size_t objectSize;
uint64_t refCount;
union {
_BUFCTL_SMALL *bufctlSmall;
_BUFCTL *bufctl;
};
_SLAB *next;
} SLAB;
I suppose I could also use a void * and just reinterpret_cast instead of using a union, but I don't feel like it :p
uh
actually I dunno if an external bufctl needs a pointer to it's slab 
I just remember seeing that somewhere
it does, but you can do clever tricks to avoid it
oh? 👀
for one you could restrict the slab size to one page and always embed the slab data inline (which might prove less wasteful for certain sizes) and/or you can store a pointer in the struct pages associated with slab memory
Well yeah, obviously I can embed the slab data for certain sizes, but it seems like I'm not really supposed to do that above a certain point, at least that's what I would be led to believe according to the paper. Granted, I could just... not, support large slabs, but I don't know how reasonable that is :p
I mean I can't believe it's super common that you allocate something bigger than 512 bytes, so I don't think having large slabs is critical, but still
that's what the paper says
freebsd for example had support for only page size slabs for a very long time, in fact they might still do
aight, good to know
Okie imma finish the code up some and commit my ultra shrimple Slab allocator to the git
okay I think the slab works now?
or at least
the list is behaving how I would expect it to
although I don't really know what this is about 
uhhh, how the heck do I use the module request 
oh
I typed module: instead of module_path: 🥀
I guess I should fix my valloc implementation because uACPI doesn't work 
It’s in the same format as specifying the executable
Man I see some of the things other kernels here can run and I'm like "Wow! It would be really cool if I could do that stuff!"
but then at the same time
I really don't wanna write a UNIX-like :p
wait it does 
well it can
you very well could port it you make your own X server implementation
and still have some cool ports
I did kind of wanna do the Window Manager myself though 
okie I think imma work on vmem a lil bit
won't do much, probably will just add some checks for whether the slab is initialized
also I know LoC doesn't mean much but I still feel like my kernel is notable small
yet somehow it's almost 100KiB 💀
removing /debug makes it slightly better ~75KiB
heads up for anyone following this thread, I'll probably be taking a break for a little bit
I mean I still wanna try and launch a userspace process before the end of the month
but after that
gonna take a break and work on some other projects
alright, hopefully this should only take like a day or two
still no timer
oh well
who needs a timer anyways 
You need one for preemption, or well you need some interrupt source
Otherwise one app could trap you inside it
But an interrupt isn’t the only way to switch tasks
who, needs preemption, purely cooperative scheduling is where it's at 
😭
A timer isn’t too hard
Just find any timer with a known frequency
Then calibrate the LAPIC
Your done
out of curiosity, what other way would you switch tasks? 
An interrupt just runs the task switch function like any other task wanting to sleep etc
Nope because it’s controlled by the user
And it could never call it
But a syscall could then run task switch inside the kernel and switch tasks
Interesting
When you do a syscall you switch to the threads kernel stack (to not use the user one) and your back running on that kernel threads context
The task just jumps to user code and drops privileges until it runs syscall or gets an interrupt etc
Hm?
I know but I have yet to figure out why uACPI isn't cooperating 🥀
uh, right, how would I go about doing that?
You can look at my old kernel repo or like read the wiki
It has some decent pages on the format of the tables
Btw I wouldn’t use the address the tables give you for the local APIC
Just read the MSR for where it is
(IOAPIC is separate tho)
ACPI is authoritative 
I’d consider the MSR to be more so considering it’s the current status of the CPU
Huh interesting
U dont lol
It is since it literally reflects the current state
Yeah, I do it in my kernel
You can probably also check limine or something
I need to fix my SMP memes though 
I explained it before
yeah, but there were too many messages in your thread since then
It's random bs that happens to work
it was never changed because it never broke
but it wasnt done because acpi is somehow more authoritive than the literal cpu msr
yeah
wait
u have 2 cases:
- lapic disabled (in that case cpuid is cleared)
- lapic enabled and has a valid base
for case 2, if that has a different base set u really dont want to change it because it's probably relocated for a good reason. What you should do is record it and apply it for all APs as well
Idr
also didnt we see in code that it rewrites the address it gets with what's currently set by bios?
can you find that conversation?
What do you do when the LAPIC is disabled?
you won't see it supported in cpuid so u just assume it doesnt exist
it's usually disabled for a good reason
too lazy but whatever, u can just do what linux does
Huh, i guess I would need some fallbacks in that case on x86-64? I thought it was architectural
So I will need to support PIC 
i just panic if it's not enabled
that's what I was gonna do 
it is technically, but nothing prevents me from doing wrmsr(apic_base, 0)
which clears cpuid
Huh neat
I could force re enable it via a cmdline on fuckass hardware ig 
And then panic with a message saying that
i mean yeah thats what linux has
no..
Ah
it has a command line to force enable it
Ahhh sorry
I could just support PIC but that makes things wayyy more painful, though it may be fine if I only allow legacy hardware though it and special case it 
i mean its not exactly hard, just means all interrupts will be delivered to cpu 0
and msis are unusable
and no SMP because you can’t IPI right?
yes
Yeah so not too bad to special case for PS/2 & serial then disable things needed MSI/X etc
Ty
yeah i just dont see any reason to support it frankly, since its not a realistic configuration
like all x86-64 hardware that has ever existed had lapics
so its a meme/vm config
I think they all pretty much have IOAPICs too? I don’t think any chipset when x86-64 was made even lacks it other than meme/vm stuff
i guess, but ioapic is not really a hard dependency, if you have no legacy interrupts you have no need for ioapics
I don't have to do much configuration of the HPET if I'm just using it to calibrate the LAPIC right?
exactly 0 other than enabling it
coolio :3
basically id support pic-only mode if u wanna support 32-bit cpus
pic is pita to detect though
I support ACPI PM timer though
Oh, I confused PIT and PIC again...
yeah
though PIC only is like 386/486 machines or broken firmware?
So I didn't bother supporting them myself
yeah i wont bother either
Anything pre-pentium is the insanity territory in my eyes
This should work right? 
void hal::x64::hpetSleep(uint64_t ms) {
const uint64_t ticks = (ms * hpetFrequency) / 1'000;
uint64_t startCount = readHpetRegister(HPET_MAIN_COUNTER_VALUE);
while (readHpetRegister(HPET_MAIN_COUNTER_VALUE) < startCount + ticks);
}
I should have a generic mmioRead/Write, but ignore that :p
Counter can rollover can’t it?
Iirc HPET can be 32bit?
it's can? 
yeah u need to use a subtraction there
ah
Yes
I think it’s common on AMD?
amd hpet is always 32-bit yes
dang, didn't know that =/
but if u do (current_ticks - base_ticks) < needed_ticks it will always work fine
ah, okay that makes sense
Well, if I can say anything about this, it at least feels better than my first attempt :p
anyhow, LAPIC time 
oh ye
I also need a TSS
I'll do that after tha LAPIC :3
do you also OR in the timer mode?
that is also offset 0x320 right
also i wouldnt read in on that register
ye
just write to it with the mode you want
i do mmio_write_offset_32(apic_address, APIC_REGISTER_TIMER, 0x20 | APIC_MODE_TSC_DEADLINE); (if its supported ofc)
is it just me or does that seem kind of low?
Imma blame hpetSleep, I think it's broken 🥀
I say sleep for 1 second and it doesn't sleep for 1 second
show code
the counter clock period should be u64
not u32
oh shoot right
well you didnt reset the counter
thats something
idk if thats the problem
this is what I do
https://git.evalyngoemer.com/evalynOS/evalynOS-old/src/branch/dev/kernel/src/drivers/x86_64/timers/hept.c
this is what I do aswell
Also make sure to use inline assembly for MMIO functions
And to always a normal “mov” and have a constraint to always use “r/eax”
that looks the same as what he's doing
idk i think volatile is ifne
It could still generate other instructions not suitable for MMIO
And AMDs manuals say not using EAX is improper for some cases
I mean I use volatile
But like do as I say not as I do
Do as the manual says 
And I don’t wana have to find that manual
But you can search previous convos on the discord
That was talking about ECAM
on x86 at least volatile should be fine?
Fair but it can’t hurt to use eax since it’s also the return register and works our mostly 
Only inline ASM is a guarantee
Yes
yes I know
but does that matter
Well it will crash kvm
Because it can only emulate a small subset for mmio
soo, how do I deal with 64bit read/write, do I just have a high and low var and stitch them together or something?
You use rax
And for 16bit you use ax or whatever
Also, I think the manual says that even if you read it as u64, the hardware can do 2 32 bit reads, so the counter can be inconsistent?
You could mask the upper 32bits and pretend it’s always a 32bit timer and handle rollover

That’s spesific to HPET
What was rax about then?
For 64bit MMIO registers

You should still read the full register if it’s a 64bit register
You read high 32 bits, the low 32 bits, then high 32 bits again
if high 32 bits change, you try again
so, something like this?
static inline void mmioWrite64(uint64_t address, uint64_t reg, uint64_t value) {
__asm__ volatile ("mov %%rax, (%%rbx)" :: "b"(address + reg), "a"(value));
}
static inline uint64_t mmioRead64(uint64_t address, uint64_t reg) {
uint64_t ret{};
__asm__ volatile ("mov (%%rbx), %%rax" : "=a"(ret) : "b"(address + reg));
return ret;
}
You have to use compiler constraints to make it work
yes, except that rbx is not the best choice
oh :p
You should let the compiler pick for RBX
uhh, how would I do that? 
Using Assembly Language with C (Using the GNU Compiler Collection (GCC))
Constraints (Using the GNU Compiler Collection (GCC))
I mean I do this https://gitlab.com/mishakov/pmos/-/blob/main/libs/sysroot/include/pmos/io.h#L20
(and I haven't needed to do 64 bit mmio accesses on x86)
(if you want 64 bit accesses, you just replace movl with movq)
why not just enforce *ax everywhere
instead of a bespoke pci_mmio_read
idk, it lets the compiler do more optimizations I guess
*ax isn’t even bad for general MMIO and it won’t really hurt the compiler given it’s the return register for reads and an extra mov and xor for writes if it dosnt inline and optimize it
Modern compilers will do just fine
it didn't feel good to me
you have all of these registers, why restrict yourself for eax for no reason
if a hypervisor has a skill issue with everything else, it's on them
thiiiiiiis mayhaaaps?
static inline void mmioWrite64(uint64_t address, uint64_t reg, uint64_t value) {
__asm__ volatile ("mov %%rax, (%0)" :: "r"(address + reg), "a"(value));
}
static inline uint64_t mmioRead64(uint64_t address, uint64_t reg) {
uint64_t ret{};
__asm__ volatile ("mov (%1), %%rax" : "=a"(ret) : "r"(address + reg));
return ret;
}
inline uint64_t mmioRead64(uint64_t *ptr)
{
uint64_t data;
asm volatile ("movq %1, %k0" : "=a"(data) : "o"(*ptr) : "memory");
return data;
}
inline void mmioWrite64(uint64_t *ptr, uint64_t data)
{
asm volatile("movq %k0, %1" :: "a"(data), "o"(*ptr) : "memory");
}
Also, why are you using uint64_t for pointers
Just no
It becomes a mess, trust me
instead of passing a register, you can just pass address + reg as pointer
Iirc this should also do the x86 vector access thing
like this can compile to something like movq %rax, 20(%rdx, %ecx, 8)
hpetSleep works now! 
Looks cool
what twas the issue
Btw if u wanna garuntee inline, you can do so with __attribute__ on gcc
Jst sayin
I'm guessing my mmio functions 
the compiler should be allowed to do its own optimization
if its static inline for somthing small like that it will anyways
im saying if for any reason you need it
Nah, it's inline so that there are no duplicate symbols
like inline doesn't actually mean inline in C/C++ since forever?
(I mean idk about C, but it's in C++ for sure)
Inline means inline
Ik abt the way it works for linking tho dw
thats static??
No
since C++ 17
Yes, since 10 years ago
An inline function or variable(since C++17) with external linkage (e.g. not declared static)
Because the meaning of the keyword inline for functions came to mean "multiple definitions are permitted" rather than "inlining is preferred" since C++98, that meaning was extended to variables.
Idk what the standard says, but it's clearly "don't complain about multiple definitions" to me
and static means local to the file
it disables external linkage of it
or makes it persist across function calls for local vars
yeah
lol, interrupts were disabled and I wasn't getting anything :p
works now! 
I dunno if I want to insure interrupts are enabled, but for testing purposes, I have 
now I need to add support for x2APIC
and just generally clean up the code some
but for now I work on scheduler
Btw it’s the same thing
Just MSRs instead of MMIO
I'll probably also work on enabling the IOAPIC and IRQLs when I get back from break :3
And diffrent offsets
And one register is different and needs a special case
(For the better)
you need iommu for that
Why would u need iommu for it
so that you can use lapic IDs > 256
Idk, both Intel and AMD went "all operating systems support iommu anyway, so we won't bother with new msi format"
"use" for MSIs
u can still use them just fine
just dont map interrupts to them
but you still can't just replace xapic code with x2apic, and not run into issues
you've got to handle this in interrupt allocation code
u can, u just have to have an if statement in irq_allocate or wahtever
alright so yesterday I got a simple PE loader working
Today I'll be working on syscalls and then hopefully actually executing the PE in usermode

it doesn't actually do anything yet tho 
it does swapgs, shows what syscall was invoked, and then immediately halts
Add a syscall for printing a string (and for a challenge make it safe
)
And then make one for exiting
So you can make a hello world for your kernel
yup, that's what I was going to do 👍
Btw you may need a special reaper thread
Where it’s entire job is to gather threads that exited
And to reclaim all the memory
ah ye, okay :3
Basically it would be pretty bad™ if you freed your own stack while your using it lol
true 
oh, that actually just... worked... was kind of expecting it to break tbh
anyhow lemme make it switch to the kernel stack
Me when your running kernel code with a userspace controlled stack
🥀
Oh wait
XD
you're fine lol
struct SyscallRegs {
u64 rax = {};
u64 rbx = {};
u64 rcx = {};
u64 rdx = {};
u64 rsi = {};
u64 rdi = {};
u64 r8 = {};
u64 r9 = {};
u64 r10 = {};
u64 r11 = {};
u64 r12 = {};
u64 r13 = {};
u64 r14 = {};
u64 r15 = {};
};
the struct for it btw
if you want
I think they can make it themselves lol
Also the = {} stuff is redundant
srry
youre always just sending random snippets of code
Like if you’re gonna share structures, atleast make sure it’s somewhat not completely trivial?
which are obviously not universally applicable
and also ofc spoonfeeding in general is bad
okie we swap to the kernel stack now 
now I need to figure out why CS and SS are being wonky 😭
probably
And your GDT being miss matched
uint64_t star = (static_cast<uint64_t>(0x18 | 3) << 48) | (static_cast<uint64_t>(0x08) << 32);
wrmsr(IA32_STAR, star);
and does this match with your GDT

uint64_t star = ((uint64_t)(0x18 | 3) << 48) | ((uint64_t)0x08 << 32);
it looks like you ripped this straight from me
but C++'d it
yes I did 
the CPU uses the values you program to assume parts of your GDT
And if you iretq you will fucking explode
Because they don’t match
I was exploding because I had dropped the | 3
Which only breaks AMD
But not Intel

ofc 🥀
So imagine the shock when others testing my shit
When it dosnt break
And then I Goto an Intel machine to test it
And it dosnt break
😭
I fucking hate syscall/sysret


(For context I main an AMD system)
Also for some fucking reason
This broke on my machines QEMUS
But not on my laptops QEMU
Which also runs AMD
And it’s also zen3
Both running arch based distros up to date

okie then they're correct :3
I hate my life 🥀
was debugging for like, an hour, just to find out I was using the wrong path in image.sh 😭
works now tho 
Now I need to make the scheduler... actually schedule
A simple scheduler should be pretty trivial
I'm calling it there for today tho
Works on my laptop as well!
Make a proper build system 😭
I dunno how I would go about having an image file build target for meson

You can make a shell script or a makefile that runs shell scripts
And that calls into meson to make the kernel
And the system that makes an initramfs
And then makes an ISO or whatever
And then calls QEMU
So it’s just make run
It compiles everything with meson and runs the build shit
And opens QEMU instantly
OHHH. Good idea
Im like… 99% sure an instruction existed for pushing and popping everything
pusha iirc
not in long mode
Ooh, didnt know that
yeah you'd expect a pushaq or pusha64
Ig it wasn’t worth it considering there are 8 more gprs
- tbh the only use for this instruction is in space confined code
Like the mbr
There are few places you want to push all gprs
makes sense
the only one I can think about is an interrupt/syscall handler
but even then
it's just not worth it
It’s also not that much code size to do it
Debugging?
You want to be able to capture state
And fork() also needs you to save all registers
i think they meant not worth its own instruction
you are in long mode
i think pusha might cause some trouble sometimes
you have the code space
from what i read, it also pushes rsp
Yes it does
in something like the mbr
💀
pusha is fucking invaluable
yep
pushing rsp is very bad sometimes
BRUH
Why dosnt it also push the RIP for the lols
I have no clue why it pushs the sp
ig it was useful to have the sp of the start of the pusha frame?
but even then
what?
?
this instruction is just confusing
Alignment
yeah
It’s technically a GPR too
i avoided it for that reason
in the most annoyingly correct way ugh
I mean okay
the instruction does fault if esp contains 7, 9, 11, 13, or 15
sooooo
😭
tf
tldr
intel worded it fucking poorly
what I assume they mean
is if sp is not aligned to 8 fault
then why 11, 13 or 15?
So I can’t use address 13000 for my stack?
Which is aligned
idk 😭
no...
that instruction is so bad
there still is something like that i think
thats what i was abt 2 say lol
AMD*
ok no there is not
fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck
I was wrong on the internet
And it’s probably easier to optimize many seperate register pushes
3:
was gonna word it along the lines of "if the least sig bit is set, it faults (from what i see)"
probably gonna work on the build system some
also apparently when an exception occurs in userspace we crash and burn 
that's certainly not supposed to happen
You need to check if it happened there
And then kill the process
Similar to the kill syscall or so
Though if your just starting out with userspace it’s a good thing imo to be able to catch the fault right there tbh
no like I triple fault, doesn't even get to the exception handler :p
Do you not have an RSP0 in your TSS?
Or IST for double faults?
You have your TSS working right 
RSP0 should be set, but I suppose I can check
actually wait
no
I don't think it is
:p
lemme fix that
💀
okay yeah it works fine now
XD
each thread should have its own rsp0 btw
ye they do
do you update it in the tss, right?
yes
perfect
also another thing, use different ISTs for NMIs, exceptions and some other interrupts
if you aren't already
remember to allocate those ISTs in the TSS too
I'll fix it when I get off break lol
Tbh I can’t even tell what’s wrong with it so
it's moreso on the code side
This is the rewrite 🥀

ah, case and point, it doesn't work under KVM 
F
💀
Lmfao
Does it work on real hardware
uhhh, lemme check
XD
just a pagefault, f
okay I'm going to try and write a terminate syscall
which I presume I'd need some way of knowing what process a thread belongs to
Would this be for killing the current process?
I suppose I could just store a pointer to the process in the thread struct?
yeah
Yes
why not port mlibc
and implement those syscalls
it should work better
does this have anything to do with mlibc?
well, it would give them the args they should expect in that syscall
it would make it easier to fully port later
what are mlibc's sysdeps anyhow 
my kernel doesn't
this yes
i just save the parent PID in the thread struct, lol
so uhhhhh
been a while

took a lil break
probably not gonna do anything major atm but I will go around fixing some stuff
I'll also probably end up messing around with object management some
ugghhhhh
well ig I can't just wait around all day and hope and pray I get the motivation to work on this
:p
so uhhh
objects it is ig :p
blkvhajklfad
I still haven't done anything 😭
gonna try and get xbstrap setup either today or tmrw
oh yeah, also gonna see if I can try to understand the FreeBSD VM stuff
wish me luck :p
I wish you luck
study netbsd instead
netbsd's UVM is really good
ah true, I do recall hearing something about UVM
freebsd's is good but it still does old shitty unix stuff like shadow object chains
for cow
actually at your level i wouldnt even try reading that code honestly, id rather read a generic book on whatever OS interests you
fair
freebsd design and implementation is pretty good
yeah I was def gonna read that, if I can keep my attention for long enough 
alright
gonna try and figure out xbstrap
let's see how long this takes
debating whether or not I should put the kernel into it's own separate repo, or just keep everything in one big repo
Separate repo is definitely a good idea
You want to be able to compare different versions of the kernel against userspace if debugging for example
It also just reduces pollution in commits
yoo hows the os going
w w
my bad internet doesnt allow me to build snow os
oof
methinks I should probably add support for kernel threads
I only have userspace ones atm
honestly I think imma just rewrite the scheduler/process creation stuff :p
also you should fix your git repo because it errors out
compiling on linux doesnt work
frick
Ofc it doesn't 
it dont work on linux btw
Haven't worked on this in a bit :p
anyhow
we schedule threads now (again) 
kernel threads anyhow
I mean user threads will also work
but rn the scheduler just blindly assumes all threads are of the same privilege level so
did what I just say make any sense? 
idk
I don't think it did
anyhow
no wait

