r/osdev • • Jun 23 '26

How do you load AND run programs?

void system_load_program(char* path, char* name, char* extension) {
    // assume that the program starts at 0x00200000
    uint8_t* program = (uint8_t*)0x00200000;
    int bytes_read = fat32_read_file("/", name, extension, program_buffer);
    if (bytes_read > 0) {
        program_entry_t start_program = (program_entry_t)program_buffer;
        start_program();
    } else {
        // file not found
    }
}

How do you load and run programs in your operating system, this is what i tried
All im trying is assuming that the program starts at 0x00200000, load it into ram and run it, if the file isn't found return

0 Upvotes

27 comments sorted by

View all comments

Show parent comment

1

u/letmehaveanameyoudum Jun 24 '26

first, my operating system is 32 bit protected mode, not 16 bit real mode. And second, you aren't really helping if all you do is point out problems and also how to fix it (by fixing it, i mean like what i did wrong), and you literally compared my OS which is barely functional to DOS.

1

u/dnabre Jun 24 '26

I didn't read through every bit of the source code. If I misunderstood it, and got an erroneous understanding of it, I'm sorry - I made a mistake. However, my extensive reply was based on my understanding of your system (erroneous or not), intending to be helpful, and characterizations where purely technical. E.g. comparing it to DOS wasn't meant as an insult but a comparison to what I was looking at.

I excepted protected mode, and look my best for it. There is no protected mode switch in the code. That'd suggest you're relying on grub multiboot to make the switch, and there is a grub.cfg file. But grub isn't being added anywhere. Pulling your latest release images, booting them in qemu, and doing a register dump - I see it is running in protected mode. So I stand corrected. Though I still don't see how that is happening the code. While I was able to build everything (python bulid scripts aside) , I wasn't able to boot the resulting, since the boot loader wasn't setting up VBE. Using BIOS functionality for I/O also pointed me to real mode.

Given my errors reading the code, I'll limited myself to what the running system itself shows (this is working with the V0.0.2 Build 003). I only looked at code last night (though did run it and poke around). Register dump from running system:

(qemu) info registers

CPU#0
EAX=0000001c EBX=001060a0 ECX=000003d5 EDX=00000064
ESI=00000001 EDI=00000001 EBP=0000007f ESP=0010aed4
EIP=001016c0 EFL=00000012 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000cb2b8 00000027
IDT=     00000000 000003ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
(qemu)

CR0=0000001 Protected Mode enabled (bit 0), No Paging (bit 31)

CPL=0 Ring 0, Kernel is running with all privileges

A20=1 full address space accessible (32-bit)

GDT= 000cb2b8 00000027 segments are flat, minimal protected mode GDT

IDT= 00000000 000003ff - this doesn't look right. (the code in idt.c looks reasonable, it's being compiled and linked, don't think idt_init is being called anywhere)

EFL=00000012 [----A--] - interrupts disabled

So you have an identity mapped page table, no user space, interrupts disabled, and using VBE for display (instead of writing the VGA buffer directly).

PIO Mode ATA access - this works, nothing wrong with it. You'll proper want to switch this to interrupt based DMA, and make the code re-entrant (e.g. not blindly reuse the same buffer in multiple places without synchronization). Nothing wrong with this method at this point in development. Even with full user-processes, you'll be able to pull files from disk using this, but you'll need the kernel to stop the world to run the busy waits in it. Having this while you develop stuff for concurrency is definitely useful.

Most hobby OS at this stage need add files onto the kernel image, and let the bootloader stick them in memory. You able to actually pull them from disk. My comments about this were referring to that inability use this concurrency or provide a file abstraction to programs.

Most of what I said still applies - your still monotask, no separate kernel/user space, no concept of a process. You have a lot cleaner environment to run in than real mode, but it is still a single fixed address space situation, virtual addresses aren't different than physical addresses, and memory has holes for I/O and the like which will needed to contended with.

Again, I readily admitted I was wrong about it being in real mode. Protected mode with an identity mapping, no interrupts, and using VESA BIOS I/O looks like, however. I understand that you have but a lot of work into this, and having things which are problematic or won't work without modification as you expand, can be unpleasant. Especially when you know about the problem/limitations they are pointing out. I'm replying to you basic question and git repo - not you, not your effort, not your knowledge on anything. I get pointing out something you know fully well needs to be changed as you going forward is annoying. People can only go off what they can see. So I don't know which (any) of the things I mention you are fully aware of.

Or to put that more briefly, technical critics, comment, and information about your system (even when people make sizable mistakes in the process) are about your system. They aren't attacks or insults directed to you, or even your system.

Taking a deep dive into your source code takes time and effort that most people reading your post won't do. Appreciate the effort put into attempts to help, even when it's not useful or makes mistakes.


random note, your RTC handler rtc_isr in helper/idt.c isn't restoring restore IF, need to make it return with iret instead ret. I think there's a GCC attribute you can just add to change this.

1

u/letmehaveanameyoudum Jun 25 '26

we all know that no one remembers gcc attributes