
Hi,
But I still don't know the way how to read file inside this FAT filesystem.
- Which command can do this? (fatload seems can not because the interface
is not known)
- From which verion u-boot supports this feature? Our u-boot is based
v2009.08. Do we need to update to latest one? (v2009.11-rc1)
I check the document and didn't found the answer. So I have to write it by
myself.
I created a patch which provide two functions: fat_norflash_init() fat_norflash_load()
The user call these function in sequence to read file from FAT file system on Nor Flash.
Here is my code, it has not been cleaned for common use, so a little bit ugly:
Index: b/common/fat_norflash.c =================================================================== --- /dev/null +++ b/common/fat_norflash.c @@ -0,0 +1,148 @@ +/* + * (C) Copyright 2009 + * Zeng Xianwei xianweizeng@gmail.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <config.h> +#include <common.h> +#include <asm/errno.h> +#include <asm/arch/hardware.h> +#include <part.h> +#include <flash.h> + +#ifdef CONFIG_FAT_NORFLASH + +/* #define DEBUG */ + +#ifdef DEBUG +#define DPRINTF(args...) printf(args) +#else +#define DPRINTF(args...) +#endif + +extern flash_info_t flash_info[]; +extern int fat_register_device(block_dev_desc_t * dev_desc, int part_no); + +static block_dev_desc_t norflash_dev; + +struct fat_norflash_info_t { + unsigned long start; + int size; +} fat_norflash_info; + +/* block read function, called by disk_read() in fat.c */ +static unsigned long +norflash_bread(int dev, ulong blknr, lbaint_t blkcnt, void *dst) +{ + ulong src = fat_norflash_info.start + blknr * 512; + + DPRINTF("== read: nr %ld cnt %ld src %lx dst %p ==\n", + blknr, blkcnt, src, dst); + memcpy((unsigned char *)dst, (unsigned char *)(src), blkcnt * 512); + + return blkcnt; +} + +int fat_norflash_init(uint32_t address, int size) +{ + int bank, cnt; + flash_info_t *info; + + for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) { + cnt = 0; + info = &flash_info[bank]; + + /* Nothing to do if the bank doesn't exist */ + if (info->sector_count == 0) + continue; + /* Found */ + if (address >= info->start[0] && + address < (info->start[0] + info->size)) { + break; + } + } + + if (bank == CONFIG_SYS_MAX_FLASH_BANKS) + return -ENODEV; + + if (size > info->size) { + printf("Fat filesystem size exceeds entile flash size.\n"); + return -EINVAL; + } + + /* Valid flash infomation */ + fat_norflash_info.start = address; + fat_norflash_info.size = size; + sprintf((char *)norflash_dev.vendor, "Flash ID: %ld", info->flash_id); + + /* Initialize block layer */ + norflash_dev.blksz = 512; + norflash_dev.lba = size / 512; + norflash_dev.part_type = PART_TYPE_DOS; + norflash_dev.dev = 0; + norflash_dev.lun = 0; + norflash_dev.type = DEV_TYPE_HARDDISK; + norflash_dev.removable = 0; + norflash_dev.block_read = norflash_bread; + norflash_dev.if_type = IF_TYPE_UNKNOWN; + norflash_dev.priv = &fat_norflash_info; + + DPRINTF("Fat FileSystem on NorFlash at %lx size %lu bytes (%luMB) ", + address, size, size / (1024 * 1024)); + return 0; +} + +int +fat_norflash_load(const char *filename, unsigned long load_addr, + unsigned long maxsize) +{ + struct fat_norflash_info_t *info = + (struct fat_norflash_info_t *)(norflash_dev.priv); + long size; + int ret; + + if (!norflash_dev.blksz) { + printf("Fat on NorFlash has not been initialized.\n"); + return -ENODEV; + } + + ret = fat_register_device(&norflash_dev, 1); + if (ret) { + printf ("Unable to use fat on nor flash at %lx err %d\n", + info->start, ret); + return 1; + } + + if (maxsize > info->size) + maxsize = info->size; + + DPRINTF("Load file "%s" to memory %lx\n", filename, load_addr); + size = file_fat_read (filename, (unsigned char *) load_addr, maxsize); + if (size == -1) { + printf("Unable to read "%s" from FAT in NorFlash at %lx\n", + filename, info->start); + return 1; + } + + printf ("\n%ld bytes read\n", size); + return 0; +} +