#Zinnia
1 messages · Page 4 of 1
ive never seriously written C++
there's libasync
doesnt it hard require stl
freestnd-cxx-hdrs ?
also afaik it doesnt do oom safety
Why do people love async IO syscalls that much? Is it not way simpler to wrap a blocking IO op in a thread and thus make it nonblocking?
simpler yes, faster no
threads are expensive
very
I looked at this recently, why is it even in a .cpp file
https://github.com/iillis/Hirie/blob/main/src%2Fhirie.cpp
Simple Graphic Engine. Contribute to iillis/Hirie development by creating an account on GitHub.
How so? Just curious
i don't want any external libraries besides uacpi (and maybe smoldtb)
they need a stack, making them requires syscalls
scheduling more threads is pretty expensive
and rescheduling into a different thread is very expensive too
because its a syscall
hm
maybe i should just scratch async
too much effort
not like i'm trying to do linux roleplay 
lol fair
that's the main motivation behind keeping things simple
but actually, C++ isn't a bad shout
i probably want a better type "safety"
I feel like with a microkernel you won't have any use for an async pipeline inside the kernel since anything but primitive I/O is moved into user space
you still want to be able to do nonblocking IPC
how so?
you need to allocate shared memory
most likely quite a lot of it
for every pair of processes that communicate
I mean that's up to the process
the kernel should just deliver utilities for shared memory
and locking
use core::{
ops::{Deref, DerefMut},
sync::atomic::{AtomicBool, AtomicUsize},
};
use alloc::sync::Arc;
use crate::{global::GlobalData, heap::ProcessNumaHeapAllocator, random::CSPRNG};
use super::{arch::cpu, memory::VirtLv1PageAddress};
pub const TLS: CoreLocalPointer = CoreLocalPointer();
pub struct CoreLocalPointer();
impl Deref for CoreLocalPointer {
type Target = CoreLocalData;
fn deref(&self) -> &CoreLocalData {
unsafe { &*cpu::get_cl_pointer() }
}
}
impl DerefMut for CoreLocalPointer {
fn deref_mut(&mut self) -> &mut CoreLocalData {
unsafe { &mut *cpu::get_cl_pointer() }
}
}
pub struct CoreLocalData {
pub(super) arch_data: [u8; 64], //TODO move it into a concrete type definded in arch::*
pub core_id: u64,
pub core_csprng: CSPRNG,
pub system_plm_offset: VirtLv1PageAddress,
pub process_plm_offset: VirtLv1PageAddress, //Move to a dedicated struct later
pub global_data: Arc<GlobalData>,
pub thread_data: TlsData,
//pub process_data
}
impl Drop for CoreLocalData {
fn drop(&mut self) {
panic!("Undroppable Value Dropped")
}
}
pub struct TlsData {
pub process_id: u32,
pub local_heap: ProcessNumaHeapAllocator,
pub held_locks: AtomicUsize,
pub yield_to_scheduler: AtomicBool,
pub current_plm_offset: VirtLv1PageAddress,
}
ah
okay i am probably going to take this
yea fuck it i'm going through with the rust rewrite
i like my interface design so much better than the C version
someone please tell me wtf gnulib is doing
i've been here for a solid 5 minutes
i fucking hate gnu
this is why we use tarballs
gnulib is shipped inside tarballs
also tarballs are provided using better mirrors
ah
i kinda wish i could go with the llvm toolchain (like chimera) but my patches don't work yet 
soon
™️
who says you need to patch llvm 
just tell it you're targeting freestanding and pass in all the defines and sysroot from the command line in configure
im definetly not putting off adding my own toolchain to llvm
nooo (but seriously take a break and come back with fresh ideas, I find that always helps me if I get stuck)
thx
@spark surge does limine not give a shit where the executable wants to load even if it's at !0 when ET_DYN?
disable KASLR?
oh true
i was gonna yap about how this unclear from the protocol doc but who cares
reading helps
do you pass -cpu host to qemu?
could also just measure the frequency via some other timer
iirc amd cpus don't have the frequency in msrs
i don't really want to use the tsc to begin with
why not?
i mean what other timer are you gonna use
fair, although when available the tsc is the nicest imo
well, at the point of enabling it i would need another timer to calibrate it
i guess i can give it higher prio than the HPET at least
or actually, i should move cpu init after firmware init
yea then i can also use the tsc
@idle flower need uacpi-rs
most cases you can get away without calibration for invariant tsc, and in vms which dont pass that information through you can use kvm clock
and maybe fallback to hpet
that covers about 99.5% of modern machines
imo
u can figure out the frequency using cpuid
where
.
this doesn't work
yeah some hosts dont pass that info through
so just use kvm clock
but it's there on real hw?
pretty sure if you have invariant tsc you have that
but idr
would be a good idea to check lol
i wonder if you can find info about that online
or maybe the sdm
im on phone so kinda hard to browse the sdm
the main advantage is that it's just 1 insn to read vs having to do mmio
true
and with x2apic scheduling a deadline interrupt is a single msr write
in tsc deadline mode
invariant tsc + tsc deadline is the best you can get on x86
realistically
rolls over in god knows how long, dead simple to use, only downside is the calibration sometimes
actually nvm, it's always an msr write
setting it up in xapic mode could be mmio though
but really you do it only once
and it doesnt go through pch
yeah the lapic config might require mmio
so who cares
but the deadline is an msr
lapic accesses are caught by the cpu
always
yeah thats nice
I'm doing this now
i still need to convert the other cases to use Hz
huh
what unit is the tsc frequency in
or rather
how do i properly convert to nanosecs
stamp * 1e9 / freq
uh
makes sense, the initial value of the tsc is whatever
on real hw it'd at least include time spent in bios and the bootloader etc
oh i didn't pay attention to the large jumps between values
this is all i have rn
atm it takes the second branch
and the tsc is cpu local, right?
hm, how would i best represent that in code?
i have one central module that does timekeeping
but i would potentially need to keep a record of the different frequencies, no?
linux assumes the frequencies are the same on all cores
ah
okay that makes it easy then
very cool
maybe that messes with big.little stuff?
who knows
which apis do you need first?
okay super weird
in order to make this actually calculate the correct value i have to multiply by 1000?
what
this looks wrong
in the calibration loop, why do you not read both the TSC and the reference clock before and after the wait? you might've been preempted in between.
this runs before the scheduler
i.e.
t1 = read_tsc ();
ref1 = read_ref ();
sleep;
t2 = read_tsc ();
ref2 = read_hpet ();
regardless, it is a good idea
what would that get me
better measurements probably
in what way
it is quite likely that wait_ns waits slightly longer than 1s
that is mitigated by reading both the tsc and the reference clock before and after
iirc I did like a 100ms calibration loop, and that gives me very accurate measurements
yea 1s is probably overkill
however you can calibrate over a longer time period. for example by scheduling a timer event for 1s into the future, and recalibrating the TSC then. syncing the recalibrated TSC to other CPUs might be a little tricky, though.
as in,
- measure tsc and ref
- sleep >=1s (+ scheduling jitter)
- measure tsc and ref
okay i think i know what went wrong
i didn't check for the 0x15 leaf
i only check for the tsc bit
I hope you mean the invariant tsc bit too?
lol
midnight coding
ill fix in the morning
pragmatic means it works on my machine
call that optimization
hm
okay checking the leaf didn't work either
Leaves 0x15 and 0x16 are quite new I believe, and are only available on intel cpus.
You'll want to support calibrating the tsc with another timer (hpet, acpi, pit) or if you're running under KVM you can use pvclock which gives you all the info you need.
i would use the hpet if uacpi-rs was ready 
didn't you say you were giving up on rust?
.
i'm bipolar probably
idk
i change my opinion on things every day
real
just write some interop code so you can write your kernel in C, C++, and Rust depending on your mood 
also the hpet really isnt that hard to do yourself
i had that ironically
it's not about that
its just an acpi table and some mmio
cursed
i already had hpet in C
but i need uacpi bindings
because i dont want to duplicate table defs
the table always has the same in memory layout, just memcpy it 
rust
i have a transmute thing
fuckin uh unsafe { std::mem::transmute } it
"""safe""" 
yes safe
incredible that rust needs a library to read(fd, buffer, sizeof(buffer))
what will they think of next
yep, thats truly insane
if the C++ comittee was like 30% less brain damaged rust would be screwed 
more democracy into C++
sadly this is not a perfect world
developers vote for features
take a look at this
lol, lmao even
rofl, if you feel so inclined
i mean
i get their point
reading random data into structures is generally not a good idea
just dont deserialize anything
if you can guarantee that it's not bogus (like POD types) it's fine
keep everything in memory 
uhhh
this is going to make reading from disk really fun
tbh i might just make that part unsafe to get some speed
not an argument btw
rust users when they need to store indicies into global arrays but its definetly not shared mutable state because borrowck is ok with it
a common style of pattern i was forced into when i was experimenting with rust (don't blame me for it, a lot of people experiment with rust in their youth)
take when i was wondering how to express a graph structure in rust
the pattern i was told to use was have nodes instead of pointing to other nodes directly, instead have indexes into some node vector or similar
it can be argued this is in fact less safe
just Arc it 
because if you run your C program with valgrind, you can in fact get nice errors if you try to dereference a pointer to a node that was deallocated. but with indices or some other kind of identifier, you'd need to add your own logic for never reusing identifiers in a debug mode
Yea this is the kind of stuff that's annoying
I tend to have to do a lot of hacks like that
bruh
I am fucking tired from explaining people "having to use unsafe" is not an argument
outside of my kernel and some langdev project where I was doing pointer tagging (which is obviously hilariously unsafe) I've used the unsafe keyword maybe 10 times
and like 6 of them was for FFI
it was a joke
borrowck is still borrowcking the global arrays unless you're doing something very wrong
hence the trollface
and Weak<> exists
yea not necessarily targeted at you I should have made that clear
just something I hear very often (and often unironically)
this is usually very bad lol it's worse than most transmutes
chonky boi

tcg doesn't have invariant tsc
you can't enable it
at least I don't think you can
smh "at list"
I just wrote a linked list
at list
i hate it
is there another timer i can use without acpi
pit 

kvm pvclock
but as you would imagine, only on kvm
duh
I mean uacpi rs has table support no?
i dunno what the state is

hm, looking at my old interrupt code rn
how would i "rustify" this signature
is there a way to not have to resort to a void*?
some generic bs maybe?
idk
actually I think it works if your host cpu supports it but qemu doesnt report it
which is retarded ofc
Just box a closure and you'll have all the context that you want
what
I dont think a box here would work
that would require memory allocation
You don't need to allocate them in the interrupt handler, you can just make an array of boxed closures that act as irq handlers
yea but isnt Box on the heap
can yall give some example
he's looking for a way to store a pointer to callbacks
which boxed closure would be the solution in userspace
You also have alloc in no_std rust
I think just an array of fns would work no?
this is not my problem
ah the context
yea just use *u8 or something
theres not really a way to make it generic and safe I think?
unless you make each irq a different type
yea i couldnt think of anythin either
Or you'd need to use the heap and do dynamic dispatch, but if you don't have inizialized an heap you really can't
rn i do this
idr rust but something like
type Irq32Handler = IrqHandler<Irq32Context>
i have heap at that point
yeah
I just assumed no heap
Then you can make irq_handler an array of boxed closures like this: [Box<dyn Fn()>; 256]
what's the point of doing that
does it not?
so the interrupt has device specific info
theres probably a better way to design this
linux does it this way :P
ofc linux is not perfect
but it has its uses
also global state = yuck
this is a microkernel, right?
the NT way is using DPCs and stuff
which is probably what you want anyway
i have no idea about any of that honestly
is it normal for qemu tcg to say my TSS is TSS64-avl, but kvm to say it's TSS64-busy
i mean it doesn't matter since it goes through, but i seem to be doing everything like the SDM wants it
For dynamic linking?
kinda
my C version could either link the code dynamically as a module or have it be built into the kernel
maybe i should drop builtin support altogether
you want to dynamically link rust-rs to your kernel?
rust-rs?
uacpi-rs
a project afaik
til
yes afaik rlibs are not real binaries but rusts intermediate language which has the same version stability as the rust abi currently aka none
like std and core are shipped as a rlib
@spark surge what's the actual difference between the exec file feature cmdline vs the cmdline feature?
does the latter simply not allocate the kernel file?
they are the same
the latter is a short hand for the former
so how does it work? does it always allocate the kernel file?
id like to avoid using memory that i don't need
well it has to load the kernel file into memory to load it i guess
and instead of freeing it, it's just passed along to the kernel in a response
don't worry about it kitten
🥺
@spark flax
osdev kittens
you can reclaim it if you need the memory
hello
bruh this is new
im stupid
rela stuff has to be in the text segment
okay i should print what symbol is unresolved
ah i see the problem
because i link the .dynsym and .dynstr as PT_LOAD, limine can't access them anymore as they are now in virtual space

@spark surge is this something PR worthy?#
are they supposed to be PT_LOAD?
just make limine provide u with the kernel binary?
i had a typo
but still
unresolved symbols should maybe be ignored?
not sure if it's panic worthy
it was a fault on my side
limine does handle symbol table offsets properly
i had a typo in my linker script, but since i compile the kernel as a dynamic library, it simply does weak linkage
which limine doesn't like
maybe it could print which symbol is unresolved 
@spark surge
thx
why not resolve the index to a string
yeah that's a fair point
ah sry
i'll force push this commit away
then you can send one all together with the fixed commit msg
@spark surge like this?
yeah i guess
looks aight to me
dope
@near tartan Marvin alt
melvin
marvins evil twin
he probably works at redhat
are you sure he is the evil one
i need some rust gods to help me
for some reason rust includes sse2 shit in my build
but my target turns it off
that's uhhh
funny
okay it's triggered by BTreeMap::insert
but wtf is it doingggg
never mind
me when i double lock 🗿
what the fuck is this code
this shit sucks so bad
lmfao
Lock one more time just to be sure
idk
it's interesting though
my allocator is completely fucked
because the translation from C is incorrect
the page wise allocation works
yay
does the rust stdlib not just come with a pile of premade allocators for you
no
oh
why would it
idk it seems like the sort of language that would
no language does afaik
zig does
well, theres probably allocator crates
how does it work in no_std
the allocators just take void *ptr, size_t size in their constructor
then allocate from that
i dont really see how that can work in a no_std environment
i dont see why it doesnt
for some of them you can iirc
i mean i've got like half a dozen allocators i've stolen off github that were made for hosted targets that work just fine freestanding
its not a particularly hard thing to do even by accident
if you've got a block of memory to allocate from you can store all your control structures in it
im tempted to just use a crate for allocations
zig has an Allocator api, basically an opaque pointer + vtable pointer that has a few methods like allocate, reallocate, free
it can ship allocators in the std because they are built on top of each other, a GeneralPurposeAllocator needs a backing allocator which can provide memory for it and by default it's std.mem.page_allocator which uses mmap in userland but you can override it to do what you want iirc, or just tell GPA to use your own allocator which can call into pmm + map the pages
no shame in using a crate for an allocator
if its a bad crate, lots of shame
imo
this design has one flaw which is that it makes cpu speculation unhappy
because vtables slow
they aren't that slow
almost the same as regular pointers to functions
and can be the same in some cases

any recommendations?
this one looks nice
also has oom handling
i mean given that macos malloc uses a vtable dispatch on the critical path
yeah lol
i NIHed mine
if you want a general purpose one, i.e. not for a kernel, dlmalloc probably
for a kernel 
my slab impl isn't rusty at all
it's just a huge unsafe block
thats fine tbh
and doesn't work
oh thats less fine :^)
yea
only page wise allocations work
some sort of corruption happening
but i cant be asked ngl
lol
🗿 the redox slab impl is fucking shit
lol
this is the allocator from shkwve: https://paste.sr.ht/~pitust/43699e812923d956c892d94cbfd9b204624a6866
i think i'll just use talc
hows rust osdev so far
it's not too bad
you have a few global state anchors here and there
but the rest feels pretty nice
page mapping is the worst offender, that's almost purely unsafe
but it'll be way more fun when i'm building abstractions around this
now that the allocator is actually fast + efficient, i don't really have a lot of things left to do on the low level / mostly unsafe side
thats nice
next step is remaking the vfs and fs abstractions
i want to focus more on fuse support
i think i will buy this thing https://de.aliexpress.com/item/1005006965588873.html
there are
e.g. there's linked_list_allocator
already done :)
port managarm 
bet
i already have a wip mlibc port
this is the most useless fucking table ever
the loongarch manual is ass
okay it's just the html version
mental illness
yes, please give me XVFRSQRTE.D apples
the names makes sense though? eXtended Vector Floating-point Reciprocal SQRT Estimate (dot) Double-precision
i did cheat slightly, i had to look up what the E stood for
but the other parts are pretty obvious
didn't say that it doesn't make sense
x86 simd instructions aren't better in this regard
okay i need to finish the mlibc loongarch port sometime soon
i need it to build limine
@near tartan is the rust menix public?
yes
different branch
ill switch to it as the main branch once i have everything back to the state of the C version
still missing are the scheduler, vfs and fbcon
ah the joys of writing an llvm toolchain
i must've rebuilt llvm 50 times over 3 days when i did mine
#
question
👁️
how do you deal with compiler built ins
i can't use libgcc
but for some reason i can't build libclang_rt.builtins.a either
oh that was a fun one
just implement yourself lool

you know what is a skill gap
so you build llvm for the build machine including compiler-rt, then install the headers for your libc, configure llvm again to only build libc++ and compiler-rt using your own sysroot, and then you can use that
being a mlibc maintainer but being scared to merge things but at the same time literally no one is telling me yes or no
trolled
what about 1323 btw
remember to specify -DCMAKE_C_COMPILER_WORKS=1 -DCMAKE_CXX_COMPILER_WORKS=1 when configuring libc++ and libunwind for your target
whenever korona tells me "ok"
so next week 
or Arsen
this is my full option set until i have a working rtld implementation
or ideally both
it's really fucking annoying
i am quite burnt out about PRs
then dont make them 
i've been sending many PRs, so many that i lost count
not just to mlibc
to other things too
it's so annoying, you just wait on other people and often other people are dead
and you're just sitting there waiting
i am losing my marbles
do you have a full set of build instructions?
open source development is a failure
oh wrong paste my bad
https://github.com/apache-hb/BezOS/tree/master/repo/packages/tools you'll probably care about llvm-libcxx.xml and llvm-compiler-rt.xml
interesting build system
and this is the patch for my toolchain https://github.com/apache-hb/BezOS/blob/master/repo/patches/llvm/add-bezos.patch
Perhaps wacky, one might even say crazy, im losing my mind, my marbles, my bananas, im falling off my rocker so to speak
dont worry about it 
i hate yaml more than i hate xml
fair
just press the merge button
you're an mlibc maintainer anyway
just say you're following googles live at head policy and that breaking other peoples builds simply improves product quality
thats to build them for the build machine
you're not gaslighting mint are you 
I'm just joking
miracle
lfg
no that's actually not what he said
i think he wants me to add a mlibc-crossers for loongarch
mlibc/mlibc when
what's the point again
none really
pedantry
he wants to have a "proper" "targetted" "toolchain" even though in this case it makes hardly any difference practically other than making the CI more annoying
am i blind
i see some strings at 2080h
but where's the metadata
also what if you just used an elf section to store your metadata
like .note.menix-module or smth
guess what
that is the metadata
it contains module name + description + author + dependencies
yeah that's what i gathered :^) but they look like unterminated strings, which means you have to store the length somewhere
i store them in the phdrs
ahh that makes sense
what if a module wants to have more than 255 dependencies with names longer than 255 characters
i think u might be cooking with dt_needed
yea
i could've made it use usize but dt_needed is cooler
@hoary cave hell yes
seems to work
epic
how do modules work? how are dependencies defined? do modules expose a C API or are they just regular rust crates?
so you can basically use any public module from your kernel in your modules
same with other modules
that is kinda cool
yep
this is already much cleaner than the C version
where you had to hardcode your module dependencies
this is how you use it
yeah i checked out the code
looks pretty nice
but the question is, how do i contribute :^)
wow i am blind
yeah looks about what i'd expect
but it was more of a question of uhh
what needs to be done
ah
i can open up some feature requests
there's a lot that needs porting from C
most importantly vfs
:^)
i see
also the scheduler is not in yet, but that's kinda blocked by uacpi-rs
scheduler needs interrupt needs timer needs hpet needs uacpi
I haven't checked the state of uacpi-rs yet
ye
should be enough
i have a pretty large diff rn with the module changes
and the module loader
question is
are the kernel and modules going to fit in the -2GiB address space
probably
then i can just load kernel modules after LD_KERNEL_END
you can, and you probably should, give them a chunk from the 0xffff'8000'0000'0000..0xffff'ffff'7fff'ffff address range
but what's left after the kernel end is probably more than enough lol
but keep in mind KASLR could make that smaller
the c version just hard mapped it to 0xffffc..+
good point
i don't see any way to have the dylibs not named libfoo.so
is there a way to do that with cargo?
like instead of naming it libfoo.so => foo.ko
but not a big deal if not
.ko implies it's an object, which it isn't
but i think you can change that in your target spec json
It is an object tho
yeah but it's a shared object
ohh
linux is using normal objects, that is true
thats why i said that .ko is a bit misleading
but not entirely untrue, it is an object
.kso
lol
you can use dll_prefix to remove the "lib" i think
meh
not that big of a deal
i now store version, author and description
the rest i can encode in the elf
{
"dll_prefix": "",
"dll_suffix": ".kso",
}```
like entry point, dependencies, name
:^)
where
target json
ah
i think you can just slap that at the top level
i dont know if there's a way to do this globally instead of per-target
the dll_suffix might be wrong but i think that's what i did last time
might need to remove the dot idk
ah i got trolled
it makes sense
but yeah empty prefix and .kso suffix will produce foo.kso
lfg
hell yeah
@hoary cave i'm going to add some cards in the github kanban board
i made it private 🤦♂️
oops lmao
yup issues are there
i probably want to redesign the vfs because the c version sucked major balls
also wasn't your plan to make a microkernel?
#1287456798407790684 message
it's cool but ultimately too much work imo
my goal with menix is to have some sort of desktop and oss games running on it
how original

i mean making it run on all 4 platforms will be cooler than it being able to do wayland/xorg
imo
true
if i do ever get my hands on hardware, i would also consider ppc64 support
but for now uefi/acpi based systems seem like a good base
i have a few aarch64 devices with acpi
i don't, but i have an m1 mac that i can probably try to get menix running on which should be fun :^)
once the aarch64 port is up of course
yep
well i should add support for it sooner or later if i want to realistically run on !x86
device tree boot
like acpi vs dt?
ye
only a stub
when it checks for xsdp/dtb
i will prefer acpi 100% if i get the xsdp
but i think uboot efi emu should be decent enough to boot from
based
multiboot would be a nice addition
even though
the protocol is absolute dogshit
it's still nice to have diversity
you can pr it in 
you only need to call 3 functions and add a feature for it
i wonder how putting it all in one binary will work
that would work, yes
then i could also just map my own hhdm instead of having to stick what limine gives me
actually yes, let's try doing that
yeah at that point kernel doesn't care what booted it
that's the better abstraction probably
at the very beginning of the rewrite i was planning to do that but i failed to come up with a good way to share e.g. vmm code
yes
why would you need to do that
i mean
i guess the code deduplication is nice
but it's like 100 lines of code you need for the page table manipulation
it's not that big of a deal imo
maybe the uptick in effort is not worth it lol
fair
hm
i need to think this through
maybe the prekernel can also handle smp setup?
no that would be dumb
i need to be able to control cpus at runtime
you could do it in the prekernel to save yourself some trampolines
like
i would also need cpu setup code in both binaries
and the acpi stuff should also be part of the kernel
yea no i think that's easier
just let it be a boot proto abstraction
for now
i wonder if there's a way to get rid of .rustc
it currently takes up 50% of the kernel size
/DISCARD/ : { (*.rustc*) } and see what happens 
dies
damn
it "needs" it to link
but i don't actually need it to load
it's NOLOAD anyways
but it's annoying
What does it contain?
get rid of it by rewriting in c++
🤫
i'm experimenting
trying to find a nice and ergonomic api for accessing packed structures
SpecFieldLE + SpecFieldBE maybe?
struct DtbHeader;
impl DtbHeader {
const MAGIC: SpecField<u32> = SpecField::new_ne(0);
const TOTAL_SIZE: SpecField<u32> = SpecField::new_ne(4);
const OFF_DT_STRUCT: SpecField<u32> = SpecField::new_ne(8);
// ...
}
fn test() {
// ...
_ = space.read(DtbHeader::MAGIC);
}```
/// Aligns a value to the next higher multiple of `alignment`.
pub const fn align_up(value: usize, alignment: usize) -> usize {
return value.div_ceil(alignment) * alignment;
}
/// Aligns a value to the next lower multiple of `alignment`.
pub const fn align_down(value: usize, alignment: usize) -> usize {
return (value / alignment) * alignment;
}
pub trait Primitive: Copy + Default {
fn swap_bytes(self) -> Self;
fn from_ne_bytes(buf: &[u8]) -> Self {
#[cfg(target_endian = "little")]
return Self::from_le_bytes(buf);
#[cfg(target_endian = "big")]
return Self::from_be_bytes(buf);
}
fn from_le_bytes(buf: &[u8]) -> Self;
fn from_be_bytes(buf: &[u8]) -> Self;
fn to_ne_bytes(self, buf: &mut [u8]) {
#[cfg(target_endian = "little")]
self.to_le_bytes(buf);
#[cfg(target_endian = "big")]
self.to_be_bytes(buf);
}
fn to_le_bytes(self, buf: &mut [u8]);
fn to_be_bytes(self, buf: &mut [u8]);
}
macro_rules! impl_primitive {
($($ty:ty),*) => {
$(impl Primitive for $ty {fn swap_bytes(self) -> Self {<$ty>::swap_bytes(self)}
fn from_le_bytes(buf: &[u8]) -> Self {<$ty>::from_le_bytes(buf.try_into().unwrap())}
fn from_be_bytes(buf: &[u8]) -> Self {<$ty>::from_be_bytes(buf.try_into().unwrap())}
fn to_le_bytes(buf: &[u8]) -> Self {<$ty>::to_le_bytes(buf.try_into().unwrap())}
fn to_be_bytes(buf: &[u8]) -> Self {<$ty>::to_be_bytes(buf.try_into().unwrap())}
})*
};
}
impl_primitive!(
i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize
);
firmware/fdt.rs
// OpenFirmware flattened device tree handling.
use crate::generic::spec::MemoryField;
struct DtbHeader;
impl DtbHeader {
const MAGIC: MemoryField<u32> = MemoryField::new_be(0);
const TOTALSIZE: MemoryField<u32> = MemoryField::new_be(4);
const OFF_DT_STRUCT: MemoryField<u32> = MemoryField::new_be(8);
const OFF_DT_STRINGS: MemoryField<u32> = MemoryField::new_be(12);
const OFF_MEM_RSVMAP: MemoryField<u32> = MemoryField::new_be(16);
const VERSION: MemoryField<u32> = MemoryField::new_be(20);
const LAST_COMP_VERSION: MemoryField<u32> = MemoryField::new_be(24);
const BOOT_CPUID_PHYS: MemoryField<u32> = MemoryField::new_be(28);
const SIZE_DT_STRINGS: MemoryField<u32> = MemoryField::new_be(32);
const SIZE_DT_STRUCT: MemoryField<u32> = MemoryField::new_be(36);
}
pub fn init(dtb: *const u8) {}
okay col
@hoary cave i solved the .rustc issue
it's only used during compilation, so after the build i can just strip the section from the .ksos
the metadata is irrelevant to the kernel during the actual dynamic linking
and that still works
that's a lot of symbols
i thought you needed the section during runtime to figure out which modules have to be loaded and all?
and to provide metadata, but i wasn't sure what you wanted to do with it
ah right, you get the required modules from DT_NEEDED
that's not the dynamic section
it's just some abi info in .rustc
yeah i know, you are talking about your own metadata section
oh
you mean the .rustc section
i totally missed the dot
lol
vc when
soon
going to take a shower (rare) then eat
first ill do loongarch
(rare)
then mlibc menix
i already ate and had a shower
so i can vc soon too :^)
finishing up jinx stuff probably
or working on mmio thing
no shower = no vc
okay mlibc stuff is almost done
i need to update my gcc patches to take the crts into account
le device has been obtained
might convert into a server for my rack
i might buy this
tbh at this point, targeting a qcom laptop is better than loongarch imo
also since when is menix ported to 4 architectures lol
weren't you rewriting
yea
why not

that's a different story
the rewrite isn't even that far yet
but i want to have a different approach
instead of doing x86_64 only first, i want to work on all 4 ports so i can make the most portable abstractions
i want to have very little arch-specific code in menix
both have uefi, that's enough for me
i tried that and doing page tables for 3 architectures blew my brain out
i tried that and doing page tables for 3 architectures blew my brain out
ok discord wtf
risc-v has the easiest page tables imo
true
what's different?
aarch64 has a lot of different configurations and (n)G(n)R(n)E is comparatively harder to encode IMO
huh
what sort of different configurations?
tbh aarch64 is the arch i know the least about
e.g. 16k pages
linux
i mean in hardware
oh
16k is somewhat common tho
but every UEFI capable device has 4k
i believe something requires the host system to be 16k but in virtualised environments 4k is supported
so the 4k is there in silicon, most probably iboot or something drops you in 16k
or whatever
idk
all that i care about is that snapdragons are 4k
raspberry pis also have 16k as an option
🤢
and raspberry pi is pushing it a little slowly
there's performance gained apparently
btw how did you notice this


i'm on my 9th llvm rebuild