Assembly hard drive bootloader

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
Elja98
Posts: 15
Joined: Fri Aug 16, 2013 1:38 pm

Assembly hard drive bootloader

Post by Elja98 »

Hi,

I'm creating a boot loader for a hard drive but I'm stuck. I decided that I wanted to use FAT32 because it works with harddrives. NTFS is
documented rather bad so that's not an option. How do you load the root dir and FAT to load files? And how do you load a sector? I hope someone can help!

Thanks in advance





Edit: Just found out there's no Root dir in FAT32
azblue
Member
Member
Posts: 147
Joined: Sat Feb 27, 2010 8:55 pm

Re: Assembly hard drive bootloader

Post by azblue »

The Fat32 BPB (http://en.wikipedia.org/wiki/File_Allocation_Table#BPB) has an entry which specifies where the RDE starts; unlike Fat12/16, it is not, as you figured out, in a fixed location with a fixed size. Instead, it starts at a specific cluster and you use the FAT entries to figure out where the rest of the cluster chain is.

Your boot sector starts at "Hidden Sectors"
Your FAT Starts at "Hidden Sectors + Reserved Sectors"
And then your first cluster (#2) starts at "Hidden Sectors + Reserved Sectors + SectorsPerFAT*Number of FATs"

You'll want to become familiar with Ralf Brown's Interrupt list (http://www.ctyme.com/rbrown.htm) for using the BIOS while you're still in real mode.

To read a sector you can use Int 13h function 2. I'll leave you to find out how to use LBA and how to find out if the disk and BIOS support LBA.
Elja98
Posts: 15
Joined: Fri Aug 16, 2013 1:38 pm

Re: Assembly hard drive bootloader

Post by Elja98 »

Already thanks for the answers. I now managed to create a boot loader that should load one cluster and execute it.

Code: Select all

;calculate DataSector
mov al, BYTE [NumberOfFATs]
mul WORD [SectorsPerFAT32]
add ax, WORD [ReservedSectors]
mov WORD [data], ax

;Load first data cluster
mov ax, WORD [RootDirStart]
call LBA
mov bx, 0x0200
call ReadSector

;Skip first 32 bytes
mov di, 0x0200 + 0x20

;Get first cluster of file (Offset 0x1A
mov dx, WORD [di + 0x001A]
mov WORD [cluster], dx

mov bx, 0050h
mov es, bx
mov bx, 0

mov cx, 8
mov ax, WORD [cluster]
call LBA
call ReadSectors

push WORD 100h
push WORD 0
retf
Now my question, How should I load the next cluster? And does it matter if I change the cluster size from 8 to something like 1, 2, 4, 8, 16, 32 or 64?

Again, Thanks in advance
Last edited by Elja98 on Sun Nov 03, 2013 11:34 am, edited 2 times in total.
azblue
Member
Member
Posts: 147
Joined: Sat Feb 27, 2010 8:55 pm

Re: Assembly hard drive bootloader

Post by azblue »

Elja98 wrote:Already thanks for the answers. I now managed to create a boot loader that should load one cluster and execute it.

Code: Select all

;calculate DataSector
mov al, BYTE [NumberOfFATs]
mul WORD [SectorsPerFAT32]
add ax, WORD [ReservedSectors]
mov WORD [data], ax

;Load first data cluster
mov ax, WORD [RootDirStart]
call LBA
mov bx, 0x0200
call ReadSector

;Skip first 32 bytes
mov di, 0x0200 + 0x20

;Get first cluster of file (Offset 0x1A
mov dx, WORD [di + 0x001A]
mov WORD [cluster], dx

mov bx, 100h
mov es, ax
mov bx, 0

mov cx, 8
mov ax, WORD [cluster]
call LBA
call ReadSectors

push WORD 100h
push WORD 0
retf
Now my question, How should I load the next cluster? And does it matter if I change the cluster size from 8 to something like 1, 2, 4, 8, 16, 32 or 64?

Again, Thanks in advance
Did you read the document Hobbes posted? It tells you how to find the next cluster.

Reading any cluster size will work, but you should write your code with multiple sizes in mind -- don't hard code 8 in there.

There are quite a few problems with your code. You said you were using fat32, but you only get the lower 16 bits of the cluster, and that's not the only case where you grab 16 bits when you need 32.

I don't know why you load 100h into bx before loading 0 into it.

Your code appears to load at 0x0000:0x0100 in real mode -- I'll let you figure out what's wrong with that.

Although you can name your functions whatever you want, clear names help with writing, debugging, etc. I would expect functions like LBA and ReadSectors to be agnostic about the filesystem and to only read raw sectors from either a physical drive or a partition. Your code looks like it reads clusters.

Your code doesn't actually search for a file; you have it hard coded to load the 2nd entry in the RDE; it would be better and more flexible to actually search through the RDE.
Elja98
Posts: 15
Joined: Fri Aug 16, 2013 1:38 pm

Re: Assembly hard drive bootloader

Post by Elja98 »

Hi azblue,

I meant to type this:

Code: Select all

mov bx, 100h
mov es, bx
mov bx, 0
I'm now working on searching a file. The root dir starts at sector 2 in the data area right? and it points to the file cluster at offset 0x1A At which offset does it point to the next root entry?

I also got what's wrong with 0000h:0100h, I changed it to 0050h:0000h.
Post Reply