Bootloading from SD card

I want to enable my device to replace the contents of flash by reading in a binary file from the SD card. The catch is that I don't want to implement FAT in my bootloader. I want it to be as small in size and as simple as can be.

The vast majority of the users will be running windows. The binary file (representing the new flash contents) does not have to be placed on the SD card by conventional methods (dragging the downloaded file from hard disk to SD in explorer). I can force the user to place the file onto the SD card using the application used to configure the device. Another constraint is that the SD card format (FAT) must be left alone as the user needs to read and write files that the device has generated. So, how can I write this file to the SD card from a windows based machine such that my device can read the firmware without knowing anything of FAT (yet FAT is still present on the card)?

Hopefully the problem makes sense... :)

--------------------------------------- This message was sent using the comp.arch.embedded web interface on

formatting link

Reply to
eeboy
Loading thread data ...

a

an

D

rd

d

nt

/

formatting link

you need to use my NoFAT(TM) method

1) format SD 2) place a file with 4MByte HEADER + payload to the card 3) in embedded system a) read 1 sector at 4MB abs offset, check header calc offset to payload b) read payload

header should include signature and "counter" that gives offset to payload

this method has been used in many systems already

Antti

Reply to
Antti

AFAIK a FAT filesystem is pretty lightweight; make it so it only understands a single file with a specific name and size and it should be even lighter weight yet (I think this is what Antti was getting at).

That'll leave it compatible with Windows, and may be good enough for what you want.

I suggest you build something into your system that makes the file in the SD card unique to your board -- a filename, a checksum method, something. You don't want to burn the right code for the wrong product into your board!

--
www.wescottdesign.com
Reply to
Tim Wescott

A simple way is to modify the boot sector (Cluster 0) on teh MMC/SD card to create a larger RESEVERED AREA.

See link for details:

formatting link

The RESEVERED AREA area is always at the beginning of the "disk area" and is just consecutive sectors.

FAT understands this RESEVERED AREA and will just jump over it. This area is also hidden from FAT users.

don

Reply to
don

Huh? Isn't it how all operating systems are booting?

  1. Create a contigious file on FAT (attributes "system", "unmovable")
  2. Put your data into this file.
  3. Read this file not as a file, but as a sequence of sectors.

The bootloader only has to know what sector is the beginning of the file. If you don't want to parse directories, put the reference to the starting sector into boot sector.

Vladimir Vassilevsky DSP and Mixed Signal Design Consultant

formatting link

Reply to
Vladimir Vassilevsky

Along the same lines, you can create two partitions on the memory card: one is FAT and the other one is your own personal space. Set the partition ID byte to something that Windows doesn't recognize and it will completely ignore your partition and will never attempt to read or wite to it. Your bootloader only needs to know how to read a partition table, which is fairly trivial.

Reply to
Tom

g

as

le

he

rd

the

ne is

te to

ur

nly

I think you missed eeboy's intent. He wants the card to be not only FAT formatted, but the file to be accessed by the bootloader is to be written to the card using windows normal file access although it can be from a program rather than through the windows GUI. I get what he is doing. In fact, I might want to do something similar myself. I would like to be able to read an SD or MMC card using an FPGA without a CPU. As long as the access is very simple, this should not be a problem. The idea of a single file on the card with direct access by knowing the sector offset rather than going through the FAT file system would make this not so hard in an FPGA.

Antti is suggesting a method of writing a file of known content and then searching it from the target system to measure the offset I believe.

Rick

Reply to
rickman

Yes, that could be done. Write the file to an otherwise empty filesystem. It should then start at cluster 2, and hopefully sequentially thereafter. Might have to write it on a older DOS system to get that to work. When updating the file, OVERWRITE the existing file, do not delete and then write it. Create it initially large as it will ever need to be. The firmware loader should be able to start at a known sector address and read sectors in order.

--
ArarghMail911 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html

To reply by email, remove the extra stuff from the reply address.
Reply to
ArarghMail911NOSPAM

=

readin=

to

=

fi=

t=

ha=

=

the

So,

machine

of

card

o=

by=

yo=

o=

Rick is correct. Given the ideas presented above it sounds as if I would need to take control of the formatting as well but I am not sure if I want to get that restrictive. I may just have to implement a portion of FAT in my bootloader so that I can seek out a particular filename/filesize.

The problem is that the user can (and likely will at some point) format the SD card via Windows Explorer and use it in the device. So, I can't rely on any specific format. The device it is used in would then generate a large number of files (up to 16GB) as well. Now, say the user wants to upgrade firmware. So, they place the SD card in a card reader and poke a button in my application that prepares the SD card. Given the suggestions, I would have to copy off existing data temporarily, format the card using one of the suggestions above, write the binary file to a known offset and finally replace the data on the card.

--------------------------------------- This message was sent using the comp.arch.embedded web interface on

formatting link

Reply to
eeboy

It's not all that difficult for FAT12 or FAT16 if you restrict your file to the root directory. I wrote a routine that searches the root directory for a specific file, and reads it into memory via the FAT. I think it took less than 512 bytes on an x86, not sure, but definitely less than 1024 bytes. The boot sector is only 2 sectors long -- non standard disk format - but I presume your routine would be in ROM or flash so my non-standard format is not an issue.

FAT32 would be a somewhat larger headache. :-) There are at least two web sites that have disassemblies of x86 bootsectors for FAT12, FAT16, and FAT32. The code may not be useful, but the logic would be.

More than likely. :-)

If it's the first thing you write to a newly formatted drive, it would be. Except that windows may not use sequential allocation units.

--
ArarghMail911 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html

To reply by email, remove the extra stuff from the reply address.
Reply to
ArarghMail911NOSPAM

The original poster did not mention the target system's CPU or even type. If it's a PC or an embedded x86, then your solution is OK because the BIOS does most of the nasty work and your boot sector just calls INTxx but what if it's an ARM or MIPS or... ?

yg

--
http://ygdes.com / http://yasep.org
Reply to
whygee

True.

I forgot all about the BIOS doing all the hard work doing the drive I/O. However, from what I remember when I read thru some bios listings, reading from an MFM / RLL / ESDI / IDE drive in PIO mode isn't all that big a deal. I would think that the other systems wouldn't be that much more complicated, but I have no idea, never having used any of them.

Unless you count a DG NOVA clone some 25 or 30 years ago. :-)

--
ArarghMail911 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html

To reply by email, remove the extra stuff from the reply address.
Reply to
ArarghMail911NOSPAM

Easiest solution is to do whatever LILO (Linux loader) used to do: put the binary file on the SD Card using normal file copy. After the file has been copied, use a special application to find out exactly where the file is, and make a list of all sector numbers. Put that list in the second half of the boot sector.

If the sector list doesn't fit in the boot sector, put it somewhere else on the disk, and put its sector numbers in the boot sector.

Reply to
Arlet

ARM bootloaders that run in a total of 8KB of memory (code and data) are able to find and load files fromt the root directory of a FAT filesystem on an SD card, so it can't be _that_ hard.

--
Grant Edwards                   grante             Yow! All right, you
                                  at               degenerates!  I want
                               visi.com            this place evacuated in
                                                   20 seconds!
Reply to
Grant Edwards

this would be OT for this group ;-)

yg

--
http://ygdes.com / http://yasep.org
Reply to
whygee

Sure.

However, 1 or 2 sectors take 512 to 1024 bytes, while 8KB is larger than that. That's at least

8x more work :-/

Seriously, with Linux, there is no such issue, just "cat mybinary > /dev/SDcard" and make the embedded CPU read X consecutive sectors. That's more or less what I did for my own x86 boot-sector applications, with nasm and standard GNU utilities. The rest of the script ensured that the device where I 'cat' is not mounted, to prevent accidental catastrophes :-)

Now, if the original poster really wants to use MS Windows, he is trading ease/speed of development for ease for the user, but sometimes the cost (time, money, complexity) is not worth it. At least, for me, it's not worth caring about this at all, for many years. With W95 it was still possible to access BIOS-driven routines for raw device access from a DOS box, but because of the lack of a decent security model, MS simply forbids this now. So why care about FAT when it can be avoided, and bait&switch operating systems ?

yg

--
http://ygdes.com / http://yasep.org
Reply to
whygee

Oops. I missed the requirement that it fit in 1-2 512-byte sectors.

--
Grant Edwards                   grante             Yow! Everybody is going
                                  at               somewhere!!  It's probably
                               visi.com            a garage sale or a disaster
                                                   Movie!!
Reply to
Grant Edwards

however the OP could code something that dumps the X first sectors anyway :-)

yg

--
http://ygdes.com / http://yasep.org
Reply to
whygee

There is no need to resort to BIOS calls to access disk sectors on Windows; one can access disk sectors using the Win32 file API calls by calling the CreateFile() function with "\\\\.\\PhysicalDriveX" as filename (X should be replaced with the number of the physical drive).

Reply to
Dombo

That's correct. I use that method to read data in a proprietary sequential file system that I use with SD cards on MSP430 loggers.

You don't necessarily need to use the physical drive number either. I use this:

sprintf(devname,"\\\\.\\%c:", *EDDevice->Text.c_str()); devhandle = CreateFile( devname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);

where %c in the file name is the drive letter (usually 'E' for the SD card interface on my computer).

Mark Borgerson

Reply to
Mark Borgerson

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.