Page 1 of 2
Making bootsector for USB pen
Posted: Sat Jun 21, 2008 8:26 am
by Revelation
Hi,
Most of the tutorials concerning boot sectors I find online are intended for floppies. But I think we are long past the floppy era, and my computer, lacking a floppy drive of course, silently confirms this.
What I am trying to do now is create a small OS on a USB memory stick. The boot loader I am using now is a copy of
this one. The problem I have is converting the FAT12 header for a floppy to a decent header for a 1.1 GB memory pen. If I use the original boot loader, my memory stick size is reduced to 1.44 mb, which is very inconvenient.
OEM_ID db "QUASI-OS"
BytesPerSector dw 0x0200
SectorsPerCluster db 0x01
ReservedSectors dw 0x0001
TotalFATs db 0x02
MaxRootEntries dw 0x00E0
TotalSectorsSmall dw 0x0B40
MediaDescriptor db 0xF0
SectorsPerFAT dw 0x0009
SectorsPerTrack dw 0x0012
NumHeads dw 0x0002
HiddenSectors dd 0x00000000
TotalSectorsLarge dd 0x00000000
DriveNumber db 0x00
Flags db 0x00
Signature db 0x29
VolumeID dd 0xFFFFFFFF
VolumeLabel db "QUASI BOOT"
SystemID db "FAT12 "
Who can help me?
Re: Making bootsector for USB pen
Posted: Sat Jun 21, 2008 8:32 am
by mutex
Dont get stuck with the bootloading stuff. Use grub on it. Very easy to install and very powerfull. If you need to load a 1.44mb image grub can do this for you easily.
My recomendation would be to focus on the kernel and setting up a runnable environment. Use multiboot for loading your kernel with grub.. If you need help there are a lot of info in grub-manual with actual sourcecode for having a c-kernel loaded...
-
Thomas
Re: Making bootsector for USB pen
Posted: Sat Jun 21, 2008 9:32 am
by suthers
I disagree, writing a bootloader is a very good exercise, that often teaches people a lot of good lessons before they start coding their kernel.
For example, I learned how to code in assembly when I wrote my bootloader (before I only knew the basics...).
Sorry, I can't help you, I've never written a bootloader for a flash drive..., but I think it's a good exercise so don't quit (though I know loads of people are going to disagree with me...)
Jules
Re: Making bootsector for USB pen
Posted: Sat Jun 21, 2008 10:50 am
by Dex
I would say the answer to your ?, could be Fat16, it works the same as fat12, but bigger.
I would get "bootprog" see here:
http://alexfru.chat.ru/epm.html#bootprog
It come with a fat12 and a fat16 loader, plus a program that will take the BPB info etc from the origanal BPB and jump over it to load the boot loader.
You will need to format the fob fat16, than mode your load as per the examples in the bootprog zip.
Re: Making bootsector for USB pen
Posted: Sat Jun 21, 2008 11:37 am
by Combuster
There is no real difference between an USB drive and a Floppy drive working different - it's just what's on them. Floppies are usually FAT12, but most other FSes will work as well. An USB drive is larger, and hence doesn't use FAT12 because it can't handle the disk size (with the normal block size, 2¹² * 1024 = 4MB max, can be larger) thus it uses something different - which is in most cases either FAT16 (which with 4096b sectors can go up to 256MB, more with larger sectors) or FAT32 (anything into the TBs) The way the bios boots your USB drive is the same as it does for regular floppies or harddisks
Once you know what FS is actually on your drive, the only thing left is to change the FS-dependent code and everything should work. Or you could, as dex said, force the filesystem of your choice and be done without different pieces of code
Note that CDs are bound by specific standards, and are therefore booted differently on PCs by convention. In that respect some other non-PC architectures make even that easy

Re: Making bootsector for USB pen
Posted: Sat Jun 21, 2008 12:00 pm
by Revelation
I already tried GRUB before, but I failed to do so somehow. I already have grub for my Vista - Ubuntu dual boot, and I figured I could just add the memory stick to the list (menu.lst), but I was wrong.
I also looked at the boot16.asm file, which had question marks behind almost every variable, like TotalSectorsLarge. Ignoring that, I DDd it to my stick, but it rendered it unmountable. Thus, that file doesn't work unfortunately. Why does there have to be such information in the bootsector anyway, when without one the format can just be read?
Can I strip the information from my USB drive?
Re: Making bootsector for USB pen
Posted: Sat Jun 21, 2008 12:24 pm
by Combuster
That file had question marks for a reason - it doesn't yet know what the size of the drive is. Yet you put it on the drive, overwriting exactly that info it needed. (Which is also what the OS needs to read it, rendering the device unusable).
Use a tool that can put a bootsector in place when formatting the drive. When it does so, it copies the bootsector over, then overwrite those parts that are needed to access the file system. The bootloader is written such that it reserves those areas for data, so when the formatting tool has put everything in place, the blank areas are filled in with the properties of the filesystem - for you and the OS to read.
Much more humane than DDing bits of code over and hoping you got everything right

Re: Making bootsector for USB pen
Posted: Sat Jun 21, 2008 2:21 pm
by JJeronimo
Never done that before, but my hints would be:
- First of all, there's a little problem about pens: some
pens have a MBR and partitions; some pens just have
a filesystem stored is it, from byte 0 on. For this, the
boot sector still needs to take into account the "offset"
of the filesystem, which the chinloader (possible the
MBR boot code) is supposed to have passed to it.
- Blindly assume the BIOS supports LBA. I think this is
reasonable for pens...
- As is usually done for FAT boot sectors, write a version
for FAT16 and another one for FAT32. I think it's
somewhat useless to write one for supporting FAT 12.
Besides pretty limited in max volume size, the table is
also complicated to parse (not that you couldn't write
code for that, but it's not worth the effort!).
- There's another little point here: I think existing FAT
boot sectors for hard disk partitions can do the job, so
take this into account too.
As about the header, you do not want to tie your code to
the data you declare in your header. That's because your
boot sector is supposed to be *installed* in the file system
image, so it has to take into account the real values of the
file system that is being booted...
Hope this helps.
JJ
Re: Making bootsector for USB pen
Posted: Sun Jun 22, 2008 5:15 am
by Revelation
Thank you all
I've written some code (inspired by
this) that reads the boot sector from any disk. If I'm not mistaking, it supports every FAT. Now I can write a boot code installer.
Code: Select all
// This application reads FAT boot sectors from any drive and prints the results to the screen.
// Compatible with FAT, FAT12 and FAT16. Not compatible with FAT32 yet.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// this struct contains the whole 512 bytes of the boot sector
typedef struct BPB
{
unsigned char jumpCode[3];
unsigned char oemName[8];
unsigned short bytes_Sector;
unsigned char sec_Cluster;
unsigned short size_Sector_Reserved;
unsigned char fatCount;
unsigned short Max_Root_Entry;
unsigned short Total_Sector_FS;
unsigned char Media_Type;
unsigned short sectors_per_fat;
unsigned short sectors_per_track;
unsigned short total_Head_Count;
unsigned long no_Sectors_Before_Part;
unsigned long no_Sector_FS32;
unsigned char BIOS_13h_Drive_No;
unsigned char reserved;
unsigned char ext_Boot_Part_Signature;
unsigned long vol_Serial_Number;
unsigned char vol_Label_Name[11];
unsigned char FS_Type[8];
unsigned char boot_Code[448];
unsigned short signature;
} __attribute__((__packed__)) BPB;
void printbpb(BPB bpb)
{
printf("Disk Information: \n");
printf("===========================\n");
printf("Assembly Instruction to jump to Boot code: 0x%x\n",
bpb.jumpCode);
printf("OEM Name: \"%.8s\"\n", bpb.oemName); // this string may not be zero terminated!
printf("Bytes per sector: %d\n", bpb.bytes_Sector);
printf("Sector per cluster: %d\n", bpb.sec_Cluster);
printf("Size in sector for reserved area(Boot Sector): %d\n", bpb.size_Sector_Reserved);
printf("Number of FATs(File Allocation Table): %d\n", bpb.fatCount);
printf("Number of files for root directory: %d\n", bpb.Max_Root_Entry);
printf("Number of Sectors in File System: %d\n", bpb.Total_Sector_FS);
printf("Media Type: 0x%x\n", bpb.Media_Type);
printf("Number of Sectors for each FAT: %d\n", bpb.sectors_per_fat);
printf("Sectors per track: %d\n", bpb.sectors_per_track);
printf("Number of head in storage device: %d\n", bpb.total_Head_Count);
printf("BIOS INT13h Drive number: 0x%x\n", bpb.BIOS_13h_Drive_No);
printf("Number of large sectors: 0x%x\n", bpb.no_Sector_FS32);
printf("Volume Serial Number: %d\n", bpb.vol_Serial_Number);
printf("Volume label Name: \"%.11s\"\n", bpb.vol_Label_Name); // this string may not be zero terminated!
printf("File system type: \"%.8s\"\n", bpb.FS_Type); // this string may not be zero terminated!
printf("Boot Sector Signature: 0x%x\n", bpb.signature);
}
int main(int argc, char** argv)
{
FILE* drivefile;
char bootsector[512];
BPB bpb;
if (argc < 2)
{
printf("The following error occurred: Application needs disk location.\n");
return 1;
}
const char* drivename = argv[1]; // /dev/sdf1 on UNIX for example; A: on WINDOWS
drivefile = fopen(drivename, "rb"); // force binary, for WINDOWS
if (!drivefile)
{
perror ("The following error occurred");
return 2;
}
// clear buffer
memset(bootsector, 0, 512);
// read bootsector
fread(bootsector, 512, 1, drivefile);
memcpy(&bpb, bootsector, 512);
printbpb(bpb);
fclose(drivefile);
return 0;
}
I hope other people find this code useful
edit: there are still some errors in the code.. trying to fix them.
edit: I see there is no support for FAT32...
Re: Making bootsector for USB pen
Posted: Sun Jun 22, 2008 5:40 am
by JJeronimo
Revelation wrote:Thank you all

Not at all.
I've written some code (inspired by
this) that reads the boot sector from any disk. If I'm not mistaking, it supports every FAT. Now I can write a boot code installer.
I forgot to give you a pointer that might be useful, which is the FAT Spec from Microsoft itself:
http://www.nondot.org/sabre/os/files/Fi ... Format.pdf
JJ
Re: Making bootsector for USB pen
Posted: Sun Jun 22, 2008 5:58 am
by Revelation
Thanks JJernimo!
I am still checking my code, because I know it gives wrong results. bytes_Sector for example should be 512 and my app returns 8194. Really weird, because the value of the variable above it is correct.
Re: Making bootsector for USB pen
Posted: Sun Jun 22, 2008 7:23 am
by Korona
I don't know if that causes any problem in this case but generally structures that the compiler must not align or reorganize should be marked with __attribute((__packed__)).
Re: Making bootsector for USB pen
Posted: Sun Jun 22, 2008 8:34 am
by Revelation
You hit the nail on the head

I've adapted the source posted above.
Re: Making bootsector for USB pen
Posted: Sun Jun 22, 2008 9:10 am
by JJeronimo
Korona wrote:I don't know if that causes any problem in this case but generally structures that the compiler must not align or reorganize should be marked with __attribute((__packed__)).
I was to suggest this, but forgot...
JJ
Re: Making bootsector for USB pen
Posted: Sun Jun 22, 2008 11:19 am
by kmcguire
Korona wrote:I don't know if that causes any problem in this case but generally structures that the compiler must not align or reorganize should be marked with __attribute((__packed__)).
Structures that have member fields that you do not want padded to maintain alignment on word boundaries need to use the
__attribute__((__packed__)) expression. The C compiler should never reorganize the members of a structure! The padding increases the performance of data access (if you have ever noticed inside the manuals for a processor's instruction set it will hint to performance decreases on unaligned memory accesses for some stuff).
The alignment of the structure it's self comes from it's creation. Such that if you create the structure as a local variable then it is automatically aligned by the stack's word size. While, if you create the structure using a pointer, then the structure may or may not be aligned no matter if you used the __packed__ attribute or not.