[U-Boot] u-boot: How to read file from FAT filesystem on NorFlash MTD partition

Xianwei Zeng xianweizeng at gmail.com
Tue Nov 24 04:09:24 CET 2009


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 at 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;
+}
+

-- 
Best Regards
Xianwei ZENG
----Linux Fans


More information about the U-Boot mailing list