Real Mode Bootloader Problems
-
- Posts: 13
- Joined: Tue Oct 01, 2013 11:45 pm
Real Mode Bootloader Problems
Hello, I'm getting frustrated and tired of researching and constantly messing with the code to fix this problem so I'd greatly appreciate it if someone could help out. I'm having some issues with printing messages in the BIOS. Before I had it split up, due to it becoming greater than 512 bytes, it worked perfectly, but now that I'm loading from the disk, using BIOS functions to load, my messages typically don't print except for one. I don't understand why this is as it's only 2 KB and you can reference up to 64KB within a single segment correct? I've tried many different things to get this to work but there's obviously something I'm doing wrong. I'm using nasm to compile it to a 2KB boot.vfd and running it in vbox and qemu, and I get the same result in either one. I've uploaded the boot.asm source. Sorry I can't narrow it down but I have no idea where the problem lies. Thank you for your help fellow dever....
- Attachments
-
- boot.asm
- bootloader source
- (8.28 KiB) Downloaded 68 times
Last edited by dragonfire353 on Wed Oct 16, 2013 9:08 pm, edited 1 time in total.
-
- Posts: 13
- Joined: Tue Oct 01, 2013 11:45 pm
Re: Real Mode Bootloader Problems
Alright, so I figured out the problem lol, as I tend to do right after I spend days trying to fix it then finally post about it.....
I had defined cursor position as only one byte, rather than a word which is what dx is. Stupid mistake per usual on my part
Although it still acts a bit funky, so if anyone cares to compile and run this updated source, or if anyone's learning like me and wouldn't mind looking at some slightly messed up code to reference from lol, go ahead.
I had defined cursor position as only one byte, rather than a word which is what dx is. Stupid mistake per usual on my part
Although it still acts a bit funky, so if anyone cares to compile and run this updated source, or if anyone's learning like me and wouldn't mind looking at some slightly messed up code to reference from lol, go ahead.
- Attachments
-
- boot.asm
- Updated bootloader source
- (8.3 KiB) Downloaded 73 times
-
- Posts: 13
- Joined: Tue Oct 01, 2013 11:45 pm
Re: Real Mode Bootloader Problems
Ok, more problems.... so I'm having an issue with the cursor going down on consecutive calls to print string, i'm trying to get the cursor to only go down after the first call to print_string using the get cursor position function of the BIOS. I've even tried using a local boolean variable but that didn't even work. I'm using test dl, dl and je. I've tried cmp dl, 0 and je but that doesn't work either.
Also trying to figure out page map level 4 and paging in general for 64bit mode. Reading the intel documentation. I basically just copied the code from the wiki here: http://wiki.osdev.org/Entering_Long_Mode_Directly and I'm trying to fully understand it so I can modify it to my what I want.
Oh, and also trying to hard code fat32 partition for virtualbox for now till I understand it enough to write an installer from usb. I have the BPB and EBPB I believe but not the partition listings at the end of the 512 bytes if anyone has any hints.....
I've googled quite a bit, currently on bad internet so I'm fed up with it lol if anyone can help please..
If anyone has any insight to any of these please reply....
I've uploaded what I have so far on the bootloader
Thank you...
Also trying to figure out page map level 4 and paging in general for 64bit mode. Reading the intel documentation. I basically just copied the code from the wiki here: http://wiki.osdev.org/Entering_Long_Mode_Directly and I'm trying to fully understand it so I can modify it to my what I want.
Oh, and also trying to hard code fat32 partition for virtualbox for now till I understand it enough to write an installer from usb. I have the BPB and EBPB I believe but not the partition listings at the end of the 512 bytes if anyone has any hints.....
I've googled quite a bit, currently on bad internet so I'm fed up with it lol if anyone can help please..
If anyone has any insight to any of these please reply....
I've uploaded what I have so far on the bootloader
Thank you...
- Attachments
-
- boot.asm
- (15.01 KiB) Downloaded 110 times
-
- Member
- Posts: 5604
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Real Mode Bootloader Problems
Why not use the teletype function to print text? It handles the cursor automatically for you. When you want the cursor to go down, print a CR+LF pair.dragonfire353 wrote:Ok, more problems.... so I'm having an issue with the cursor going down on consecutive calls to print string, i'm trying to get the cursor to only go down after the first call to print_string using the get cursor position function of the BIOS. I've even tried using a local boolean variable but that didn't even work. I'm using test dl, dl and je. I've tried cmp dl, 0 and je but that doesn't work either.
The partition list goes at the end of the MBR. The BPB and EBPB are part of the VBR.dragonfire353 wrote:Oh, and also trying to hard code fat32 partition for virtualbox for now till I understand it enough to write an installer from usb. I have the BPB and EBPB I believe but not the partition listings at the end of the 512 bytes if anyone has any hints.....
Speaking of BPB, yours is invalid. The long jump at the start of your code is five bytes, but there are only three bytes of free space before the start of the BPB.
Re: Real Mode Bootloader Problems
dragonfire353,
some notes about FAT32 BPB+ structure:
- first 3 bytes must be short jump and nop or "near" 16-bit jump;
- TotalSectors16 field must be 0;
- you forget to add TotalSectors32 field at all;
- you can use HiddenSectors field to get starting sector of primary partition (I assume that you use MBR partitioning scheme), don't try to read MBR for that; advanced MBR boot loaders can provide this info for you as well;
- leave sector 1 unused (perhaps, split stage 1 and stage 2 into different files), or move FSInfo to other place;
- you can use DriveNumber field to save corresponding value, or you can save it somewhere outside the image in memory.
Usually stage 2 is contained in a file, not in boot record. Try to use RAW partition format, or leave important FS data untouched during installation.
some notes about FAT32 BPB+ structure:
- first 3 bytes must be short jump and nop or "near" 16-bit jump;
- TotalSectors16 field must be 0;
- you forget to add TotalSectors32 field at all;
- you can use HiddenSectors field to get starting sector of primary partition (I assume that you use MBR partitioning scheme), don't try to read MBR for that; advanced MBR boot loaders can provide this info for you as well;
- leave sector 1 unused (perhaps, split stage 1 and stage 2 into different files), or move FSInfo to other place;
- you can use DriveNumber field to save corresponding value, or you can save it somewhere outside the image in memory.
Usually stage 2 is contained in a file, not in boot record. Try to use RAW partition format, or leave important FS data untouched during installation.
If you have seen bad English in my words, tell me what's wrong, please.
-
- Posts: 13
- Joined: Tue Oct 01, 2013 11:45 pm
Re: Real Mode Bootloader Problems
Ok, I took your guys corrections and fixed up the structures and moved stuff around, I believe the structures are correct at this point, reading the fat wiki was confusing at first... don't have the other problems fixed. Print screen move cursor down problem and the function that's supposed to tell if the memory detection function's finished yet. But i have the screen and text a different color lol
- Attachments
-
- boot.asm
- (17.07 KiB) Downloaded 58 times
Re: Real Mode Bootloader Problems
No, your "jmp start" isn't short jump because "start" is too far. Here is short jump:
When you use "teletype function" in stage 1 you can forget about other video functions (including function 0). Here is one of my putstr modifications:
Use CR-LF (13, 10) to move cursor to the beginning of the next line.
Now you should read sector 2 (c:h:s=0:0:3), not 1 (c:h:s=0:0:2). Moreover if your image is in partition you should add its starting sector number to 2 and convert result to CHS before reading, or use "extended read" function. You can use some foreign first stage boot loaders, e.g. Yoda's fat32/"rawfs" stage 1.
Code: Select all
jmp short @f
nop
rb BS_SIZE-3
@@:
Code: Select all
@@:
mov bx,7
mov ah,0Eh
push si
int 10h
pop si
putstr:
mov al,[si]
inc si
and al,al
jg short @b
ret
Now you should read sector 2 (c:h:s=0:0:3), not 1 (c:h:s=0:0:2). Moreover if your image is in partition you should add its starting sector number to 2 and convert result to CHS before reading, or use "extended read" function. You can use some foreign first stage boot loaders, e.g. Yoda's fat32/"rawfs" stage 1.
If you have seen bad English in my words, tell me what's wrong, please.
-
- Posts: 13
- Joined: Tue Oct 01, 2013 11:45 pm
Re: Real Mode Bootloader Problems
egos wrote:No, your "jmp start" isn't short jump because "start" is too far. Here is short jump:When you use "teletype function" in stage 1 you can forget about other video functions (including function 0). Here is one of my putstr modifications:Code: Select all
jmp short @f nop rb BS_SIZE-3 @@:
Use CR-LF (13, 10) to move cursor to the beginning of the next line.Code: Select all
@@: mov bx,7 mov ah,0Eh push si int 10h pop si putstr: mov al,[si] inc si and al,al jg short @b ret
Now you should read sector 2 (c:h:s=0:0:3), not 1 (c:h:s=0:0:2). Moreover if your image is in partition you should add its starting sector number to 2 and convert result to CHS before reading, or use "extended read" function. You can use some foreign first stage boot loaders, e.g. Yoda's fat32/"rawfs" stage 1.
Thank you! I fixed the short jump not being short jump... windows and mac recognizes my structures now!
Although windows says it's 255MB, and mac says 265.9MB, guessing it's all the different ways a "MB" can be calculated.... though I thought I set it to 32MiB unless I did my math wrong for BigNumberOfSectors? 2000000h = 33554432 bytes = 32MiB? Is 255/265.9 MB(D&F*^G@ the min fat32 size?
I'm confused what you mean by I should be reading from sector 2? I have here:
Code: Select all
mov ah, 02h ; code for the read disk command
mov al, 3 ; how many sectors to read?
mov ch, 0 ; which cylnder?
mov cl, 2 ; which sector do we start reading from?
mov dh, 0 ; which head?
mov bx, 7E00h ; es:bx where we loading this stuff? in this case, we're loading directly after the first 512 bytes that were loaded by the BIOS, so we get the rest of the bootloader
int 13h ; BIOS disk operation interrupt
Also about your suggestion for using teletype... the problem I'm having is determining when I should move the cursor down, not how to. The code here:
Code: Select all
push si ; the BIOS call(s) may destroy the si register
call get_cursor_position
test dl, dl ; is dl (column) 0? If not we should move the cursor down
je .pre_repeat
call move_cursor_down
...
get_cursor_position:
xor bh, bh
mov ah, 3
int 10h
ret
Reason I'm trying to do this complicatedly is so that it only moves the cursor down if it's not at the first column, meaning it's at the end of an already printed string simply because I don't want the cursor blinking below the last printed line, OCD much? But it's more frustrating that I can't get this seemingly simple thing to work.
The more important matter is with my bios memory detection routine never ending which I'm guessing has something to do with the following code:
Code: Select all
; returns with carry set if finished
.is_finished:
jc conditional_return ; carry set means "end of list already reached"
stc
cmp ebx, 0 ; ebx 0 means that we've reached the end of the list
je conditional_return
clc
ret
...
conditional_return:
ret ; this is used since there is no "return if equal/ne" instruction
I refuse to use any other code because I'm stubborn like that lol, want everything "from scratch"
Sorry for the really long post and thanks in advance for any help...
- Attachments
-
- boot.asm
- (18 KiB) Downloaded 45 times
Last edited by dragonfire353 on Wed Oct 16, 2013 9:07 pm, edited 1 time in total.
-
- Member
- Posts: 5604
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Real Mode Bootloader Problems
Never. You never have to move the cursor. The teletype function automatically moves the cursor (and, when you run out of room, scrolls the screen).dragonfire353 wrote:Also about your suggestion for using teletype... the problem I'm having is determining when I should move the cursor down, not how to.
Yes. Your function always returns with carry clear because "cmp ebx, 0" will clear carry when ebx equals 0.dragonfire353 wrote:Is there something obviously wrong with the way I'm doing things?Code: Select all
stc cmp ebx, 0
-
- Posts: 13
- Joined: Tue Oct 01, 2013 11:45 pm
Re: Real Mode Bootloader Problems
wow thank you! again simple error... really bad about those, clearly, lol
Ok, so teletype automatically moves the cursor for me when the end of the screen is reached, so does regular printing, from my experience so far, does it not?
I want to move the cursor down before reaching the end of the screen, after each line, so I need to manually call it, or print CR+LF if using teletype?
Sorry if I'm not being clear, I'm trying to tell on each call to the print_string function, if the cursor is not in the far left most column, column 0, and if it is not, then I should move the cursor down; because that means something was already printed on that line, and I don't want to print something else on that line or I should print a space before printing the next string.
Thank you for the help so far!
You guys have been most helpful while my internet is incapacitated...
I have added partition mappings following this site:
http://www.pjrc.com/tech/8051/ide/fat32.html
and:
http://home.teleport.com/~brainy/fat32.htm
this is what I came up with:
After adding this my mac doesn't recognize it anymore, is it because I didn't enter valid chs data? I read a bit about it on one of those sites and it seemed they made it very complicated in order to support modern operating system disk sizes so I just put 0 for chs data. Is it because of this or because I haven't added a "first sector" information structure to this partition area yet? I just thought of that actually so going to try it now...
EDIT:
tried it:
Mac still doesn't recognize it, how come it worked when there were no partition tables? Do you not need partition tables if there's only one partition?
Ok, so teletype automatically moves the cursor for me when the end of the screen is reached, so does regular printing, from my experience so far, does it not?
I want to move the cursor down before reaching the end of the screen, after each line, so I need to manually call it, or print CR+LF if using teletype?
Sorry if I'm not being clear, I'm trying to tell on each call to the print_string function, if the cursor is not in the far left most column, column 0, and if it is not, then I should move the cursor down; because that means something was already printed on that line, and I don't want to print something else on that line or I should print a space before printing the next string.
Thank you for the help so far!
You guys have been most helpful while my internet is incapacitated...
I have added partition mappings following this site:
http://www.pjrc.com/tech/8051/ide/fat32.html
and:
http://home.teleport.com/~brainy/fat32.htm
this is what I came up with:
Code: Select all
times 446-($-$$) db 0 ; pad till partition area
; *** BEGIN PARTITION LIST AREA ***
; FIRST PARTITION:
db 80h ; current state of partition (0 for inactive, 80h for active)
db 0 ; beginning of the partition, head
dw 0 ; chs begin, don't care
db 0Ch ; Partition type, fat32 LBA
db 0 ; end of partition, head
dw 0 ; end of partition chs, don't care
dd 7 ; number of sectors between MBR and partition, so same as reserved sectors in the BPB minus the first sector
dd 2000000h ; number of sectors in partition
; SECOND PARTITION:
db 0
db 0
dw 0
db 0
db 0
dw 0
dd 0
dd 0
; THIRD PARTITION:
db 0
db 0
dw 0
db 0
db 0
dw 0
dd 0
dd 0
; FOURTH PARTITION:
db 0
db 0
dw 0
db 0
db 0
dw 0
dd 0
dd 0
times 510-($-$$) db 0 ; Pad remainder of boot sector with 0s
dw 0xAA55 ; The standard PC boot signature
EDIT:
tried it:
Code: Select all
times 2048-($-$$) db 0 ; pad out to backup sectors
; empty backups
times 4096-($-$$) db 0 ; pad out to first partition sector
; *** BEGIN FAT32 VOLUME ID ***
dw 512 ; bytes per sector, 512 yet again...
db 64 ; sectors per cluster, 64 yet again...
dw 32 ; number of reserved sectors, usually 20h (32) i guess?
db 2 ; number of FATs, always 2 apparently?
dd 64 ; Sectors per FAT, I just set it to a single cluster
dd 2 ; root directory first cluster, second cluster?
dw 0AA55h ; signature
times 5120-($-$$) db 0
- Attachments
-
- boot.asm
- (18.57 KiB) Downloaded 84 times
-
- Member
- Posts: 5604
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Real Mode Bootloader Problems
Teletype always moves the cursor for you; regular printing does not.dragonfire353 wrote:Ok, so teletype automatically moves the cursor for me when the end of the screen is reached, so does regular printing, from my experience so far, does it not?
Printing CR+LF using teletype guarantees that the screen will scroll if you've reached the bottom, so that's what you should do.dragonfire353 wrote:I want to move the cursor down before reaching the end of the screen, after each line, so I need to manually call it, or print CR+LF if using teletype?
Several of my strings include a space at the beginning or end so that formatting will be correct for all combinations I'd want to print them in. For example:dragonfire353 wrote:Sorry if I'm not being clear, I'm trying to tell on each call to the print_string function, if the cursor is not in the far left most column, column 0, and if it is not, then I should move the cursor down; because that means something was already printed on that line, and I don't want to print something else on that line or I should print a space before printing the next string.
Code: Select all
db "CPU Signature: ",0
db "Feature flags:",0
db " APIC",0
db " CMOV",0
db " MMX",0
You're confusing the MBR (Master Boot Record) with the VBR (Volume/partition Boot Record).dragonfire353 wrote:Mac still doesn't recognize it, how come it worked when there were no partition tables? Do you not need partition tables if there's only one partition?
The MBR, if you have one, goes at the very beginning of the disk. It contains the partition table and a small amount of code to load the VBR of the active partition, or complain if there is no active partition.
The VBR is the first sector of the partition. It's where your BPB/EBPB and boot code goes.
-
- Posts: 13
- Joined: Tue Oct 01, 2013 11:45 pm
Re: Real Mode Bootloader Problems
Octocontrabass wrote:Teletype always moves the cursor for you; regular printing does not.dragonfire353 wrote:Ok, so teletype automatically moves the cursor for me when the end of the screen is reached, so does regular printing, from my experience so far, does it not?
Printing CR+LF using teletype guarantees that the screen will scroll if you've reached the bottom, so that's what you should do.dragonfire353 wrote:I want to move the cursor down before reaching the end of the screen, after each line, so I need to manually call it, or print CR+LF if using teletype?
Several of my strings include a space at the beginning or end so that formatting will be correct for all combinations I'd want to print them in. For example:dragonfire353 wrote:Sorry if I'm not being clear, I'm trying to tell on each call to the print_string function, if the cursor is not in the far left most column, column 0, and if it is not, then I should move the cursor down; because that means something was already printed on that line, and I don't want to print something else on that line or I should print a space before printing the next string.Code: Select all
db "CPU Signature: ",0 db "Feature flags:",0 db " APIC",0 db " CMOV",0 db " MMX",0
You're confusing the MBR (Master Boot Record) with the VBR (Volume/partition Boot Record).dragonfire353 wrote:Mac still doesn't recognize it, how come it worked when there were no partition tables? Do you not need partition tables if there's only one partition?
The MBR, if you have one, goes at the very beginning of the disk. It contains the partition table and a small amount of code to load the VBR of the active partition, or complain if there is no active partition.
The VBR is the first sector of the partition. It's where your BPB/EBPB and boot code goes.
Between you and the website I referenced earlier, I'm getting confused lol
particularly at this part:
Could u help clarify what's going on then?http://home.teleport.com/~brainy/fat32.htm wrote:Master Boot Record
The Master Boot Record is the same for pretty much all Operating Systems. It is located on the first Sector of the Hard Drive, at Cylinder 0, Head 0, Sector 1. It is the first piece of code that your computer runs after it has checked all of your hardware (POST) and turned control of loading software over the hard drive. It also contains the partition table, which defines the different sections of your hard drive. Basically if anything happens to this little 512 byte section, your hard drive is brain dead. Kinda scary, eh?
Offset Description Size
000h Executable Code (Boots Computer) 446 Bytes
1BEh 1st Partition Entry (See Next Table) 16 Bytes
1CEh 2nd Partition Entry 16 Bytes
1DEh 3rd Partition Entry 16 Bytes
1EEh 4th Partition Entry 16 Bytes
1FEh Boot Record Signature (55h AAh) 2 Bytes
Also, while that is one way to just get printing working correctly, and one of many ways I could just settle on an easier path, I'm too frustrated and stubborn to change the way I'm doing it now, at least while I can't get it working. So if you have any idea what's wrong with the way I'm trying to do it, because clearly I'm missing some fundamental piece of knowledge of how assembly works which could come in handy now, or later on (as I plan to do the kernel in assembly as well, at least for now) I know I'm crazy
Re: Real Mode Bootloader Problems
Actually the min FAT32 size (in 512-byte sectors) is 32 (typically) + (((2+65525)*4+511)/512)*FATs + 65525*SectorsPerCluster.dragonfire353 wrote:Is 255/265.9 MB the min fat32 size?
No, I meant sector with linear number 2, i.e. the 3rd sector (the 1st sector (0) is a boot sector, the 2nd sector (1) is a FSInfo sector). LBA 2 = CHS 0:0:3.I'm confused what you mean by I should be reading from sector 2? I have here:
That we start reading from sector 2? Is this not correct?Code: Select all
mov ah, 02h ; code for the read disk command mov al, 3 ; how many sectors to read? mov ch, 0 ; which cylnder? mov cl, 2 ; which sector do we start reading from? mov dh, 0 ; which head? mov bx, 7E00h ; es:bx where we loading this stuff? in this case, we're loading directly after the first 512 bytes that were loaded by the BIOS, so we get the rest of the bootloader int 13h ; BIOS disk operation interrupt
In my boot loaders I put cursor at the end of last dispayed string. For example:Reason I'm trying to do this complicatedly is so that it only moves the cursor down if it's not at the first column, meaning it's at the end of an already printed string simply because I don't want the cursor blinking below the last printed line, OCD much? But it's more frustrating that I can't get this seemingly simple thing to work.
Code: Select all
call putstr
nb 13,10,"Disk error",0
...
call putstr
nb ".",13,10,"Press Ctrl-Alt-Del to restart...",32,128
You can have two different formats on the flash drive:Could you help clarify what's going on then?
- superfloppy (when FAT volume space starts from 1st physical sector);
- MBR partitioning scheme (when MBR occupies 1st phisical sector, then usually some gap goes, and then 1st partition goes). It's typical for flash drives. In this case you can put your code into MBR and unused gap, or into VBR.
So first of all you should check what you have.
If you have seen bad English in my words, tell me what's wrong, please.