OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 2:49 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 36 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Bootloaderis not consistent when booting in real hardware
PostPosted: Sat Jun 12, 2021 4:21 pm 
Offline
Member
Member

Joined: Sat Jun 12, 2021 4:13 pm
Posts: 46
Hi, i'm facing an issue that I can't really fix and it drives me nuts !
Basically, I have two computers, one a little bit older but it as still a 64 bits CPU and a modern one which also run on a 64 bit CPU. The problem is that on the older one, I can successfully read my boot sectors but on the modern one, it does not even print one of the first strings. Instead it print some garbage things all around the screen for like 2 seconds and then hangs.. I have the csm enabled in bios settings (in order to boot on my usb stick). Can someone help me ?
Bootloader.asm

Code:
[org 0x7c00]
[bits 16]
section .text
    global BOOTSECT


BOOTSECT:
    ; Making sure to reset every segment before loading.
    ; Because some BIOS tend to modify those..
    cli
    xor ax, ax
    mov ss, ax
    mov ds, ax
    mov es, ax
    cld
    sti


    ; Changing the bios background color to the default black one...
    mov ah, 0x0b    ;Function Code
    mov bh, 0x00    ; Function parameter
    mov bl, 0x00    ;Background color
    int 0x10

    mov bx, MSG_START
    call print

    mov bx, MSG_READING
    call print

    mov al, 1
    mov cl, 2
    mov bx, 0x1000
    call readSector

    ; Changing the bios background color if success (GREEN)
    mov ah, 0x0b    ;Function Code
    mov bh, 0x00    ; Function parameter
    mov bl, 0x08    ;Background color
    int 0x10

    mov bx, MSG_SUCCESS_DISK
    call print

    jmp $

%include "print.asm"
%include "readSector.asm"

MSG_START: db "[INFO] Starting in 16-bit Real Mode !",13 ,10 ,0
MSG_READING: db "[INFO] Reading Sectors...",13 ,10 ,0
MSG_ERROR_DISK: db "[ERROR] Error Loading Disk !", 13 ,10 ,0
MSG_SUCCESS_DISK: db "[SUCCESS] Loading Disk Into Memory Succeded !", 13 ,10 ,0
times 510-($-$$) db 0
dw 0xaa55
times 512 db 0


readSector.asm

Code:
readSector:
    pusha
    mov ah, 0x02
    mov ch, 0
    mov dh, 0

    int 0x13
    jc disk_error
    popa
    ret

disk_error:
; Changing the bios background color FAIL (RED)...
    mov ah, 0x0b    ;Function Code
    mov bh, 0x00    ; Function parameter
    mov bl, 0x04    ;Background color
    int 0x10

    mov bx, MSG_ERROR_DISK
    call print
    jmp $


print.asm

Code:
print:
    pusha

printloop:
    mov ah, 0x0e
    mov al, [bx]
    cmp al, 0
    je done
    int 0x10
    inc bx
    jmp printloop
   
done:
    popa
    ret


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sat Jun 12, 2021 7:29 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
Are you perhaps using a USB flash drive? Firmware gets picky if you don't have either a MBR with a valid partition table and one active partition, or a FAT VBR with a valid BPB. The firmware might be trying to "correct" the geometry in your BPB, but since those bytes are part of your code instead of a BPB, it ends up corrupting your code.

I also found a bug:
liwinux wrote:
Code:
    mov ss, ax

You set SS but not SP. Where is your stack? You don't know! If your stack is somewhere it shouldn't be, that could also corrupt your code and result in strange behavior.


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 3:55 am 
Offline
Member
Member

Joined: Sat Jun 12, 2021 4:13 pm
Posts: 46
Octocontrabass wrote:
Are you perhaps using a USB flash drive? Firmware gets picky if you don't have either a MBR with a valid partition table and one active partition, or a FAT VBR with a valid BPB. The firmware might be trying to "correct" the geometry in your BPB, but since those bytes are part of your code instead of a BPB, it ends up corrupting your code.

I also found a bug:
liwinux wrote:
Code:
    mov ss, ax

You set SS but not SP. Where is your stack? You don't know! If your stack is somewhere it shouldn't be, that could also corrupt your code and result in strange behavior.


HI, thanks for taking the time to answer my question !

Correct me if I'm wrong but isn't the instruction [org 0x7c00] supposed to align the addresses ? So if I understood correctly, the stack would begin at the address 0x7c00 and that can cause the issue then right ?

Also, I don't get the part where you talk about the MBR, what am I supposed to do then ? How can I be sure that it will always boot ? I also should have pointed out before posting that I've made two bootable usb drives just to be sure and I got the same result.

Thanks again !


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 4:31 am 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
In theory, the BIOS only depends on the last two bytes of a 512 byte bootsector to be 0xAA55. Many BIOSes, however, require an MBR and/or a partition table to load. Lookup Master Boot Record strucutre and partition table structure. It is a structure that takes the first bytes of a bootsector. Also, stack issues could very well be a problem as well. Many BIOSes are really quirky, so don't be surprised by anything in a boot sector.

_________________
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 8:53 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
liwinux wrote:
The problem is that on the older one, I can successfully read my boot sectors but on the modern one, it does not even print one of the first strings. Instead it print some garbage things all around the screen for like 2 seconds and then hangs.. I have the csm enabled in bios settings (in order to boot on my usb stick). Can someone help me ?
It is a wonder that you can read sectors with floppy services from an device. My guess is, your newer machine does not support floppies and CHS addressing any more, so you'll have to use LBA addressing and Int 13/AH=42h. That always worked on all legacy CSM emulations I've run into.

Other than that, you don't set up a stack, so god knows what's going to happen on the first "call" instruction. You set "ss", but not the pointer, "sp", as Octocontrabass said. Aligning the address only means that your Assembler will produce code in compile-time expecting to be ran on that address, but this has nothing to do with setting up registers in run-time.

About the partitioning table and such: don't care. It only happens on some buggy BIOSes when they are in some kind of strange emulation mode. Your BIOS reads the boot sector, so don't mind that all. The magic bytes should be enough, and they are on both of your machines.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 10:14 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
liwinux wrote:
Correct me if I'm wrong but isn't the instruction [org 0x7c00] supposed to align the addresses ? So if I understood correctly, the stack would begin at the address 0x7c00 and that can cause the issue then right ?

No. The org statement only tells the assembler where in memory your code will be loaded, relative to the segment base, so it can translate labels into numeric addresses. You have to set both SS and SP to set the stack location.

liwinux wrote:
Also, I don't get the part where you talk about the MBR, what am I supposed to do then ? How can I be sure that it will always boot ?

I recommend adding a partition table with one active partition.

bzt wrote:
It is a wonder that you can read sectors with floppy services from an device.

CHS addressing has been a hard disk service since hard disks were first added to PCs. Have you found any CSMs that don't support CHS addressing?

bzt wrote:
About the partitioning table and such: don't care. It only happens on some buggy BIOSes when they are in some kind of strange emulation mode. Your BIOS reads the boot sector, so don't mind that all. The magic bytes should be enough, and they are on both of your machines.

Yes, it boots, but it doesn't work. A BPB or partition table is required to make it work.


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 2:02 pm 
Offline
Member
Member

Joined: Sat Jun 12, 2021 4:13 pm
Posts: 46
Hi guys, thanks for all those useful information, really...

I made some little changes as you all suggested me but still no luck... This time, it prints the first string 2X times. Still don't know what's going on here. I've removed every almost everything including the function where I read sectors just to test if at least printing things to the screen works, but as you can see it's still not working... If you could take a look, that would be awesome from you guys. I think i'm missing something here that I can't really understand.

Also, I've made MBR partition, used DD, also used Etcher etc...

Code:
[org 0x7c00]
[bits 16]
section .text
    global BOOTSECT


BOOTSECT:
    ; Making sure to reset every segment before loading.
    ; Because some BIOS tend to modify those..
    cli
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
   
    cld
    sti

    mov bp , 0x8000
    mov sp, bp


    mov bx, MSG_START ; This line is printed two times....
    call print


    jmp $

%include "print.asm"
%include "readSector.asm"

MSG_START: db "[INFO] Starting in 16-bit Real Mode !",13 ,10 ,0
MSG_READING: db "[INFO] Reading Sectors...",13 ,10 ,0
MSG_SUCCESS_DISK: db "[SUCCESS] Loading Disk Into Memory Succeded !", 13 ,10 ,0

times 510-($-$$) db 0
dw 0xaa55
times 512 db 0


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 2:13 pm 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3191
I start my boot sector with a far call so I'm independent on which CS BIOS uses. You only know that the code is loaded at 7C00, not that CS is 0.

Actually, I don't set CS to zero as it is much more convinient to set it to 7C0, because then there is no need to org the code.

Also, you clobber SS by resetting it to zero, and before you load SP with a reasonable value, you enable interrupts. This is not ok. You always must make sure that SS & SP are loaded as a pair without any possibilities for interviening interrupts. The usual way to do this is to load SS first, and then in the next instruction SP. This works since the CPU is designed to run those as atomic.


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 3:46 pm 
Offline
Member
Member

Joined: Sat Jun 12, 2021 4:13 pm
Posts: 46
rdos wrote:
I start my boot sector with a far call so I'm independent on which CS BIOS uses. You only know that the code is loaded at 7C00, not that CS is 0.

Actually, I don't set CS to zero as it is much more convinient to set it to 7C0, because then there is no need to org the code.

Also, you clobber SS by resetting it to zero, and before you load SP with a reasonable value, you enable interrupts. This is not ok. You always must make sure that SS & SP are loaded as a pair without any possibilities for interviening interrupts. The usual way to do this is to load SS first, and then in the next instruction SP. This works since the CPU is designed to run those as atomic.


So, I've modified once again my code, and it stills fail.
Code:
[org 0x7c00]
[bits 16]
section .text
    global BOOTSECT


BOOTSECT:
    ; Making sure to reset every segment before loading.
    ; Because some BIOS tend to modify those..
    cli
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov bp, 0x8000
    mov sp, bp
   
    cld
    sti

    mov bx, MSG_START ; This line is printed two times....
    call print


    jmp $

%include "print.asm"
%include "readSector.asm"

MSG_START: db "[INFO] Starting in 16-bit Real Mode !",13 ,10 ,0
MSG_READING: db "[INFO] Reading Sectors...",13 ,10 ,0
MSG_SUCCESS_DISK: db "[SUCCESS] Loading Disk Into Memory Succeded !", 13 ,10 ,0

times 510-($-$$) db 0
dw 0xaa55
times 512 db 0


Now, I'm wondering If it's more like an hardware compatibility issue at this point.
but I thought someone could write a boot loader to test if it works on my machine, that way I would be sure that I'm not doing anything wrong. If it works then most likely I was doing something bad and I could learn from my mistakes.. So could someone do that for me and be sure that it will work ? Just a simple one to test if it prints correctly. It could be written in asm as well in nasm I'll compile it myself.

Thanks again for taking the time to help me with my issue and teaching me new things, really appreciate it you all !


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 4:22 pm 
Offline
Member
Member

Joined: Sun Jun 23, 2019 5:36 pm
Posts: 618
Location: North Dakota, United States
How do you know your stack is at 0x8000? (Also, don't set CS to 7C0 -- just set it to 0 unless you want to be dealing with multiple segments.) Does your linker script place the stack at 0x8000?


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 4:30 pm 
Offline
Member
Member

Joined: Sat Jun 12, 2021 4:13 pm
Posts: 46
Ethin wrote:
How do you know your stack is at 0x8000? (Also, don't set CS to 7C0 -- just set it to 0 unless you want to be dealing with multiple segments.) Does your linker script place the stack at 0x8000?


Well, I don't use any linker script. In fact I just compile it and ask nasm to create a binary file. And also, if I set CS to 0, nothing works in QEMU. So, I just decide to set the stack safely away from 0X7C000


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 4:34 pm 
Offline
Member
Member
User avatar

Joined: Sun Feb 18, 2007 7:28 pm
Posts: 1564
Hi,

Load sp right after setting ss. I.e. there should be no instruction (like your load to bp) in between.

Also as noted above, your first instruction should be jmp 0:fixcs (due to org 7c00) to load cs:ip with known values.

_________________
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Sun Jun 13, 2021 5:03 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
liwinux wrote:
Also, I've made MBR partition, used DD, also used Etcher etc...

After creating the partition table on the disk, read it back and see what bytes it contains. If it's not valid or there's no active partition, it won't work. Post it here if you're not sure.

rdos wrote:
Actually, I don't set CS to zero as it is much more convinient to set it to 7C0, because then there is no need to org the code.

I disagree. Having nonzero segment bases now will just make things more confusing later.

liwinux wrote:
And also, if I set CS to 0, nothing works in QEMU.

The MOV instruction cannot be used to load the CS register. You have to use something like a far JMP if you want to set CS to 0. It's a good idea to set CS to a known value at some point, but your current code will work perfectly fine even if you don't set CS.

liwinux wrote:
So, I just decide to set the stack safely away from 0X7C000

The stack grows down, so placing it at 0x8000 gives you 512 bytes of stack before it starts to overwrite your boot sector. Some BIOS calls require more stack space than that!


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Mon Jun 14, 2021 1:01 am 
Offline
Member
Member

Joined: Sat Jun 12, 2021 4:13 pm
Posts: 46
So guys I think I made it , kind of because I don't really understand why it works now...
So basically what I've done is just relocate my "%include" at the beginning of my bootloader file as it was at the end before my padding... I don't know why it works now.. Can someone explain it to me ? Also, if I replace my "%include" where they were (at the end) AND remove the "section .text" part, it works too. It doesn't really make sense to me. I'm missing something here for sure !

Code:
[org 0x7c00]
[bits 16]
section .text
    global BOOTSECT

jmp 0x0000:BOOTSECT
%include "print.asm"
%include "readSector.asm"

BOOTSECT:
    ; Making sure to reset every segment before loading.
    ; Because some BIOS tend to modify those..
    cli
    xor ax, ax
    mov ss, ax
    mov sp, 0x9000
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    cld
    sti

    mov bx, MSG_START ; This line is printed two times....
    call print
   
    mov bx, MSG_READING
    call print

    mov al, 1
    mov cl, 2
    mov bx, 0x1000
    call readSector

    ; Changing the bios background color if success (GREEN)
    mov ah, 0x0b    ;Function Code
    mov bh, 0x00    ; Function parameter
    mov bl, 0x08    ;Background color
    int 0x10

    mov bx, MSG_SUCCESS_DISK
    call print

    jmp $

;; I used to place my %include here...

MSG_START: db "[INFO] Starting in 16-bit Real Mode !",13 ,10 ,0
MSG_READING: db "[INFO] Reading Sectors...",13 ,10 ,0
MSG_SUCCESS_DISK: db "[SUCCESS] Loading Disk Into Memory Succeded !", 13 ,10 ,0

times 510-($-$$) db 0
dw 0xaa55
times 512 db 0


Top
 Profile  
 
 Post subject: Re: Bootloaderis not consistent when booting in real hardwar
PostPosted: Mon Jun 14, 2021 8:53 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
liwinux wrote:
I don't know why it works now.. Can someone explain it to me ?

It's hard to say for sure without being able to run dozens of tests. Maybe you finally got a valid partition table. Maybe something about the far JMP instruction you added convinces your firmware that it doesn't need to "fix" the BPB anymore. Maybe your 4.5kiB stack is finally big enough. (Some uncommon BIOS calls still need a bigger stack!)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 36 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 48 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group