#Xiromos 16-Bit NASM OS
1 messages · Page 3 of 1
nice
lets gooo, i fixed the write command, now you can actually write things into a file
this is the 2000 message of this channel
my arch linux crashed
qemu-system-i386 -hda disk.img -hdb disk2.img -fda floppy.img -fdb floppy2.img -m 2M
multiple disk support is coming
if i look in a texteditor into my disk.img i see somtimes random these numbers: F8 FF FF FF
what do they mean?
no look, there are somtimes these random bytes, but they do not belong to the root directory or the FAT
then they would belong to something other
like garbage bytes or smth
maybe some of your kernel data?
that cant be, my kernel data is in the data area
idk
yes, i asked my good old friend 
I MADE ITTT LETS GOOOOOO
muttiple disk support!!!!!
it took me a whole day..
whohooooo
cd = change disk
cd normally means change directory. Then you may do
cd d:/
to change disks or
cd d:/folder
etc
i know
but change disk is a funny name
of course i will rename it because i want to implement directories soon
they're an end of fat marker aren't they?
last cluster in chain
yes, thats what chatgpt said
why not something like chdsk
cd = change disk isnt very intuitive
alright i changed it to cdisk
because soon i want to implement directories
btw there is a command calles lsdisk, which shows you available disks
thats cool
btw my system supports FAT12, i can read and write files on a FAT12 disk
thats very impressive, is this your first os?
yes
so you have a vfs now?
whats that?
no, FAT12 and FAT16 are nearly indentic so i can use both
the only difference is the amount of clusters
ok but let's imagine that you want to add support for another completely different fs
for some reason
then you would need a vfs
true
i suggest you write one now
no
but why
ok, but i would make your fs handling architecture cleaner
not really
why?
why would you
it'd be better than having a function for every fs
sure
well ofc u would have to abstract the two fs's through some common layer
but idk if that really constitutes a vfs
making a better and simpler texteditor
guys, i need your help. I have a systemcall (int 0x20) for loading and executing a program. it expects the filename in SI. if i just put a regular variable with the filename (eg: name db "TEST BIN), it works fine, but if i put a buffer in there, it doesnt work. I use cmpsb in my syscall, does it have problems with buffers? i checked the buffer and it has the correct filename in it, so i dont understand why rep cmpsb doesnt find it
mov di, command_buffer+8
mov al, 'B'
stosb
mov al, 'I'
stosb
mov al, 'N'
stosb
mov si, command_buffer
mov di, read_buffer
mov cx, 11
rep movsb
mov si, read_buffer
call print_buffer
int 0x20
ret
print_buffer:
mov cx, 11
mov ah, 0x0e
.loop:
lodsb
int 0x10
loop .loop
ret```
the print_buffer function shows, that the filename is in the correct format, but the interrupt doesnt find it in the root directory
but when i pass instead of the buffer a normal variable: calc_bin: db "CALC BIN", then it works fine
oh yeah guys, my system now supports floppies too!!
now you can use A and B as a floppy, C as the root disk and D and E as external or additional drives
you have basically unlimited space
thats so cool
made a new syscall for file operations on floppy disks
- if you type a program name into the terminal, the command interpreter searches in the root directory for this name and if found, it will execute it.
this is better than the previous version, because there the start of the programs were hardcoded in the kernel and you couldnt add new programs from extern drives
but now you can just copy a program onto the disk or if you have a FAT12/FAT16 disk with programs and files you can just read from it, because of multi disk support
Maybe you could have a special folder for programs to where you just need the name and for other programs you either give it the full (or relative) path or it searches the current folder
true, but for that i have to implement direcotories...
im not sure if im experienced enough to implement directories
don't worry, it's not that hard to do
(at least in C, I never tried in asm tbh)
alright, my OS has now FAT12 floppy disk support, so you can do file operations on floppy disks too
there are some bugs but i am trying to fix them
this is all on a FAT12 formatted floppy disk
it uses CHS reading and writing instead of LBA
is it bad for FAT12 that i am loading my fat on a odd offset?
wait
that doesnt make sense
why did someone invented something like FAT12??
use FAT16 instead, it is much easier and gives you more disk space
fat 12 was made for floppies
fat16 metadata takes more space than fat12
floppies are tiny
disks are bigger
finally! now you can switch between floppy and hard disks without any bugs.
some commands on the floppy disk doesnt work properly, but i will try fix them.
but FAT12 is really hard in comparison to FAT16
true, but you have to do this bit-shifting
not in assembly
the coolest part of my system: red screen of death
possibly but there is no reason to write it in assembly so like
this will be shown if the system fails to load the FAT and the root of an external disk and then fails to reload the FAT and root of the root disk
Easier on the eyes
Крутой хэдлер скачать бесплатно из x16-PRos
да это же всего лишь одна строка кода
Не бери в голову, я же прикалываюсь. А вот функции вывода это уже не одна строка кода. В программах видны куски кода проса.
кроме калькулятора программы я сам писал. и его я тоже ещё перепишу
to create directories in the root directory isnt that hard, but i dont know how to create a directory in another directory
little program to format a disk
i think you should ask for confirmation before formatting the disk
or store a list of the drives to format in memory (you add one using a f <drive> command for example)
and the user can decide to apply the changes with a command
or to cancel them
is the answer case sensitive for y/n?
no it isnt
you can type y or Y
btw if you press q you can quit this program
the help command is now a program
and my OS has officially FAT8 support!!
my own filesystem
because FAT8 doesnt exists officially
Microsoft did have an 8-bit FAT file system in Stand-Alone Disk BASIC-80
it was infact the original incarnation of FAT
but was never supported by DOS, and is very different from FAT12, FAT16, and FAT32
should not help be a shell built-in?
it is, but it is also a program
finally the programs are in a directory
thank you
now the LS command works in directories too
and sub-sub directories also work
i implemented directories for hard disks now
and the file operation commands word in directories
wait
there are only 3 levels of dirs?
or infinite levels
you can do infinite
ok
also i have a debug mode where i see more information than in the normal mode
oh yeah guys, i made that 2 programs work now at the same time
now i will try that more programs work
i will make it so, that the kernel and max. 4 other programs can work at the same time because of memory limits
how does it work
i hooked int 0x8 (timer) and now the cpu jumps every 18ms from the one program (shell) to the other program (eg. HELP.BIN). this all happens in the timer interrupt where the cpu first saves all the registers, then loads the stack of the other program and jumps to it
do you save regs?
ah yes you already said
so basically it's preemptive without protection
nice
yes
thank you!
how do programs decide what addresses they load
do you have an executable format that allows relocation
like dos .exe
the program loader looks how many processes are running and then calculates a free adress. but that doesnt work yet. and i will make it so, that you can max. load 4 programs, so the first program is loaded at 0x50000, the 2. at 0x60000...
yes, true
how's this project going
very good
that's awesome to hear
thank you
is it still 16 bit
yes, but i plan to make a 32bit OS on top of this, like microsoft did it with windows 3.1 and windows 95. but it will be in assembly too
yeah
yes but they rewrote windows from scratch then
the more assembly the better
so maybe, just maybe, there is a reason to that
to what?
the fact they removed the msdos base from windows
evolution and advancement...
i think it is more compatible with real hardware
btw all your routines that use BIOS interrupts will not work in protected mode
yes, but only later
no, C compilers generate assembly, so compatibility is the same
but people will bring up architecture and chipset specificity and stuff
i know... i have to rewrite everything
(ik you have to write some parts in asm but it's because C is intended to run everywhere)
C will not run on my analytical engine prototype
bits 16
start:
cli
xor ax, ax
mov es, ax
mov ds, ax
lgdt [gdt_descriptor] ;load GDT
mov eax, cr0
or eax, 1 ;set PE
mov cr0, eax
jmp code_off:main
gdt_start:
dq 0
;code segment
dw 0xffff
dw 0x0000
db 0x00
db 0b10011010 ;access byte
db 0b11001111 ;flags
db 0x00
dw 0xffff
dw 0x0000
db 0x00
db 0b10010010
db 0b11001111
db 0x00
.end:
gdt_descriptor: dw gdt_start.end - gdt_start - 1
dd gdt_start
idt_start:
times 256 dq 0
.end:
idt_descriptor:
dw idt_start.end - idt_start - 1
dd idt_start
bits 32
main:
mov ax, data_off
mov es, ax
mov ds, ax
mov ss, ax
mov esp, 0x90000
call set_idt
mov edi, 0xb8000
mov eax, 0x07410741 ; 'AA'
mov [edi], eax
mov esi, msg
call print_string
halt:
hlt
jmp halt
set_idt:
mov ecx, 256
mov edi, idt_start
xor eax, eax
rep stosd
rep stosd
mov ecx, 256
xor ebx, ebx
.setidt_loop:
mov eax, isr_default
push ecx
call set_idt_entry
pop ecx
inc ebx
loop .setidt_loop
lidt [idt_descriptor]
ret
isr_default:
cli
iret
print_string:
pusha
mov edi, 0xb8000
.next:
lodsb
cmp al, 0
je .done
mov ah, 0x07
stosw
jmp .next
.done:
popa
ret
guys i have a problem
the CPU doesnt triple fault, but why does it not print a text? i am in 0x03 text mode
mov eax, 0x07410741 ; 'AA'
mov [edi], eax``` even this doesnt work
am i stupid?
btw code_off is 0x08 and data_off is 0x10
protected mode is very complicated
forget about BIOS interrupts
yeah, i set 0x03 befor jumping to the kernel
try this:
mov edi, 0xb8000
mov byte [edi], 'A'
mov byte [edi + 1], 0xf
i don't think it matters
hm, but i was int 0x12 video mode, which already starts at 0xa0000
_ _
each character in vga text mode is 2 bytes
1 byte for the character and another byte for its attributes
okay
this doesnt work unfortunately
hmmmmmmm
yeah...
where does it crash
maybe there is an error loading the GDT
run qemu with -d int -no-reboot
and send the output here
and btw when reloading your segments you need to fill FS and GS
Servicing hardware INT=0x9 thats the last one and then it stops.
because i do CLI
does it dump any register
no
yes..
what are these registers for?
what about this GDT?
gdt:
dw .size - 1 + 8 ; GDT size
dd .start - 8 ; GDT start address
.start:
; 32-bit code
dw 0xffff ; Limit
dw 0x0000 ; Base (low 16 bits)
db 0x00 ; Base (mid 8 bits)
db 10011011b ; Access
db 11001111b ; Granularity
db 0x00 ; Base (high 8 bits)
; 32-bit data
dw 0xffff ; Limit
dw 0x0000 ; Base (low 16 bits)
db 0x00 ; Base (mid 8 bits)
db 10010011b ; Access
db 11001111b ; Granularity
db 0x00 ; Base (high 8 bits)
.end:
.size: equ .end - .start
i got it from the limine source code
some flags are different than yours
maybe it is the issue
also you don't need an idt for now
i tried it out, but unfortunately its the same result
thats very strange
i am in 0x03 text mode and i see the cursor blinking, but no chars
forget about BIOS text mode
okay
if you try to use BIOS interrupts in protected mode it will crash
i know, i set video mode before jumping to the new kernel
run qemu, then go to "compartmonitor0" and type info registers
no need to do that
you are in vga anyways
the first thing I can see is that your GDT isnt loaded
CS is null
you are in protected mode
the kernel is at real mode adress 0x0000:0x8000
bits 16
start:
cli
xor ax, ax
mov es, ax
mov ds, ax
lgdt [gdt_descriptor] ;load GDT
mov eax, cr0
or eax, 1 ;set PE
mov cr0, eax
jmp code_off:main
gdt_start:
dq 0
;code segment
dw 0xffff
dw 0x0000
db 0x00
db 0b10011010 ;access byte
db 0b11001111 ;flags
db 0x00
dw 0xffff
dw 0x0000
db 0x00
db 0b10010010
db 0b11001111
db 0x00
.end:
gdt_descriptor: dw gdt_start.end - gdt_start - 1
dd gdt_start
idt_start:
times 256 dq 0
.end:
idt_descriptor:
dw idt_start.end - idt_start - 1
dd idt_start
bits 32
main:
mov ax, data_off
mov es, ax
mov ds, ax
mov ss, ax
mov esp, 0x90000
mov fs, ax
mov gs, ax
call set_idt
mov edi, 0xb8000
mov byte [edi], 'A'
mov byte [edi+1], 0x0f
mov esi, msg
call print_string
halt:
hlt
jmp halt
set_idt:
mov ecx, 256
mov edi, idt_start
xor eax, eax
rep stosd
rep stosd
mov ecx, 256
xor ebx, ebx
.setidt_loop:
mov eax, isr_default
push ecx
call set_idt_entry
pop ecx
inc ebx
loop .setidt_loop
lidt [idt_descriptor]
ret
isr_default:
cli
iret
print_string:
pusha
mov edi, 0xb8000
.next:
lodsb
cmp al, 0
je .done
mov ah, 0x07
stosw
jmp .next
.done:
popa
ret
here it is
CS should be 0x08, right?
it worked!!
times 256 dq 0
.end:
idt_descriptor:
dw idt_start.end - idt_start - 1
dd idt_start``` these lines were the problem
if i remove it i get an 'A' printed!
maybe there was something wrong with the offset
you don't need an IDT in your bootloader
check_exception old: 0xffffffff new 0x6 what does that mean?
0x6 = invalid opcode
so you're probably executing incomplete instructions or even data
why don't you use C btw
it would be like
i dont know C
so easier
then learn it, it is not that hard
you learnt x86 asm, why couldnt you learn C
isnt assembly much easier than C? because its just simple instructions
okay
but i dont understand what pointers are
a pointer is a variable which contains the address of another variable
this allows you to use memory directly
so in ASM this would be this?: mov ax, [ptr] this doesnt move the adress into AX but the value
ah, you mean: mov [0x0000], ax
an example in C would look like this:
int x = 5; // variable x with a value of 5
int *p = &x; // pointer p which stores the address of x
ig it's like
mov dword [x], 5
mov edi, x
where edi points to x
okay, i think i understand it a little bit
nice
how can i use higher resolutions in PM, like eg. 1024x720?
vbe? they might have higher resolutions
depends on the target though
i tried, but it didnt worked
i have already print function, print_newline, scroll and colored print functions
i have a question, why is ring 1 and ring 2 not used? i asked chatgpt and he said, i should use ring 0 for the kernl and ring 3 for shell, programs, etc... but what is about ring 1 and 2?
Well, you're a developer, why are you asking about kernel rings if you yourself indicated in the code whether they are used or not?
This is your OS, you are its creator, you should know this, unless of course you did everything using AI
youre right, but somtimes im just asking AI about facts
its the same like searching the internet i guess, unless you write your code yourself
So, am I correct in understanding that you weren't the one who wrote the code for implementing the kernel rings?
i dont have any rings yet
Hm, okay, that makes sense
@echo granite are you using C now?
well, i have the kernel which is in ring 0, but i dont know what ring to use for the shell
ring 3
obviously
Is there any other rings?
no, i have to watch a tutorial how to link assembly and C
yes there are 4 protection rings
not yet
I am asking about his project
just compile your C and assembly files into object files and link them together
okay, i will try it
https://wiki.osdev.org/Security
and please read this
btw you should not write 16 and 32-bit code in the same file
if you wish to use C
okay
sudo pacman -S opsec
interesting
what code did i steal?
haha, i know you're trolling
btw the output functions are the same in every 16bit OS. because there are no other ways to make them
and binaries are in the zprograms/ folder
btw ProX, why isnt your post in the project-specific-no-ai channel?
because they dont wanna move it in another channel...?
yeah but he said in one of his youtube videos that he dont use any AI
but maybe he is open to the use of AI
hm, maybe
bro, ahahaha
I don't want to create a new channel about my OS on this server. It already has news and reactions, and I think everyone's already got used to
Why "they" 😭
I hadn't checked your pronouns before, so I didn't know
To be honest, I don't really understand all this "they/them"
in english you say "they/them" when you dont know the gender of a person
Oh, okay, I will remember that
They are not needed. Most OS designs only use two privilege levels: kernel and userspace. Paging also only supports two privilege levels, so ring 1 and 2 aren't that useful.
ohh, okay
Huh??
because of the linker i guess
like this
bits 16
; some code
bits 32
; some code
if you wanna link with C
You can do that regardless of whether you link with C
really?
it has a very very specific structure that you need bit-accurate
Why wouldn't you be able do that?
do relocatable ELFs support 16-bit code mixed with 32-bit code?
vbe took me a bit to get working but it's not too hard when you know where things go
Why would they care?
i'm just asking
I mean
okay i will try
you should also make sure a mode is actually available before you try to switch to it
because i thought it was true
it seemed normal to me
This is not a good page
mb
But why did you think it was true?
if you have an issue I can likely help this time because I've done it too
i once tried to assemble a file with mixed 16/32-bit code to an ELF32 and it didn't work
And anyway, you can also use other formats with C
yes pleasee
mov bx, 0x4118
int 0x10``` i do this, before executing the new kernel
but i dont know where the video memory is
video memory can be fetched by calling mode information and reading certain bits
hold on
offset 0x40 of the mode information block is a pointer to video buffer
okay
hm, i get 0x0d exception (general protection fault) when i do STI. but why is this if i am in ring 0?
this is not the error, because im doing: jmp far code_off:main
interesting
@little drift
Thank you so much
no problem
maybe it is because of the timer interrupt, if you don't handle it
yes, i remapped the PIC and now it doesnt show 0x0d anymore
why so many functions for the same thing 💀
i got vesa mode working but its actually very hard to write a print function for it
@raven sierra how do you print chars in VESA?
which vesa
I never used a terminal vbe mode so I'm not sure what interrupt
you might be better off writing your own character printing routine
with that comes the difficulty of a font however
just also ask chatgpt about it
.PSF fonts are easy to parse and it’s easy enough to make a rendering routine
yes the rendering routine is the easy part
the hard part is the font part
unless you do it the boring way and use someone elses'ss's''s
no, he isnt that smart
yes, i will just use someone elses's font
vgas 640x480 is 1-bit anyway
im still sticking with that resolution but vbe lets me get it in 16 bit color
wow 0x118 has a lot of color are you sure you need that much
not really, but i want to use it because of the resolution. but i dont know how to render a font
pusha
movzx esi, al
sub esi, 32
imul esi, 16
add esi, font8x8
mov edi, [cur]
mov ecx, [rows] ;8
.row:
mov dl, [esi]
inc esi
push edi
mov ebp, 8 ;8 pixel
.col:
test dl, 0x80
jz .skip
cmp byte [bpp], 4
je .write32
mov byte [edi], 0xff
mov byte [edi+1], 0xff
mov byte [edi+2], 0xff
add edi, [bpp]
jmp .skip
.write32:
mov dword [edi], 0xffffffff
.skip:
shl dl, 1
dec ebp
jnz .col
pop edi
add edi, [pitch]
loop .row
popa
ret
``` hmm, i have this problem that only the first pixel row is drawn
i have a 8x8 font
and [cur] is the adress in the frame buffer where to write
this happens if i try to draw a '['
and this is if i try to print a message
i dont know why but everything is printed twice
and the '!' is printed correct
have you considered using 64 bit writes and rep movsq to write the rows
but im in 32bit mode
or are you entirely only using 16 bit opcodes
if you have a 64 bit CPU you can use 64 bit regs in 32 bit mode
if
hm. no, my OS is designed for the i386
okay, i will do that
it took me 2 days but FINALLY i can write in vesa mode 0x118
uhm yeah, the font is pretty ugly...
GDT INIT OK?
they're plain binary where each bit set is an on pixel
same as flanterm uses
this one is similar, called YES-T
Since they're straight binary I'd imagine you can copy it into an assembler somehow as a label
looks like you need 1px spacing
according to flanterm if the right hand column has a 1-bit it's duplicated to the 9th spacing column, so that characters like box drawing and _ don't have gaps
take a look at XMO in XMODE
oh, yes you true
lets goo, now there is a real shell with input and commands
unfortunately there are some graphical bugs
and i added CLEAR command
okay, now i will try to implement disk I/O, Int 0x13 style. Should i support CHS reading or only use LBA?
i implemented a syscall for reading an ATA disk
now i will try to implement writing onto the disk
writing to the disk is implemented, too
lets goo, LS command works
better LS command and READ command
cool
thanks
beautiful
thank you!
Maybe for a real mode os it's a little big, but nothing bananas
such numbers are unheard of
blame the font
but honestly as long as it can fit on a 1.44mb floppy its okay
doesnt his os run in protected mode now?
Wait yeah 😂
oh
yes, my new OS (XMODE)
but its made for hard disks with the size of 9MB - 2GB
wait this is all asm right how much data do you have in there
~7KB of text files
https://github.com/xiromos/XMODE my 32bit OS is now public
this is amazing
umm
hmmm...
i tried...
you can't compile it?
which one
Lol
what does that mean?
i didnt want everything to have in one giant file
sure but you could've used relative paths
could you send the flags you used for the compiler and the linker
and your linker script if you have one
btw why arent the build scripts in the repository
i decided to use flat binaries
so...?
how do you want people to build your OS
or help you to fix your build scripts
if you don't push them
aah
wait
thats a serious problem
ENTRY(_start)
SECTIONS
{
. = 0x20000;
.text :
{
*(.text*)
}
.rodata :
{
*(.rodata*)
}
.data :
{
*(.data*)
}
.bss :
{
*(.bss*)
*(COMMON)
}
}``` this is my linker script
and flags for the compiler were -m32, -ffreestanding and -c
you probably need to add the GOT to the linker script after .data
.got : {
*(.got)
*(.got.plt)
*(.igot.plt)
}
that or you probally need more compiler flags for things
also should like push things to git

assuming this is the error still
okay thank you, i will try that
write function works
i really dont know why there are this lines
btw happy birthday
Hey Ty
maybe some mem corruption?
maybe
i have a folder now which contains the file autostrt.sys. if this file contains the number 1, my 32bit OS will be started automatic. for that i implemented a function which can load a directory, search a file in it and load it to a specific adress in memory
xasm.bin is btw the Xiromos Assembler, which i now will code
@cinder bronze finally C code
let's gooo
this is just a program
the OS itself is fully written in assembly
ah
how do i emulate a drive in QEMU with DMA controller?
i am trying to find a mass storage device with IDE controller because i try to implement DMA driver
emulate it in qemu
i try this command but it doesnt seem to work
google it, it will explain it better
wait, 70018086 01018000 is a PIIX3 IDE controller
no you can also write on it
lets goo, i found the device finally
now i can write DMA driver
then my OS will be much faster because of faster disk read
no its not
@cinder bronze I'm afraid I have to disappoint you
but i think i will code the assembler in assembly
because C is too compilacted
in what sense?
what is the issue?
i dont know, i would have to learn the whole language. i had problems with just calling a syscall. also there is this compiler which always tries to optimize your code. i like assembly more, its just so much easier
syscall is a separate thing from c
also, the compiler optimizing code is a good thing
(you can disable it for debug)
so you don't have issues with the language itself
almost every C compiler allows you to write inline assembly
it is like asm you embed in your C code
you can also call your asm functions from C
like this
; functions.asm
use_syscallX:
; do something
ret
// kernel.c
extern void use_syscallX(void);
and then you can call it as a normal C function
okay, thank you
maybe i will do this
whohoo, mov instruction work
CLC /CLD / CLI work also
and STC / STD / STI
but that was the easy part
and you can do comments
like syscalls literally ahve nothing to do with the language
yes but i have to call syscalls in this language
and that is harder than in assembly
Inline assembly:
You can also very well link assembly code with C
And have an assembly function to invoke a syscall
And that function can be invoked from C
i hate the syntax
Well then make a function in assembly and call it from C
And assembly can even call functions made in C
okay i will try that
?????
wat
like
inline assembly?
true
try rust
although you will have to fight the borrow checker and other bs
i never coded in rust
💀
LETS GOOO
my assembler can now assemble in 16bit or 32bit mode
and the TEST.BIN program actually worked because i added RETF instruction
you can set the bits via $b
for example $b32 says the assembler it must compile for 32bit mode
hooray
why a instead of ax?
i changed it and i added SI, DI, SP, BP registers and the INT instruction
i made a real installer for my OS
and i have a test branch for both projects now on github
great!
thanks
i improved it
now it copys actually every single item instead of copying cluster for cluster
this allows you to copy the OS to disks with a completly different geometry and different sec_per_cluster
did you test it in real hardware?
yes i tested it but it just freezed. this always happens when i try do disk I/O. i think the error is something with the drive number because the usb stick is marked as drive 0x00, but my disk I/O is extended LBA
which is for hard disks
but if i can fix that it should work perfectly on real hardware, too
fixed the LSDISK program
now it actually shows available drives and its size
btw B:/ is only 128KB because it is formatted with my own FAT8 and 128KB is the limit
My installer supports up to 512MB big disks, but unfortunately right now it doesnt work properly with large directories like A/B/C/D/E
it works fine with copying only root and root/subdir
what is D detected as? it doesn't seem to show in floppies or disks
D is a hard disk
floppies are A and B
there can be only 2 floppies active at a time
LETS GOO
i can now create windows in different sizes and i can write in them
here is a bigger window for example
you can create it in the size you want and you can specify the background color and the text color
i added a title
thank you so much
making a shell in an extra window
this is the start of multitasking
i pushed everything to the dev branch on github
cool
now the syscall for drawing a window saves the content, which is overwritten by a window, in a buffer and restores it, when the window is deleted
💀
yes
and a syscall for deleting it
you shouldn't use syscalls for that
my idea was, that at a start the program could either run in the shell or draw a window and run in it
not even to draw something directly
i've never designed a gui in an OS before but i think that everything related to windows should run in userspace
your window manager should be a program for example
and ig the framebuffer should be accessed via a file (like /dev/fbX)?
please someone say if I'm wrong
btw do you have userspace @echo granite
Yes; with and there are some IOCTLs and MMAP too
yes i have, all my programs run in userspace
ok
@echo granite so basically you should use syscall write on /dev/fbX
i guess
depends
e.g. Windows NT 4.0 and later has it in the kernel as win32k.sys
tho it started out in userspace and was moved to kernel space for performance reasons
k i see
tho they probably regretted that decision
why that?
what is fbX?
i think i will keep the syscall for drawing a window but i will limit it to 2 windows per process
when i have multitasking
Framebuffer
X is a placeholder for a number
e.g. /dev/fb0
/dev/fb1
etc ...
The kernel can expose through the path /dev/fb0, so that an application can open a FD, and then use this FD to read or write to the FB.
Or more likely, mmap it into its own address space.
okay, but how does the program then draw a window?
this should do the kernel for the program right?
because the program could destroy the framebuffer
It draws it itself.
Yes, but you could make it so that only programs with root can directly access the framebuffer device file.
but if you create in windows a window you dont draw every pixel
you can create it via a function i guess, but im not sure
for example if you use tkinter in python you call a function and give it x, y, width and height to draw a window
You'd have some windowing system running as a userspace process that does it for the program.
yes, thats a good idea, but what is the difference between the kernel drawing the window or the userpace program drawing the window?
Well, on Windows, you'd call something like CreateWindowEx, which is a function of the user32.dll shared library.
This in turn probably calls the kernel-side backend implemented in win32k.sys.
In principle you could do either, but it's generally good practice to keep stuff in userspace (to a reasonable extent). This is because a bug or security vulnerability in the kernel is generally more fatal than in userspace.
okay, then i will do it like this
implementing multitasking isnt that hard i guess
Also, what we discussed here applies to drawing something on top of a framebuffer. For accelerated graphics, things get more complicated.
But for a simple framebuffer, the kernel typically exposes it as something similar to Linux' fbdev, and userspace takes it from there.
For input on Linux, look up evdev.
yes, thats true
cli
pushad
push ds
push es
push fs
push gs
cmp word [task_count], 2
jb .done
movzx eax, word [current_task]
imul eax, 4
mov edi, tasks_esp
add edi, eax
mov [edi], esp
mov ax, [current_task]
inc ax
cmp ax, [task_count]
jbe .load_next
mov ax, 1
.load_next:
mov [current_task], ax
;load next task context
movzx eax, word [current_task]
imul eax, 4
mov edi, tasks_esp
add edi, eax
mov esp, [edi]
.done:
mov al, 0x20
out 0x20, al
pop gs
pop fs
pop es
pop ds
popad
iret```
mov ax, [max_tasks]
cmp word [task_count], ax
jae .too_much_tasks
;save shell context
mov eax, 1
imul eax, 4
mov edi, tasks_esp
add edi, eax
mov [edi], esp
inc word [task_count]
mov esi, read_buffer2
mov esp, program_stack
push ss
push esp
pushf
push code_off_user
push program_addr
pushad
push ds
push es
push fs
push gs
movzx eax, word [task_count]
imul eax, 4
mov edi, tasks_esp
add edi, eax
mov [edi], esp
jmp program_addr
mov ecx, 100
.loop:
mov al, '#'
call print_char
dec ecx
jnz .loop
ret```
max_tasks: dw 2
current_task: dw 0
tasks_esp:
dd 0 ;task 0 (reserved)
dd 0 ;task 1 (shell)
dd 0 ;task 2 (program)
dd 0 ;task 3 (program future)```
when the shell is started by switching to ring 3 the task_count is incremented by 1
and if i start another program the taskcount should be incremented again, so the scheduler can switch between the tasks
in theorie the whole multi-tasking process should work like this: i start a program, it pushes the context and increments task_count, then the program is executed because IRQ0 switches between the two different tasks, so the program works while '#' is printed
but unfortunately the program just starts and nothing happens then, the '#' isnt printed.
and i dont understand why this is so
i dont use TSS because shell and program are both in ring 3 so there is no ring switch
dont you need a TSS for multitasking?
you need it to switch between userspace and kernel space
or well, it's not required
(you can do it without, but it's a PITA)
you will 99% need the TSS
Well if you wana take an interrupt in userspace and not die you need it
from what someone said you can go without it
but you have to handle it very carefully
Well that person is stupid
The CPU pushes shit to the stack
You don’t want that on a userspace controlled stack
i have a tss but i dont think you need it when switching between two ring 3 programs
or do i need it?
This is also why you want SMEP/SMAP to prevent this
You need it when running anything in ring3 because if you get an interrupt while running there your stack won’t switch properly
And you need a kernel controlled stack for that
you do
bc the switcher is an interrupt
or well, you still have to go back to kernel
You can use the TSS for task switching but that’s stupid imo
And iirc it’s slower than normal software switching
No it’s not
Task switching does not have to be from an interrupt
You should be able to task switch at any moment in the kernel with a few exceptions
yeah i somewhat corrected it with the second msg
I’m still going to be very explicit here because this is a common topic for people to be confused by and you aren’t helping with some of the stuff you are saying lol
LETS GOOOOOO
MULTI TASKING
i dont know why the window is so buggy
anyways
i can type in the window while in the background there are printed the '#'!!!!!!!
this means the CPU switches between the program and the shell
whohoooooooo
but there is still a problem
when i type somthing the CPU generates a ton of exceptions so it triplefaults
you can even see the GP in the corner
or it freezes
x16-PRos is a little bit compatible with my OS. i do the command qemu-system-x86_64 -fda x16pros.img -hda disk.img
you can read, write, delete files from x16-Pros in my OS and switch directories.
@ProX
because both OSes use the same filesystem ig
Don't they both support FAT12?
yes
no, i can change some adresses in my OS and then even the programs of x16-PRos will run
because we both use the same format
flat binary
@timber wraith why is ProX banned from the server?
read his thread
but they are not compatible
the only way to do this would to use a binary format that supports fat binaries
iirc Mach-O does this?
why?
they can run on my OS if i change some adresses
yes because they both can parse the same binaries
and filesystems
guys, if a program is in ring 3 and an interrupt appears, does it push only EIP, flags and CS onto the stack or does it push also ESP and SS?
because for my multi tasking i use the timer interrupt
it's a normal interrupt
the whole copying from MikeOS and lying about it and covering it up thing
its a switch from ring 3 to ring 0
when there's a CPL change, it pushes ESP and SS as well
oohh, now i see the problem in my task switching
FINALLY I GOT MULTITASKING WORKING
you see that i type in the shell in the background and in the window
this is because the CPU switches between shell and program
multitasking!!!!!
it took me 4 days....
nice!
thanks!
great
thank you!
@cinder bronze what is your current project?
i started to work on a kernel in c++ a few days ago and i'm also working on a traditional roguelike (in c++ too)
isnt your project benix?
i archived the repo
it wasnt fun anymore
and i wanted to experiment with c++
you cant see it but there are 3 windows stacked. i improved the scheduler so now 4 tasks (3 programs + shell) can run at the same time
also, when i finish the multi tasking i want to make a window tiling manager for my OS like i3 wm
if the E in EAX stands for extended, what does the R in RAX mean?
register :^)
rextended
considering theres a REX prefix 
is this an english word?
Its an Intel word
i see
didnt come it from AMD?
I made it up btw
i improved the keyboard handler. now it checks current task with foreground_task, and if equal it returns the key
now only the foreground task has the keyboard, which is much better
you can see, that i can type text in the window but not in the shell
woah that's a window up there
Yes
i worked a lot last month
i think i make a break soon
but first i want to do window managment
window tiling manager
look at my progress, in 3 months i upgraded my first OS a lot + made a second multitasking + window managment kernel
i suppose so
if it even has GUI / multitasking
whats that?
currently i have no paging
but i want to use it
💀
look, no you can switch between tasks. you can see that there are 3 window tasks running and im typing in the shell because i switched to the shell and started new programs
Now it is real multitasking
i want to implement it soon
i think i will make a seperate UEFI bootloader for my 32bit OS, so it can run on newer machines, too
because now it is started only trough the BIOS, which is nice and easy, but CSM support disapears and i want my OS compatible with newer computers
then the user can chose if he uses Xiromos (legacy BIOS) as bootloader or my new bootloader for UEFI
so my OS is compatible with the i386 and new computers
i hope
why 32 bit OS
just go 64 bit
¯_(ツ)_/¯
you will have to go back to protected mode then
i know, but i think its not that hard
noo
my OS is designed to be compatible with the i386
while it should also be able to run on newer machines
can you load a .efi file from a FAT16 partition?
Gemini said its possible but i dont trust it
you can make a multi-arch OS
for both x86 and x86_64
what is multi-arch?
how is that possible?
it is easy
because both architectures have similar mecanics
(it would be a lot easier in C tbh)
if you keep using asm you would need to write 2 kernels instead of one
why does it work with C?
does the C compiler compiles the code for 2 different architectures?
because C allows you to abstract things
yes it can target different architectures
please just use C 😭
nooo
why
its so complicated
no 😭
it is not
it is wayyyy easier to write complicated stuff in c than in asm
you just dont wanna learn the language
yes
why
i got used to assembly and its easy to work with
no
it isnt
try to write high level stuff with it
you would struggle for a while
okay, i will resume coding my OS in Assembly but i will learn C on the side so later i can implement stuff in it, too
deal?
deal
my UEFI bootloader is almost done, then the system supports BIOS and UEFI and is able to run on newer machines without BIOS
what do you think guys, should i make a documentation about my OSes?
because i dont know, on the one hand only i am working on it and no one would need it, but on the other hand, maybe its interesting to read and someone could learn something
GUYS I MADE IT
my OS supports UEFI and BIOS booting
- look how much cleaner my screen looks when i use UEFI
there are no yellow pixels anymore, this is a BIOS bug i think, idk
but now it looks so much cleaner
this is how it looks with BIOS
there are these stupid yellow things
maybe i will try implement multicore soon
you only really have to worry about your scheduler for that
(and maybe a lot of race conditions that will randomly pop up)
what are race conditions?
idk, but i'm sure you'll find them
okay
btw i implemented busmastering DMA disk I/O, so now my OS supports ATA PIO mode and IDE DMA read
now i want to take a look at AHCI
i'm starting with NVMe
huuh, not tried yet
NVMe works in a completely diff way
and i think it's simpler too
yes its different but i dont think its simpler
arent there queues and stuff like this?
queues are ring buffers
what are ring buffers?
buffers that when you reach the end, they wrap around to the start
how does that work?
i didnt get it
like, if an array is 5 long
when you reach index 4
the next iteration you set index back to 0
it supports PCI, but im not sure about PCIe
tho in emulation you can do anything
thats true
yeah, okay
Guys, i have a problem
if i emulate an AHCI device in QEMU, then disk I/O on my 16Bit OS part doesnt work properly
when i try read i file, the BIOS just hangs
if i emulate an IDE device, everything works
the most interesting part is that the kernel is loaded, but the kernel itself cant do anything then
this is exactly the same problem i have on real hardware
but how do i fix this? its a BIOS issue i guess
what context?
the code would suffice
just a normal INT 0x13h read (extended):
mov ah, 0x42
mov dl, [drive_number]
int 0x13```
show dap
here it is:
mov [file_dap+6], word 0x8000
.load:
mov ax, [program_cluster]
call cluster_to_sec
mov [file_dap+8], ax
xor cx, cx
mov cl, [sec_per_cluster]
mov [file_dap+2], cx
file_dap:
db 0x10 ;size of packet (16 bytes) [program_dap+0]
db 0 ;always 0 [program_dap+1]
dw 0 ;number of sectors to read [program_dap+2]
dw 0x0000 ;offset [program_dap+4]
dw 0x0000 ;segment [program_dap+6]
dq 0 ;LBA [program_dap+8]```
there is also the code how i fill it
program cluster is a valid number, something like ~40
I meant can I see the values you pass that fail
mov [file_dap+2], word 1
mov [file_dap+4], word 0
mov [file_dap+6], word 0x2000
mov [file_dap+8], word 4
mov si, file_dap
mov ah, 0x42
mov dl, [drive_number]
int 0x13```
all reads fail, no matter what values i use
drive_number is 0x80
assuming si is zero it looks valid yeah
sounds like a bios issue but cant really comment further without testing myself
yes, it only appears when emulating an AHCI device, classic IDE works fine. Also, when i test it on real hardware i use an USB stick which is a xHCI device, which has the same problem - the BIOS reads freeze the system
bruh, i edited a text file in a hexeditor and added at offset 510 the bytes 0x55 and 0xAA and now im booting from a text file
😂
i have multidisk support now
AHCI driver isnt working right now but im working on it
but my OS already supports PIO Mode and Busmastering DMA
how hard is it to make a GPU driver for the NVIDIA Riva or TNT?
A LOT
you have better chances to just port an existing one
anything gpu driver related is hell on earth
99.99999% you will not be able to do anything
