#Retro Rocket OS - A BASIC powered Operating System (started 2009!)
1 messages ยท Page 2 of 1
im not sure where you get them on macos, likely homebrew
or you likely just need to update that path
adding some better error reporting
just spent 3 hours fixing the recursive descent parser madness that causes that error
got some cleanups to do on it tomorrow
but for now, sleep calls!
finally fixed unary operators so that it doesnt require a preparse step to 'represent' negative values without a negative number
Back in the 1980s, kids in Britain cut their teeth on the BBC Micro. Learning to code, exploring BASIC, and seeing what these tiny machines could do.
Retro Rocket is my modern homage: a home-brew OS with its own BASIC shell, graphics demos (yes, even a textured cube!), and working internet access. All written from scratch in C, running here on ...
- Now working on adding missing editor features; added search
- Fixed error where procedures inside functions break the expected return value
- Fixed issue where INSTR doesnt work right and can crash
- Fixed issue with move-to-first variable optimisation burying system variables like TRUE/FALSE and causing runtime errors in BASIC
finally squashed some deep interpreter bugs that were preventing search/replace working in the editor. nearly working now
decided to post on reddit
https://www.reddit.com/r/osdev/comments/1n2r6ti/end_to_end_os_dev_test_showing_graphics/
Added IPV4 loopback support (not needed it until now)
Last night i added:
New BASIC keywords
- OUTPORT
- OUTPORTW
- OUTPORTD
- UDPBIND
- UDPUNBIND
- UDPWRITE
New BASIC functions
- UDPREAD$
- UDPLASTSOURCEPORT
- UDPLASTIP$
- INPORT
- INPORTW
- INPORTD
- BITOR
- BITAND
- BITEOR
- BITNOT
- BITNOR
- BITNAND
- BITXNOR
- BITSHL
- BITSHR
- BITROL
- BITROR
New Programs
A PS2 mouse driver completely written in BASIC where you can query mouse state via a UDP socket on localhost. Needs a bit of testing.
well, it loads and it reads the mouse state. thats a start!
it works! im able to read mouse coordinates while the driver is loaded, by querying its port ๐
UDPBIND "127.0.0.1", 9999
REPEAT
UDPWRITE "127.0.0.1", 9999, 14501, "GET"
PACKET$ = UDPREAD$(9999)
IF PACKET$ <> "" THEN
PRINT PACKET$
ENDIF
UNTIL INKEY$ <> ""
UDPUNBIND "127.0.0.1", 9999
yay
mouse cursor being rendered from a separate program!
we now have working BASIC drivers ๐
i might make a library for getting mouse x/y/b state so i dont need to duplicate this client code, going forward
https://github.com/brainboxdotcc/retro-rocket/blob/master/os/programs/mousetest.rrbasic
PEEK AND POKE, do you feel the DANGER yet?
do you identity map?
yup
retro rocket is: you break it, you keep it
aka mess around and find out
made a user library to interact with the mouse task
and also a page documenting tasks
https://github.com/brainboxdotcc/retro-rocket/wiki/Writing-Tasks
very epics
what exactly is the difference between keywords and functions?
i assume just the syntax to use them?
is there an option for command aliases some people might want to use like OUTB
or OUTW
aliases? nope, it wouldn't be hard to add them though.
just extra entries in an array
happy to accept a pr for it, see src/basic/function.c near the top
that's a crap ton
nice
yeah needed a bunch of them for systems programming
I forgot about the udp ones lol there's even more
oof
there, now they're added to the docs
congrats
im increasing the LAPIC timer from 100hz to 1000hz
various housekeeping tasks run on it that are improved by a higher resolution, such as fragmented packet reassembly
you shouldnt have too many threads running at once, that will compromise responsiveness
you should have support for blocking waits in the kernel if you don't already
(like the thread doesnt get scheduled at all until some event happens)
yes, this is already a thing
right now, a BASIC process has a way to register a lightweight callback that is just expected to say when the thread can be released from sleep state
this isnt part of the timer system
so right now there are 3 processes:
at the time this snapshot of the process state was given to BASIC two processes were waiting on other processes
init was waiting on rocketsh and rocketsh was waiting on proclist
the waiting processes basically dont get scheduled, only their wakeup callback gets scheduled
its kind of hard to describe, because what im describing is an interpreter driven system, not native threads
just massively improved performance by moving the variables into 3 hashmaps instead of 3 linked lists
the linked list stuff was about 15 years old lol
you should make it so retro rocket can run executable files (like elf?) AND basic code
nope not happening, sorry
thats a rabbit hole i dont want the rabbit from
would mean a complete rewrite, to handle native multi tasking, which then means ring 3, because while i can trust my interprter at ring 0 i cant trust user binaries
which then means paging, vmm, and all the other rammel
goes from keep it simple into just what everyone else is doing
@willow ginkgo you might like this
(I know that there were disassemblies of MS BASIC before but this is the real deal)
i think ive seen it
i had the disassembly of bbc basic once, thats very well documented and very clean
I'm curious whether Microsoft BASIC interpreted their BASIC files directly (they weren't plain ASCII files, but tokenized)
or if they ground it down further first
most BASICs back then were tokenized as you entered each line at the REPL
yeah
then strored in ram or on disk tokenized
i skip that step in my basic and just keep it all ASCII, its more portable
these days if i want to read a BBC BASIC program i need a viewer or converter to convert it back to ascii ๐
i think ive covered most of the scalability annoyances of my basic interpterer now
linked lists for var lists was ... ass
you might've seen disassemblies of it as this was published a couple hrs ago
๐
im currently working on properly accounting all bytes that are in use per basic program in proclist
which means moving absolutely everything about the context into the context buddy allocator
problem is stb_image used for sprites
it has no way to pass a context
you override its allocators via #define ๐
#define STBI_NO_STDIO
#define STB_IMAGE_IMPLEMENTATION
#define STBI_NO_SIMD
#define STBI_NO_HDR
#define STBI_NO_THREAD_LOCALS
#define STBI_MALLOC(sz) kmalloc(sz)
#define STBI_REALLOC(p,newsz) krealloc(p,newsz)
#define STBI_FREE(p) kfree(p)
#include <stb_image.h>
gross ๐คฎ
so no way to associate allocations with some owning context
Basic JIT when?
You allow direct port io within basic?
I thought that was your userland or equivalent
yes
direct port io and direct identity mapped access, just like the BASIC of old
peek it, poke it, you break it you keep it
i may put some settings in at some point that restrict which BASIC programs have port io and direct peek/poke and which dont, purely a flag you toggle
its not a multi user system, doesnt intend to be, so its all purely for experimenting.... want to poke at something see what happens? retro rocket got your back
Yeah that would probably be a good idea
But yeah if youโre trying to make basic like back in the day you need that
Cool that you can make drivers within your own system though
Do you plan on doing privilege levels?
I know itโs not a multiuser system but
Yeah kinda like Unix
Maybe certain programs can have privilege level
Like programs that interact with the hardware could require some sort of password or acknowledgement from the user that the program could very well nuke the computer
Like If a program uses port io, make it prompt the user or require something like sudo to make it run due to it being possible to crash
Idk
why would BASIC have a user system
at most just have a popup saying "program might do something funny to system plz beware"
at best just have nothing
Thatโs what I mean
not sure
the itent isnt to restrict stuff much
there are some obvious safeguards like you cant PEEK or POKE ram that doesnt exist (including ram holes)
dont want an obvious pagefault
perhaps some system where the first programs that start, start with ability to do everything
and, programs can disable keywords and functions for child programs, a child program cant then re-enable
so it works like a chroot or jail
so if you want to restrict it, you'd edit init or whatever
cool
Yeah I was thinking about something like chroot
i think if i just provide that, a way for a program to restrict what its child can do
that will be enough
if someone then wants to make permission systems, login prompts, user levels it can all be done thru basic
if i make it so you can also restrict what parts of the filesystem the child can see
is it a microkernel if everything is ring 0 anyway? lol
Probably not
But
You can call it whatever you want
And as long as you believe in it
Itโs the truth
your basic interpreter might be the "user space"
it essentially is, that's the idea, any restrictions are part of the interpreter, no context switches
understandable
really proud of this.... got the LINKER to sort an array by name of the symbol within it
. = ALIGN(8);
__start_kw_array = .;
KEEP(*(SORT_BY_NAME(.kw.*)))
__stop_kw_array = .;
basically takes a whole load of keyword name sections like .kw.ELSE, .kw.FOR
then sorts the section at link time so when you reference it, you get an array of integers, sorted by the name of the keyword
which is needed for fast search of tokens in the tokenizer
i was having to manually maintain two different lists, now i dont
why would you do that with the LINKER first of all
is there a point for this?
oh
nevermind
cool tho congratulations on your linker sorter
i need to read everything before responding :/
lol
just rush right on in there ๐
im currently trying to build an elf64 module loader
so i can move stuff out of the kernel core
yoooooooooooo
actually i wanna try the os how do i boot it (how 2 compile)
git clone, make sure you got gcc, mtools, php, xorriso, nasm... i think thats it
oh and cmake
its a cmake project
or if you cba to build it.... there are github actions that build isos
along with a run.sh
based
have these
is it a cross compiler gcc or just gcc
k
i did have a freestanding cross compiler years ago
but i lost it, didnt bother to reinstall another, and everything just worked fine so 
the superiority of the intel atom ๐ฅ
mine still boots, got ubuntu 16 on it iirc or maybe 14
i dont use it though
only 2gb ram
once i got literally any other laptop from that era the core 2 duo's felt like actual bliss
i had 1 ๐ญ
the ./run.sh the build generates, you might need to adjust
i have it set to host the screen via vnc
you probably dont want that ๐
yeah its qemu
but the qemu run command set vnc for the screen/keyboard etc
just take the -vnc flag out
wait i remembered that the core 2 duo laptop i have matches the system requirements for this i might run it there
qemu-system-x86_64 -machine q35,accel=kvm -s -monitor stdio -cpu host --enable-kvm -smp 8 -m 4096 -drive id=disk,file=../../harddisk0,format=raw,if=none -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -drive file=rr.iso,media=cdrom,if=none,id=sata-cdrom -device ide-cd,drive=sata-cdrom,bus=ahci.1 -no-shutdown -boot d -vnc 0.0.0.0:2 -debugcon file:debug.log -netdev user,id=netuser,hostfwd=udp::2000-:2000 -object filter-dump,id=dump,netdev=netuser,file=dump.dat -device e1000,netdev=netuser
k
its a bit of a monster lol
oh god this config
this is why the cmake outputs the ./run.sh for you, ready to go
oh cool
imagine having to reconfigure it each time
it makes some assumptions: "../../harddisk0" is a 1gb (or however big) empty raw disk image
theres a few hairs, because i havent had many others play with it for a while
does retro rocket (ima just call it rr) format the disk image?
only if you install it via the install option from the boot menu
dangit
i didnt go that far
lame /j
it lacks a couple of features i wasnt sure i wanted to give... like write raw sectors. i'd have to reinvent half the filesystem in basic
i mean understandable
security is gonna be done for if some program just overwrote the hard drive
read raw sectors might be a cool BASIC feature though, imagine a disk sector hex dumper
it's not even supposed to be secure but it would be quite a mindfuck to reinstall this for 554th time
lol
would be cool
i reinstall mine like every week
every time theres new kernel
because i dont have an upgrade path yet
i mean it isnt difficult to do, just dont reformat the rfs
just havent gotten around to it
id probably just have the makefile somehow install the kernel into a disk image because thats what i usually do
it does
reasonable
are you planning to make an upgrade path (eventually)?
when you do a hard disk install it flattens the entire drive, then makes two GPT partitions:
- EFI recovery, FAT32 68mb, contains kernel and limine
- the rest of the disk RFS, contains the BASIC programs, /programs/init, rocketsh, /system.
the EFI recovery is written out directly from a .img on the cdrom
made by the cmake
custom file system :0
yup!
peak memcpy (memcpy doesnt even copy to the hard drive but still) /j
its streamed
yooo nice
cool
once im done playing about with random stuff like kernel module support... i was improving the editor
after improving the editor, was going to make a package manager, in basic
that fetches basic programs from a http repo
do you have basic syntax highlighting actually?
no, thats on my todo next in the editor feature list
oh
for BASIC syntax highlighting i currently work in clion
i cant have colored text while doing my 10 PRINT "Hello World" 20 GOTO 10 :(
nice
but theyre discouraged
what should be used instead im not really familiar with basic
PROC is a procedure, like a function but never returns a value, can take params
PROCfoo("hello")
DEF PROCfoo(word$)
PRINT word$; " world"
ENDPROC
FN is a function, can take params but instead of ENDPROC, ends with = and a value
B = FNcrap(7,8)
DEF FNcrap(B, C)
D = B + C
=D
a LIBRARY is a collection of PROC and FN in a separate file, that you can load with the LIBRARY keyword, if you use LIBRARY you shouldnt line numbers
LIBRARY works like #include except it appends to the end, not inplace
how does that work??? (does it just add the library functions at the end of your file?)
and if you define a PROC in a library with the same name as the library, it will be auto called on load like a constructor
when you call LIBRARY the basic program is krealloc'd, to make space on the end, then its internally renumbered, reparsed, and the library appended on the end
after that the whole combined program is re-scanned for procedures and functions (you dont need forward declarations)
and if it exists, the constructor is ran
oh
it then sets the program ptr to continue after the lib statement
fair enough
understandable
two ways to start a program: from the command line, by name (it looks in /programs) or by the CHAIN command
CHAIN "/program/name/goes/here"
if you start a program by name from the shell, command line args are passed in, if you CHAIN it they arent
ok wait sorry to interrupt you but got an error after getting the makefile from cmake
make[2]: *** No rule to make target '~/Downloads/rr/retro-rocket-master/limine/limine.sys', needed by 'iso/limine.sys'. Stop.
i need to just put limine somewhere
oh, its a specific version, git submodule iirc
brain@neuron:~/retrorocket/cmake-build-debug$ git submodule
245c7c94c20eac22730ef89035967f78b77bf405 ../doxygen-awesome-css (v2.2.0-2-g245c7c9)
c93da495943c567340b7e128ae5f4fc5eaf17f43 ../limine (v4.20231024.eol-binary)
if you did git clone --recursive it would fetch it
ah
cant remember the command to do it after the fact
can i use a different version or am i gonna get smitten by zeus himself or something like that
youll get struck down by lightning
limine changed their config format completely

JUDGEMENT'd
i cba to update to the new format
it would give me some advantages though like better customisation of the boot menu
lol
aaaaaaaaaaaaaaaaaaaaaaaaaah
they archived the github
i think i might just make the binaries part of my repo
i really dont want to deal with codeberg
i dont chase trends
fatal: not a git repository (or any of the parent directories): .git
bash: syntax error near unexpected token `('
bash: syntax error near unexpected token `('

this command
why did they even move there
im probably blind as shit i dont see anything
yikes
you know you dont have to build your own rr?
no :o
i didnt see any releases on the github so i just assumed "ok i have to compile it then"
ugh master is broken anyway
why didnt i spot this
[ 71%] Generating iso/system/timezones/Pacific/Palau
make[2]: *** No rule to make target 'CMakeFiles/mod_test.dir/modules/test/test.c.o', needed by 'iso/system/modules/test.ko'. Stop.
[ 72%] Generating iso/system/timezones/Pacific/Pitcairn
make[1]: *** [CMakeFiles/Makefile2:11616: CMakeFiles/module_test.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
[ 72%] Generating iso/system/timezones/Pacific/Tahiti
it was building fine

tell me when the thing gets fixed
ping idk
there, its fixed @true ridge
wasnt complex to fix
but the reason i noticed was i checked gh actions
if youre strugglin to build just grab iso and shell script: https://github.com/brainboxdotcc/retro-rocket/actions/runs/17482255429
scroll down
k
i made it run
nice
resolution is insanely big my screen is too small lmao
ball works
TEXTURED CUBE
installer fixed
YOOOOOOO
nice
you found it then 
the mousetest doesnt mouse
you must load the driver first
oh
task drivers/ps2mouse
then run mousetest
it isnt auto loaded as its part of my longer term thing to maybe make a gui... in basic, and it will auto load the task
my mouse mouses
BASIC init system
๐ญ
btw list /programs/init
there actually is an init program, written in basic, its the first thing that runs that launches rocketsh
autoexec
which is also in basic
unbasic basic
how to clear screen i have artifacts from the demos
it's case sensitive :(
the shell prompt is actually a repl
cool
try PRINT 1 + 3 or PRINT "HELLO WORLD"
yeah BASIC is case sensitive btw
some dialects got rid of that


photoshop 
figured lol
ok it does print 4 if in actuality
ignore the error i tried something stupid
cool
can i put text before the input box
wait the test demo did that
sure, in an actual program but not on the REPL
fair
in a program you'd do:
PRINT "Prompt here";
INPUT VAR$
PRINT "You said "; VAR$; "!"
the ; on the end of the print line means no new line
you can separate items to PRINT with , or ;
placing question marks doesnt work
yes
hmm, probably a bad keymap
yeah can duplicate that
lol
what did you do
oh did you read the license agrement, said every bug you find you gotta submit a pr fixing it /j

lol
never thought to test that
what does it do?
btw, if any basic program locks up, ctrl+esc should drop you back to shell prompt
its an interrupt key like sigint
that is unless the interpreter is ded

so if i do the funny a few times it might give me its gonna give me an error on line 489
GOD DAMN IT
idk why i spammed ctrl+r but yeah idk it died
rip
well, not so bad, at least whole os didnt go
breaking news: dumbass spams ctrl+r and destroys retro rocket 
heres some commands to try
about, version, dir
tried dir already
and cd
haha, your screen is mess
:P
but does it work on real hardware
(dvd burning time MUAHAHAHAHAHAHA)
im running it rn downstairs in my cellar actually, testing a dhcp fix
there was horrible bug that cost me a whole damn weekend, not of OSdev but of network troubleshooting
hobby os's all need a certain purpose in life
if you left it running, it would eat all the dhcp leases over 100 hours uptime
networks are stupid for no reason at all
idk why
imagine whole family, 3 kids and wife complaining they cant get online
its been up since weds now and managing to hold onto the same ip
lmao
can still ping it, must still be running
brain@neuron:~/retrorocket/cmake-build-debug$ ping 10.0.0.157
PING 10.0.0.157 (10.0.0.157) 56(84) bytes of data.
64 bytes from 10.0.0.157: icmp_seq=1 ttl=64 time=0.399 ms
64 bytes from 10.0.0.157: icmp_seq=2 ttl=64 time=0.149 ms
64 bytes from 10.0.0.157: icmp_seq=3 ttl=64 time=0.158 ms
64 bytes from 10.0.0.157: icmp_seq=4 ttl=64 time=0.214 ms
^C
--- 10.0.0.157 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3073ms
rtt min/avg/max/mdev = 0.149/0.230/0.399/0.100 ms
50 000 dollar bet on that it dies right NOW

lmao
probably could kill it if i tried
its probably vulnerable to all kinds of ip exploits
hackers walking in thinking they got another windows pc
3 seconds after connecting they quickly reconsidered life choices
"what the fuck is a retro rocket"

the cmos clock commited die on the core 2 duo laptop
the battery might be a safety hazard the icon is flashing red then blue
these second hand laptops go crazy ๐ญ
also vs2010 and windows 7 :0 (i remembered my funny ass directx 3d test project i made)
nice
my laptop
KUBUNTU USER YOOOOOO
also thinkpad
i have one but its 32 bit so im sad i can only get windows xp on it
i got 7 on it but its too old to have drivers working
sadge
its from like 2004
idk its a surprisingly good windows 98 machine
literally bought it because it ran windows 98 i wanted to try playing multiplayer dos games
-# with myself tho this is saddening asf :c
im gonna try writing the iso on a usb for shits and giggles
it wont boot
limine will load the kernel, you may get as far as mounting the root fs, then it'll die
because no usb support
awh
if anything different happens lmk
im gonna try it for the science tho
probs
damnit 4.30am im a bad adult
limine stuck on flashing cursor
lmao
rip
i lost the connection cable for my usb cdrom drive brb
mine has cable built into it
apparently i was charging a calculator with it
dementia 
luckyn't
time to sacrifice a cd-rw that has a 50% chance of reading
what if a read fails actually
ok it booted
i had to disable "intel rapid storage technology" or whatever tf its called
congratbulstations
textured cube runs fast
or at least like 60 fps
nice!
this is actually really good to see, first time someone's running it on real hardware except for me
this is normally some kind of ide emulation
dressed up as some kinda raid
its some kind of sata extension iirc
but its a bit wonky
did you dare try to install it? ๐
i dont want to overwrite my windows 7 install
i have a spare hard drive when i get home its getting sacrificed
its like 140 gb
can that laptop boot from uefi?
like with an EFI partition and GPT?
because i dont do old fashioned bios partitioning
no
hmm, it prob wont boot then
theres efi emulators iirc
but you CAN use the installer to make an rfs partition, then mount the rfs partition from the livecd
didnt know this boots from efi tho either i forgor or something else
how old is it
i think 2017
it should then
its not ancient
the machine i test on boots from efi and that is 2012
its def uefi
nice
should be fine
its hard drive is borked tho and it only has nvme
i tried it in qemu on this work laptop... something weird happens in the basic intepreter
if i have time some point i'll try and figure it out
weird
something about it doesnt look right though its its an old version
either that or it can boot to shell in 0.6 secs
that could be the problem idk they changed something maybe
yeah theyre constantly changing the q35 emulation
to make it more compatible with windows and linux
mainstream os's 
boooo yeah
my end goal is to daily drive retro rocket, admittedly side by side with windows/linux on its own pc, not replacing it
same with my os except its not the entire universe propped up by a basic interpreter
didnt get that far :/
i got a vmm recently its not very far at all
once ive got my module loader working, theres nothing stopping someone dynamically loading native code into the kernel at runtime
are these utils or wdym by userland
like all the shell, utils, etc
instead of gnu, the ones from freebsd
tcsh, csh, bsd net tools etc
tfw you took time to make a basic interpreter but then someone just uses linux apps with retro rocket (compatibility layer
)
much of the code is a lot cleaner than gnu's tbh
lmao
i'd be curious to see that
i never used freebsd (sad)
someone makes a driver that just co-opts the scheduler, starts a pre-emptive interrupt driven one and drops to ring 3.. lmao
and i'd be like wtf
lmfao
the utils are probably good but im not making a unix like (maybe they should still work)
i wrote it at 2am with assistance of caffeine, google, my old ELF64 code, and a bit of LLM
make a module that prints something idk
oh
i was tempted to, but then we started chatting, and i realised that if i diverted away to test it im 50% sure it will break, and then i'd be up another 3 hours fixing it
are modules entered through the limine boot argument thing
sorry 
i mean they could be loaded via limine modules, but that isnt my plan
mac os <10 extension ptsd
that whole limine thing is a weird preboot environment i dont want to linger in
because on a hard disk its all inside a fat32 partition
and i hate fat32
my fat32 driver is spotty at best
i dont get the luxury of escaping limine boot args i want a microkernel
i wouldnt trust it to relaibly write modules into the efi
understandable
my plan is to have two things: 1) a basic keyword to load a kernel module and 2) a command line program that just calls it
so a program, like /programs/init can do KMODULE "/system/modules/test.ko"
or from rocketsh you can just do module /system/modules/test.ko
whats the extension for basic software in the os actually
or is there just none
or event just module test
theres none
in the cmake environment before the iso's built they have the extension .rrbasic, but this is just so the syntax highlighter works
theyre renamed to have no extension in <CMAKEBUILD>/iso
im going to need some kinda heuristic to know if to syntax highlight, just realised this, boo
if in rr itself you save smth with .rrbasic (nobody except psychotic dumbasses will do that but still) will it still run
sure
extensions arent an important thing
so long as you include that exension as part of the name
a
it wont try to append it
if you do syntax highlighting you can probably detect if its compatible with your basic dialect
so its not just a text file getting highlighted or whatever
it would probably be as simple as "does the first non blank line contain at least one BASIC keyword or a variable assignment"
fair
yeah maybe smth like that
scan the whole file and make sure its basic compatible 
that i did notice
also basic interpreters usually just crash if they find something stupid anyways
yup
i took time to give actual useful error messages
theres a minor bug though if the line contains tabs, the ^ that is supposed to point at the error character doesnt tab with it
i need to learn the language tho
rip
did you check the wiki
thing is you cant actually make your own programs unless you install because theres nowhere to save on the cd
unless, you drop your own .rrbasic into os/programs in cmake
and then do make, and burn your own custom iso
uhhhh yeah for the shell commands
tbh thats how i test rn, its kinda "long form" :S
fair
spare hard drives saving the universe again
time to get back to work, speak later
cya
it works!!!
module test;
fs_directory_entry_t * f = fs_get_file_info("/system/modules/test.ko");
if (f) {
dprintf("*** MOD TEST: Got info on test.ko size %lu\n", f->size);
void* module_content = kmalloc(f->size);
if (fs_read_file(f, 0, f->size, module_content)) {
dprintf("*** LOADING TEST MODULE test.ko ***\n");
if (module_load_from_memory(module_content, f->size, &test)) {
module_unload(&test);
}
dprintf("*** DONE WITH TEST MODULE test.ko ***\n");
} else {
dprintf("Couldnt read test.ko\n");
}
} else {
dprintf("*** MOD TEST: Cant get info on test.ko\n");
}
[1427]: *** MOD TEST: Got info on test.ko size 5192
[1428]: *** LOADING TEST MODULE test.ko ***
[1428]: test.ko: mod_init called!
[1429]: test.ko: mod_exit called!
[1429]: *** DONE WITH TEST MODULE test.ko ***
LETS GOOO 
rr as a linux loader when 
lol
are modules gonna work like programs in a sane regular os
it feels like theyre just drivers
modules are just any optional piece of code
They're not programs since they link to the kernel and exist in the same address space
ohok
yesnt, they have full access to all symbols in the kernel, and are basically exactly a .so
nothing else special except some compiler/linker flags to stop them being position independent and stop them using 2gb relocs
so you could schedule a timer, and have it called on events
technically in retro rocket everything exists in the same address space ๐
kernel modules in rr are placed in a kmalloc'ed aligned region big enough to hold all the PT_LOAD sections
which can be anywhere in the heap, hence the compile flag for mcmodel=large
was simply the easiest way to deal with it in a non-paged, identity mapped layout
ohokcool
started moving my docs from github wiki into doxygen, gives me much more flexibility of layout
i got so many docs ๐
idk what doxygen is :'(
that's a good thing especially if they're well written
any dumbass can just go and learn basic
where's the flashy visuals that make me feel like in a cartoon /j
where's the rocket owl did the rocket fail 
understandable
are they still gonna be in markdown or whatever you used on github?
is the github wiki gonna be maintained?
no
everything has been copied to the doxygen one
which is easily maintained by PRs
its a bunch of markdown files in the docpages dir
sacrifices have to be made ๐ฅ
wrong message
the github one only lets me have like 1 level of pages
whatever
on gh wiki on the right, that huge sidebar
that is the best i can do, cant collapse or expand etc
saddening
have now made e1000 and rtl8139 into modules! right now the kernel hard codes loading e1000 at the end of the startup process before starting the scheduler, but the next step later tonight will be to give a BASIC keyword to load a kernel module, and let /programs/init load the driver
intel 8254x when? 
yay internet
thats what e1000 is
or rather a subset of
82540EM and 82541PI
82540EM is qemu
82541PI i have in my test machine
:0
i have a thinkpad with a network card that series but it wont run RR it's 32 bit and ide only :(
(8254x series)
also can modules have their own keywords or smth
for basic
actually no wait
im stupid pardon me
there, now BASIC can load and unload kernel modules!
this is a basic of all time
of all time!!!
can now configure network via a config file in /system/config/network.conf, the defaults are for dhcp on everything. once its installed you can edit this.
BOAT
been busy tonight! lots of bugs squished:
- Fixed hostname bug: stopped freeing string literal; now store hostname in static buffer.
- Corrected IRQ stub: pass real IRQ number to C handler (was always 0).
- Implemented proper shared-IRQ handling; call all handlers on shared line.
- AHCI ISR now acks/clears PxIS bits per port to prevent interrupt storms.
- e1000 init hardened: fully initialize TX/RX descriptor rings and indices.
- Zeroed TX buffers/descriptors so no stale bytes leak into frames.
- Programmed TX/RX descriptor base/len registers correctly and aligned buffers.
- Verified on HDD boot under QEMU: no bogus 0xFF frame
it took you this long since you first programmed your idt to realise that the irq handler always returns 0
damn
it was one of the params in the irq handler function
still though
void e1000_handler([[maybe_unused]] uint8_t isr, [[maybe_unused]] uint64_t error, [[maybe_unused]] uint64_t irq, void* opaque) {
uint32_t status = e1000_read_command(REG_ICR);
if (status & ICR_RXT0) {
e1000_handle_receive();
}
}
^ the value of irq was always 0
never noticed, as nothing actually uses it
purely informational
oh
the assembler macro that built the jump table was just setting it to $0
rip
all good now
this isnt 'when your os goes crazy' this is when reminna goes crazy and cant take a simple screenshot in wayland lol
i almost just said you should post it there
im sick of seeing this tho
wtfisthat
there, all good
wireshark
welcome to the internet
if you ever integrate or write a tcp/ip stack, get used to spending hours in it
oh
internet will destroy my sanity i assume :/
porting a web browser will be total ass as well probably
im contemplating making one
and making my life easy by
- not implementing ssl yet
- making it text only like lynx
no html images? 
lol
i mean i could load images
but the minute you do that you then have to go down the css rabbit hole
just do it idk how hard its to port jpeg or whatever
oh god
and i dont have a spare extra life of time to make a graphical web browser
every time html and css get mentioned i get ptsd from my geniunely braindead web design teacher i swear
a text only browser where you can tab into an image would work
why did i even sign up there
separate app?
just open it like a separate file or smth
how difficult is png to implement
im pretty sure its lossless so its probably just "red pixel 50 times, green pixel 20 times"
sprites 
i use stb_image
stb_image can load tons of different formats
including png, gif, bmp, etc
i dont get why so many people here spend so long trying to implement png, unless they do it purely to learn
it doesnt need any porting, it just works
idk theres a ton of folders and stuff in it it just looks menacing as absolute shit
nah
fair
stb_image.h is legit all you need
fairโข
also is it difficult to implement a 3d library because that 3d cube goes hard as shit (also how does it render so fast without graphics drivers)
ok fair
but if you want the more advanced stuff it can get a bit hairy
nomal mapping, shadow maps, reflections, ssr, all that
i think i did a 3d implementation at some point
anywhere else i'd use an existing engine, but that isnt happening in retro rocket
Oh Dear God Just Use Windows At That Pointโข
understandable
unrelated question but how the hell does roblox have unreal engine level graphics
it's like there's 1 year left until they run ray tracing on a 10 year old ipad (like literally if you try hard enough you'd get rtx on a powermac g3)
i mean i dont really see the difference
there def is but not major
:0
/etc/hosts or c:\windows\system32\drivers\etc\hosts
its a set of configured aliases that override dns
you never used it?
oh
no
i feel like i just skipped a half of using a personal computer in general
adding some simple command line tools. i need these for searching the /devices/debug
That BASIC seems pretty ADVANCED imo /s
lol, this is true
except its only as advanced as you make it
IF ARGS$ = "" THEN
PRINT "File name not specified"
END
ENDIF
FILE$ = TOKENIZE$(ARGS$, " ")
SEARCH$ = LOWER$(ARGS$) ' Everything that remains
FH = OPENIN(FILE$)
IF FH < 0 THEN
PRINT "Unable to open file: "; FILE$
END
ENDIF
LS$ = ""
LN = 1
F = 0
REPEAT
BYTE = READ(FH)
LS$ = LS$ + CHR$(BYTE)
IF BYTE = 10 THEN
IF INSTR(LOWER$(LS$), SEARCH$) > 0 THEN
PRINT LN; ":", LS$;
F = F + 1
ENDIF
LS$=""
LN = LN + 1
ENDIF
UNTIL EOF(FH) = 1
CLOSE FH
IF F > 0 THEN
PRINT ""
PRINT F; " matches found."
ELSE
PRINT "No matches found."
ENDIF
thats the search program
(Im just gonna act like a understand all of this.)

lol its easy
it does exactly what the keywords look like it does
read bytes from a file until it has a line, and if the line contains the search string print it to the screen
basic is the worst programming language ever tbh
nah that would be brainfuck

pretty much if you wanted to learn to program up until the early 90s you learned BASIC
@grok is this true
btw the images above, ive changed the way heap is initialised so that even with identity mapped memory, i can claim all the 'parts' and coalesce them into one managed heap i can call from via kmalloc
generally, youll gain a gigabyte if your vm or real machine has anything more than 2gb ram
and always about a gigabyte
because everything below 4gb is punctuated by 'holes' of unusable memory
acpi, mmio, etc
nice
better error handler, for when it goes crazy
Damn thats cool
How do u know which context it is?
And how do u backtrace through irqs
i am placing a sentinel value into the stack
its pushed into the trace stack before i call IRQ or Interrupt, from the assembly stub
the interrupt call and the kernel itself share a stub, this makes it easier to cross contexts than if it was a 'user context' in ring 3 with a different stack
when i see the sentinel value i know that we entered interrupt context
i count the sentinels in the stack before i draw the stack trace, and decrement each time i cross one, when i cross the last one, i know thats pre-empted non-interrupt code
static size_t count_markers_ahead(const stack_frame_t *frame, uintptr_t lo, uintptr_t hi, size_t probe) {
size_t cnt = 0;
while (frame && CANONICAL_ADDRESS(frame) && (uintptr_t)frame >= lo && (uintptr_t)frame <= (hi - sizeof(*frame)) && probe++ < 1024) {
const stack_frame_t *next = frame->next;
if (next && (uintptr_t)next <= (uintptr_t)frame) {
break;
}
if (frame->addr == BT_IRQ_MARKER) {
cnt++;
}
frame = next;
}
return cnt;
}
void backtrace(void) {
stack_frame_t *frame;
__asm__ volatile("movq %%rbp,%0" : "=r"(frame));
uintptr_t lo, hi;
size_t depth = 0;
get_kstack_bounds(&lo, &hi);
/* We know weโre in an ISR/exception at the top */
setforeground(COLOUR_LIGHTYELLOW);
aprintf("--------------------------------[ IRQ/TRAP CONTEXT ]--------------------------------\n");
size_t remaining_markers = count_markers_ahead(frame, lo, hi, depth);
setforeground(COLOUR_LIGHTGREEN);
while (frame && CANONICAL_ADDRESS(frame) && (uintptr_t)frame >= lo && (uintptr_t)frame <= (hi - sizeof(*frame)) && depth++ < 1024) {
stack_frame_t *next = frame->next;
if (next && (uintptr_t)next <= (uintptr_t)frame) {
break;
} else if (frame->addr == BT_IRQ_MARKER) {
if (remaining_markers > 0) {
remaining_markers--;
}
setforeground(COLOUR_LIGHTYELLOW);
if (remaining_markers > 0) {
aprintf("--------------------------------[ IRQ/TRAP CONTEXT ]--------------------------------\n");
} else {
aprintf("-------------------------------[ PRE-EMPTED CONTEXT ]-------------------------------\n");
}
setforeground(COLOUR_LIGHTGREEN);
frame = next;
continue;
}
uint64_t offset = 0;
const char *name = findsymbol((uint64_t)frame->addr, &offset);
aprintf("\tat %s()+0%08lx [0x%lx]\n", name ? name : "[???]", offset, (uint64_t)frame->addr);
frame = next;
}
setforeground(COLOUR_WHITE);
}
for the debug log, i save dprintf() to a circular buffer, i use a call to take a snapshot of the buffer and then output the last n lines of it
for the asm:
.macro PUSH_SENTINEL
sub $16, %rsp
mov %rbp, 0(%rsp)
movq $BT_IRQ_MARKER, 8(%rsp)
mov %rsp, %rbp
.endm
.macro POP_SENTINEL
mov 0(%rbp), %rbp
add $16, %rsp
.endm
interrupt_stub:
PUSH_SENTINEL
call Interrupt
POP_SENTINEL
MPOPA
iretq
make a basic instruction for kernel panic 
wait so how does the code above handle irq frames vs normal frames?
since rsp/rip are at different offets no?
there is/was one
it I disabled it I think
nope same stack at least for me
probably because it doesnt switch privilege contexts
ah wait
I don't switch between ring 0 and 3, any permission checks are enforced by the interpreter... that which there are. not many rn
wouldnt this mean you're discarding the actual interrupted function?
since your moved rbp is of the previous caller
the idea is that a basic program can remove privileges on a granular basis from children "next child can't use keyword x, y z" like a chroot
doesn't seem so?
this is the first time I've revisited my stack trace code in about a decade if not more, so I might be missing something too
I just use the standard frame pointers GCC emits
and it seems to follow execution into interrupts
so like
rip of caller of caller
rbp of caller of caller
----
rip of caller
rbp of caller
---
rbp of caller
your marker
i dont see whre the rip of the called function shows up here
maybe im missing something
I don't replace anything I push a new frame entirely
yes but rbp still contains the old base value right
the new frame has nothing but a sentinel rip, 0xffffffffffffff01
if it's found it's skipped and the header printed
so how does it know the rip of the interrupted function
the frame contains next, sentinel
since next should be the base of the interrupted function
which has the rip of the caller
that's still there, the sentinel is pushed inside the stub
so yeah i still dont get it
or hmm maybe the interrupted rip is next to your pushed rbp
so like
... other values pushed by CPU
interrupted cs
interrupted rip
your stub rbp
your marker
i guess is the stack layout so it works?
looks right, I'm struggling to visualise what you mean
anyway if it works it works lol
I insert an entirely spoofed stack frsme, right before calling into the irq handler (which makes a new frame itself), then immediately after pop the spoofed one
the irqs are dispatched by 256 macros, basically a bit like the old jamesm tutorial just fixed and adapted for 64 bit and extended to support the full range of interrupts for msi
so initially the interrupt goes to that, which is a macro, which pops the sentinel
then it sets the irq number and interrupt number parameter and calls the global function IRQ or Interrupt
I don't do anything to the next frame
in my understanding with this approach you discard the interrupted function and actually start the backtrace from its caller
unless you pull the rip out of the stack frame somewhere separately
so it's like irq0 -> interrupt_stub -> push sentinel -> call IRQ() -> pop sentinel -> iret
i understand that bit yeah
oh I see... nope the stack trace goes all the way back to kmain_bsp(), the first function on the stack
nah thats not what i meant
I don't see what's lost or discarded here? I think we are both thinking of different things
is the stuff after the second yellow line here correct? Most likely its actually 5 frames deep but you're only showing 4
what, from dns_lookup_host?
handle_receive
yes that's right
is it a leaf function?
I put a memcpy to null in that function that fires if the system uptime is greater than 5 secs then ran a http test
hmm
it's the immediate function called by e1000_handler in this case attached to irq11
so nothing missing there
yeah i dont understand then
the only oddity is idt_init(), neither interrupt stacks pass through there... but it's the "nearest" symbol to the assembly stubs that don't have symfile entries
technically that is like irq11_stub or something
why dont we see the memcpy in the trace
but my memcpy is inlined
can u just *(int*)0x123 = 123?
should that show?
in that function
yeah I could but the memcpy stopped my linter bitching lol
and check what will be printed
I can't rn, but I'll check later
the only one discarded should be the very first frame (it's all one loop) because that is always just backtrace() itself
pointless to show that lol
yeah thats whatever
to be honest could discard the entire top section and error traces would still make sense
youre right, the frame alongside the sentinel is omitted, but i think it might always have been omitted. i'm looking into it
i see what you mean
the fix is simple enough
the fault address doesnt show in the trace, because the trace traces return addresses
theres no return address from where the fault occurs
im working around it by pushing rip onto the stack, and retrieving it and loading it into a parameter that i pass to the interrupt function
i can then use that rip to print the faulting function name, before the trace
Yup that's what I meant
a checked build maybe
maybe
now excluding the error handlers context
moving back now to improving the UX of the editor
finally
its very funky
colorful
only when you disable the feature it is 
everyone knows suffering is key to success
Next roadmap item:
Create a simple network file copy (FTP client? something else?) to get files on and off the installed system into github
good luck
made a better image with CUUUUUUUUUUUUUBE
CUBEEEEEEEEEEE
heap init now reclaims more. we reclaim nearly all bootloader reclaimable.
isnt that just a few mb
thtas about 4gb
is ....32gb enough for BASIC 
thats my test machine where i boot it off the hard disk
that should be enough for many applications.
how much ram can RROS handle?
i didn't set a limit
so as much as your machine can handle
Bro, your project is amazing! I love it!
why
just buy a crappy 2010 laptop if you want a test machine
why would he buy another test machine if he already has a test machine
that makes no sense
turn the test machine into a non test machine
why?
you're a glowie if you don't agree with me
uh no?
maybe it's his old workstation, i test bentobox on my laptop that has 24gb of ram
I can see your pfp glowing through my monitor
??
no the reclaimable areas
its too old and slow for that
AMD FX-6300, Gigabyte-78LMT-USB3, 32gb ram, 1tb HDD
it was my old pc, yes
32 gb of ram
"slow"
its only got 6 cores
dual channel ddr3 really isnt the fastest
the issue is more the ram speed than the amount i believe
i run a lot of memory hungry things at the same time, my current pc has 32gb ram too, and my server has 64
and yeah the bandwidth is too slow for gaming
I main a hexacore cpu ๐
at the time it was stonks