Page 1 of 2
Second Stage Bootloader is not working...
Posted: Mon Aug 28, 2023 9:55 am
by protos
Code: Select all
#include "../cpu/idt.h"
#include "../cpu/isr.h"
#include "../cpu/timer.h"
#include "../drivers/ports.h"
#include "../drivers/hdd.h"
#include "../drivers/display.h"
#define ET(x) printf("Error Trace %s\n", #x);
#define PUSH_ALL asm volatile ( \
"pusha \n\t" \
: : : "memory" );
#define POP_ALL asm volatile ( \
"popa \n\t" \
: : : "memory" );
void* search_signature(void* start_address, size_t size, uint32_t signature) {
for (size_t i = 0; i < size - sizeof(uint32_t) + 1; i++) {
uint32_t value = *((uint32_t*)(start_address + i));
if (value == signature) {
// Signature found, return the address
return (start_address + i);
}
}
// Signature not found in the given range
return NULL;
}
int check = 0;
void start_kernel() {
if(check == 1) {
clear_screen();
ET(start)
while(1) {}
}
PUSH_ALL;
readFromHardDrive(33, 2880, (void*)0x200000);
void* sig = 0x200000;
void* jmp = 0x1000;
while(sig = search_signature(sig, 512*2880, 0xDEADBEEF)) {
printf("signature found at %p\n", sig);
jmp = sig;
sig++;
}
memcpy(0x100000, jmp-9, 0x100000);
hexDump(0x100000, 64); // everything is in place
getch();
POP_ALL;
ET(usw)
check = 1;
// Rufe den Eintrittspunkt von kernel2.bin auf
void (*functionPointer)() = (void*)0x100000; // kernel_start_main;
printf("functionPtr = %p\n", functionPointer);
functionPointer();
ET(etc)
}
functionPtr is not called without notice, but probably double-tripple faults. If i keep the complete Kernel that is a little bit bigger ~49KB at address 0x1000, everything works until i overwrite the stack. So i need to second-stage, i know my way is more than unprofessional, but i dont get why this is not working. If i stay the one-load way, then copy 64KB from 0x1000 to 0x100000 and jump there it works, now i have spilt the project up in kernel.bin and kernel2.bin and amusing:) correct linker scripts. Where is the fault ?
Happy Coding! as GPT says.
Re: Second Stage Bootloader is not working...
Posted: Mon Aug 28, 2023 10:05 pm
by Octocontrabass
protos wrote:Code: Select all
#define PUSH_ALL asm volatile ( \
"pusha \n\t" \
: : : "memory" );
#define POP_ALL asm volatile ( \
"popa \n\t" \
: : : "memory" );
Inline assembly is not allowed to modify any registers without informing the compiler, and the compiler automatically handles saving and restoring registers according to the ABI. What is this code supposed to do?
protos wrote:Code: Select all
uint32_t value = *((uint32_t*)(start_address + i));
Misaligned pointers are undefined behavior. Also, you shouldn't need to search for your entry point. If you're using a flat binary, you can write an assembly stub that jumps to the real entry point and use your linker to place that stub at a fixed offset in your binary.
protos wrote:probably double-tripple faults
Have you used a virtual machine to check? QEMU and Bochs are both capable of logging exceptions.
protos wrote:Where is the fault ?
Where is the rest of your code?
protos wrote:Happy Coding! as GPT says.
GPT is a liar.
Is there any particular reason why you've decided to write your own bootloader instead of using GRUB or Limine? It's fine to write your own bootloader for fun, but it will make writing your OS that much more difficult.
Re: Second Stage Bootloader is not working...
Posted: Tue Aug 29, 2023 7:18 am
by protos
Yes, i want do as much as possible for educational fun myself. I took some barebone from (Uhh.. forgot) and added some stuff.
https://github.com/krypniok/junkyard/tree/main/DeuterOS
Now i have tried to sepearate it and what you see is the difference.
https://github.com/krypniok/junkyard/tree/main/ProtOS
Yes i am only using QEMU, VirtualBox is weirdo, generates another output.
I hope that at least with BGA i will get to that pixel
Many thanks for your help in advance
Re: Second Stage Bootloader is not working...
Posted: Tue Aug 29, 2023 9:54 am
by Octocontrabass
protos wrote:I took some barebone from (Uhh.. forgot) and added some stuff.
You followed a buggy tutorial. Now your code has bugs from the tutorial.
protos wrote:Now i have tried to sepearate it
Now that I can see more of your code, I don't understand what you're doing. You don't have to load your kernel at 0x1000, you can load it somewhere else!
Which of those repos has the code you want to fix?
protos wrote:I hope that at least with BGA i will get to that pixel
Why not use VBE? Then you can have your pixels everywhere, even without BGA.
Re: Second Stage Bootloader is not working...
Posted: Tue Aug 29, 2023 10:16 am
by protos
All VESA/VBE tries faild so far, i just haven't tested BGA yet, its another goal.
Deuteros is working "flawlessly" < ha ha
and yes, i have tried to read it from disc directly to 0x100000, doesn't work well, as you could see with that approach in mbr.asm that s commented out, yes it works, but i cannot load more than 53 sectors, why ?
So the other attempt in ProtOS, GTP says its seems to be stack problems, i dont know how to identify.
Re: Second Stage Bootloader is not working...
Posted: Tue Aug 29, 2023 10:50 am
by Octocontrabass
protos wrote:All VESA/VBE tries faild so far,
Share your code. We can help you fix it.
protos wrote:and yes, i have tried to read it from disc directly to 0x100000, doesn't work well, as you could see with that approach in mbr.asm that s commented out, yes it works, but i cannot load more than 53 sectors, why ?
You still load those sectors to 0x1000 before you copy them to 0x100000. You can't load more than 54 sectors that way because it will overwrite your MBR at 0x7C00. You also didn't set ES, so you might actually be loading it somewhere else!
protos wrote:So the other attempt in ProtOS, GTP says its seems to be stack problems, i dont know how to identify.
GPT learned from the same broken tutorials you used, which means GPT doesn't know that
the problems start all the way back at the first instruction of your boot sector. The BIOS doesn't initialize segment registers, and this instruction accesses memory using DS. There are several places where your boot sector relies on uninitialized segment registers.
Re: Second Stage Bootloader is not working...
Posted: Tue Aug 29, 2023 11:00 am
by protos
Tell me how i can copy that entire diskfile/harddiskfile (1.44MB or more) in one call to the desired address. or is there some problem with 0x100000 ?
54 because the disk_load function is in 16bit mode i know, but how can i then ?
Re: Second Stage Bootloader is not working...
Posted: Tue Aug 29, 2023 12:04 pm
by Octocontrabass
protos wrote:Tell me how i can copy that entire diskfile/harddiskfile (1.44MB or more) in one call to the desired address.
Do you mean a single INT 0x13 call? That's impossible. INT 0x13 can't load more than 127 sectors (63.5kB) from a hard disk in a single call, and the limit is lower for a floppy disk. INT 0x13 can't access memory above 0xA0000, so you need to load your data and then copy it to the desired address. There's less than 640kB of available memory below 0xA0000, so you have to switch between loading and copying to get everything into memory.
Are you sure you want to write your own bootloader instead of using GRUB or Limine? They take care of this problem for you.
protos wrote:54 because the disk_load function is in 16bit mode i know,
I don't think you know. Do you understand how segment registers work in real mode?
protos wrote:but how can i then ?
Use a different address. If you use 0x10000 instead of 0x1000, there's plenty of space. (But you need to fix your stack!)
Re: Second Stage Bootloader is not working...
Posted: Tue Aug 29, 2023 12:34 pm
by protos
My approach works for the data part, the kernel2.bin is linked for 0x100000 and (the signature is for double check), i can / you can check that with the onboard tool (dump) kernel2.bin is located at 0x100000, as if i would do it again within the mbr.asm, but i dont get the size i want then, and now with the "second" kernel, i just dont get the stack management right ? what do you mean with i dont use ES ? would you try to explain it to me in more detail so that i can adapt it ?
Okay, i try to get it, i stay the way it was, but copy it over in smaller chunks !?
What i really want is to make all this in 2ndstage.asm, but the disk_load function is 16bit code, i have to ask GPT:( to convert it for me to 32bit assembly, because i dont know how to call that c funktion i have from within than assembly.
Re: Second Stage Bootloader is not working...
Posted: Tue Aug 29, 2023 1:38 pm
by Octocontrabass
protos wrote:what do you mean with i dont use ES ?
I don't understand your question.
You use ES right here. The address of your buffer is ES:BX. You didn't set ES, so ES contains some random value.
protos wrote:would you try to explain it to me in more detail so that i can adapt it ?
Your post is very confusing, I'm not sure what you need me to explain.
protos wrote:Okay, i try to get it, i stay the way it was, but copy it over in smaller chunks !?
What do you mean? You should be able to use larger chunks, not smaller. Set ES:BX to something like 0x1000:0x0000 to put your buffer at 0x10000, then you can load 127 sectors instead of 54. If you want more than 127 sectors, call INT 0x13 again. When you've loaded about 512kB of data, copy everything from 0x10000 to 0x100000. If you want more than 512kB, start over with INT 0x13.
protos wrote:What i really want is to make all this in 2ndstage.asm, but the disk_load function is 16bit code, i have to ask GPT:( to convert it for me to 32bit assembly, because i dont know how to call that c funktion i have from within than assembly.
You can't use INT 0x13 in protected mode.
Re: Second Stage Bootloader is not working...
Posted: Wed Aug 30, 2023 2:37 am
by protos
What do you mean? You should be able to use larger chunks, not smaller. Set ES:BX to something like 0x1000:0x0000 to put your buffer at 0x10000, then you can load 127 sectors instead of 54. If you want more than 127 sectors, call INT 0x13 again. When you've loaded about 512kB of data, copy everything from 0x10000 to 0x100000. If you want more than 512kB, start over with INT 0x13.
Thanks, i'll will make that then. In hdd.c i already have the 32-bit functions for harddisk read and write. But the writeToHardDrive seems not to work, that bogs me more
Many Luck'n Love
Re: Second Stage Bootloader is not working...
Posted: Wed Aug 30, 2023 7:52 am
by protos
when i do it like this
Code: Select all
[bits 32]
BEGIN_32BIT:
pusha
mov esi, 0x1000 ; Source address
mov edi, 0x100000 ; Destination address
mov ecx, 0xFFFF ; Length of data to move
cld ; Set the direction flag to forward
rep movsb ; Move the data from source to destination
popa
call 0x100000 ; Give control to the kernel
jmp $ ; Stay here when the kernel returns control to us (if ever)
It works, even if the code was linked for 0x1000.
Why is the same not working from the C code in the first post ? Where do i have the Stack screwed up or something, how can i Debug it without gdb ? Not ?
Re: Second Stage Bootloader is not working...
Posted: Wed Aug 30, 2023 8:59 pm
by Octocontrabass
protos wrote:In hdd.c i already have the 32-bit functions for harddisk read and write.
But those functions only work for ancient legacy IDE drives, not modern SATA or NVMe. That's why you should use INT 0x13 to load everything.
Re: Second Stage Bootloader is not working...
Posted: Sat Sep 09, 2023 6:11 pm
by neon
Hi,
Tell me how i can copy that entire diskfile/harddiskfile (1.44MB or more) in one call to the desired address. or is there some problem with 0x100000 ?
A little late but wanted to bring up the strategies on loading large files or loading beyond 1MB
+64k from boot loaders.
For these scenarios you'll need to switch between real and protected modes or use unreal mode. I use the former strategy however had heard successes with using unreal mode as well. With the former strategy, there are basically two designs: (1) a generic BIOS call function and (2) a set of specialized BIOS call functions.
Our loader is based on (1) such that there is the lowest level function that switches from protected->real->protected to call the BIOS and a set of specialized drivers that call this as needed i.e. the BIOS Disk driver which implements
DiskRead. All loads are through real mode int 13h (legacy or extended) and data is cached and copied as needed in protected mode.
how can i Debug it without gdb
Serial port can be used for sending debug messages (and can be used to connect to a debugger if you have the framework setup.) Virtual machines typically support a way to send serial data to a text file so you can use it for free logging. Until then you are stuck with what you have. I used bochsdbg.
Re: Second Stage Bootloader is not working...
Posted: Sat Sep 09, 2023 8:07 pm
by Octocontrabass
neon wrote:For these scenarios you'll need to switch between real and protected modes or use unreal mode.
There's also
INT 0x15 AH=0x87, which is basically the same thing except it works before you enable the A20 line.
Still, the BIOS can't directly load data from the disk above 1MB, and it can't load more than 127 sectors in a single call. You have to split it into separate operations (load some sectors, copy above 1MB, repeat) to bypass those limitations.