Real Mode Bootloader Problems

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
dragonfire353
Posts: 13
Joined: Tue Oct 01, 2013 11:45 pm

Real Mode Bootloader Problems

Post by dragonfire353 »

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.
dragonfire353
Posts: 13
Joined: Tue Oct 01, 2013 11:45 pm

Re: Real Mode Bootloader Problems

Post by dragonfire353 »

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 :roll:

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
dragonfire353
Posts: 13
Joined: Tue Oct 01, 2013 11:45 pm

Re: Real Mode Bootloader Problems

Post by dragonfire353 »

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...
Attachments
boot.asm
(15.01 KiB) Downloaded 109 times
Octocontrabass
Member
Member
Posts: 5604
Joined: Mon Mar 25, 2013 7:01 pm

Re: Real Mode Bootloader Problems

Post by Octocontrabass »

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.
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: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.....
The partition list goes at the end of the MBR. The BPB and EBPB are part of the VBR.

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.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Real Mode Bootloader Problems

Post by egos »

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.
If you have seen bad English in my words, tell me what's wrong, please.
dragonfire353
Posts: 13
Joined: Tue Oct 01, 2013 11:45 pm

Re: Real Mode Bootloader Problems

Post by dragonfire353 »

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 :D lol
Attachments
boot.asm
(17.07 KiB) Downloaded 58 times
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Real Mode Bootloader Problems

Post by egos »

No, your "jmp start" isn't short jump because "start" is too far. Here is short jump:

Code: Select all

  jmp short @f
  nop
  rb BS_SIZE-3
@@:
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

@@:
        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
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.
If you have seen bad English in my words, tell me what's wrong, please.
dragonfire353
Posts: 13
Joined: Tue Oct 01, 2013 11:45 pm

Re: Real Mode Bootloader Problems

Post by dragonfire353 »

egos wrote:No, your "jmp start" isn't short jump because "start" is too far. Here is short jump:

Code: Select all

  jmp short @f
  nop
  rb BS_SIZE-3
@@:
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

@@:
        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
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.

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
That we start reading from sector 2? Is this not correct?

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
does not work for some reason, I even tried printing out what dl equals after the call to get the cursor position and it prints out 8 0's indicating that the bios returns a 0 to dl when the cursor is not at the beginning column position...

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
Is there something obviously wrong with the way I'm doing things?


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.
Octocontrabass
Member
Member
Posts: 5604
Joined: Mon Mar 25, 2013 7:01 pm

Re: Real Mode Bootloader Problems

Post by Octocontrabass »

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.
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:

Code: Select all

		stc
		cmp ebx, 0
Is there something obviously wrong with the way I'm doing things?
Yes. Your function always returns with carry clear because "cmp ebx, 0" will clear carry when ebx equals 0.
dragonfire353
Posts: 13
Joined: Tue Oct 01, 2013 11:45 pm

Re: Real Mode Bootloader Problems

Post by dragonfire353 »

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:

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
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:

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
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?
Attachments
boot.asm
(18.57 KiB) Downloaded 84 times
Octocontrabass
Member
Member
Posts: 5604
Joined: Mon Mar 25, 2013 7:01 pm

Re: Real Mode Bootloader Problems

Post by Octocontrabass »

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?
Teletype always moves the cursor for you; regular printing does not.
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?
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: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.
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:

Code: Select all

db "CPU Signature: ",0
db "Feature flags:",0
db " APIC",0
db " CMOV",0
db " MMX",0
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?
You're confusing the MBR (Master Boot Record) with the VBR (Volume/partition Boot Record).

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.
dragonfire353
Posts: 13
Joined: Tue Oct 01, 2013 11:45 pm

Re: Real Mode Bootloader Problems

Post by dragonfire353 »

Octocontrabass wrote:
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?
Teletype always moves the cursor for you; regular printing does not.
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?
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: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.
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:

Code: Select all

db "CPU Signature: ",0
db "Feature flags:",0
db " APIC",0
db " CMOV",0
db " MMX",0
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?
You're confusing the MBR (Master Boot Record) with the VBR (Volume/partition Boot Record).

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:
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
Could u help clarify what's going on then?

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 :twisted:
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Real Mode Bootloader Problems

Post by egos »

dragonfire353 wrote:Is 255/265.9 MB the min fat32 size?
Actually the min FAT32 size (in 512-byte sectors) is 32 (typically) + (((2+65525)*4+511)/512)*FATs + 65525*SectorsPerCluster.
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
That we start reading from sector 2? Is this not correct?
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.
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.
In my boot loaders I put cursor at the end of last dispayed string. For example:

Code: Select all

        call putstr
        nb 13,10,"Disk error",0
...
        call putstr
        nb ".",13,10,"Press Ctrl-Alt-Del to restart...",32,128
Could you help clarify what's going on then?
You can have two different formats on the flash drive:
- 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.
Post Reply