uboot/cmd/cramfs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 *
   4 * based on: cmd_jffs2.c
   5 *
   6 *      Add support for a CRAMFS located in RAM
   7 */
   8
   9
  10/*
  11 * CRAMFS support
  12 */
  13#include <common.h>
  14#include <command.h>
  15#include <env.h>
  16#include <image.h>
  17#include <malloc.h>
  18#include <mapmem.h>
  19#include <linux/list.h>
  20#include <linux/ctype.h>
  21#include <jffs2/jffs2.h>
  22#include <jffs2/load_kernel.h>
  23#include <cramfs/cramfs_fs.h>
  24#include <asm/io.h>
  25
  26/* enable/disable debugging messages */
  27#define DEBUG_CRAMFS
  28#undef  DEBUG_CRAMFS
  29
  30#ifdef  DEBUG_CRAMFS
  31# define DEBUGF(fmt, args...)   printf(fmt ,##args)
  32#else
  33# define DEBUGF(fmt, args...)
  34#endif
  35
  36#include <flash.h>
  37
  38#ifndef CONFIG_MTD_NOR_FLASH
  39# define OFFSET_ADJUSTMENT      0
  40#else
  41# define OFFSET_ADJUSTMENT      (flash_info[id.num].start[0])
  42#endif
  43
  44#ifndef CONFIG_FS_JFFS2
  45#include <linux/stat.h>
  46char *mkmodestr(unsigned long mode, char *str)
  47{
  48        static const char *l = "xwr";
  49        int mask = 1, i;
  50        char c;
  51
  52        switch (mode & S_IFMT) {
  53                case S_IFDIR:    str[0] = 'd'; break;
  54                case S_IFBLK:    str[0] = 'b'; break;
  55                case S_IFCHR:    str[0] = 'c'; break;
  56                case S_IFIFO:    str[0] = 'f'; break;
  57                case S_IFLNK:    str[0] = 'l'; break;
  58                case S_IFSOCK:   str[0] = 's'; break;
  59                case S_IFREG:    str[0] = '-'; break;
  60                default:         str[0] = '?';
  61        }
  62
  63        for(i = 0; i < 9; i++) {
  64                c = l[i%3];
  65                str[9-i] = (mode & mask)?c:'-';
  66                mask = mask<<1;
  67        }
  68
  69        if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S';
  70        if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S';
  71        if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T';
  72        str[10] = '\0';
  73        return str;
  74}
  75#endif /* CONFIG_FS_JFFS2 */
  76
  77extern int cramfs_check (struct part_info *info);
  78extern int cramfs_load (char *loadoffset, struct part_info *info, char *filename);
  79extern int cramfs_ls (struct part_info *info, char *filename);
  80extern int cramfs_info (struct part_info *info);
  81
  82/***************************************************/
  83/* U-Boot commands                                 */
  84/***************************************************/
  85
  86/**
  87 * Routine implementing fsload u-boot command. This routine tries to load
  88 * a requested file from cramfs filesystem at location 'cramfsaddr'.
  89 * cramfsaddr is an evironment variable.
  90 *
  91 * @param cmdtp command internal data
  92 * @param flag command flag
  93 * @param argc number of arguments supplied to the command
  94 * @param argv arguments list
  95 * @return 0 on success, 1 otherwise
  96 */
  97int do_cramfs_load(struct cmd_tbl *cmdtp, int flag, int argc,
  98                   char *const argv[])
  99{
 100        char *filename;
 101        int size;
 102        ulong offset = image_load_addr;
 103        char *offset_virt;
 104
 105        struct part_info part;
 106        struct mtd_device dev;
 107        struct mtdids id;
 108
 109        ulong addr;
 110        addr = hextoul(env_get("cramfsaddr"), NULL);
 111
 112        /* hack! */
 113        /* cramfs_* only supports NOR flash chips */
 114        /* fake the device type */
 115        id.type = MTD_DEV_TYPE_NOR;
 116        id.num = 0;
 117        dev.id = &id;
 118        part.dev = &dev;
 119        /* fake the address offset */
 120        part.offset = (u64)(uintptr_t) map_sysmem(addr - OFFSET_ADJUSTMENT, 0);
 121
 122        /* pre-set Boot file name */
 123        filename = env_get("bootfile");
 124        if (!filename)
 125                filename = "uImage";
 126
 127        if (argc == 2) {
 128                filename = argv[1];
 129        }
 130        if (argc == 3) {
 131                offset = simple_strtoul(argv[1], NULL, 0);
 132                image_load_addr = offset;
 133                filename = argv[2];
 134        }
 135
 136        offset_virt = map_sysmem(offset, 0);
 137        size = 0;
 138        if (cramfs_check(&part))
 139                size = cramfs_load (offset_virt, &part, filename);
 140
 141        if (size > 0) {
 142                printf("### CRAMFS load complete: %d bytes loaded to 0x%lx\n",
 143                        size, offset);
 144                env_set_hex("filesize", size);
 145        } else {
 146                printf("### CRAMFS LOAD ERROR<%x> for %s!\n", size, filename);
 147        }
 148
 149        unmap_sysmem(offset_virt);
 150        unmap_sysmem((void *)(uintptr_t)part.offset);
 151
 152        return !(size > 0);
 153}
 154
 155/**
 156 * Routine implementing u-boot ls command which lists content of a given
 157 * directory at location 'cramfsaddr'.
 158 * cramfsaddr is an evironment variable.
 159 *
 160 * @param cmdtp command internal data
 161 * @param flag command flag
 162 * @param argc number of arguments supplied to the command
 163 * @param argv arguments list
 164 * @return 0 on success, 1 otherwise
 165 */
 166int do_cramfs_ls(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 167{
 168        char *filename = "/";
 169        int ret;
 170        struct part_info part;
 171        struct mtd_device dev;
 172        struct mtdids id;
 173
 174        ulong addr;
 175        addr = hextoul(env_get("cramfsaddr"), NULL);
 176
 177        /* hack! */
 178        /* cramfs_* only supports NOR flash chips */
 179        /* fake the device type */
 180        id.type = MTD_DEV_TYPE_NOR;
 181        id.num = 0;
 182        dev.id = &id;
 183        part.dev = &dev;
 184        /* fake the address offset */
 185        part.offset = (u64)(uintptr_t) map_sysmem(addr - OFFSET_ADJUSTMENT, 0);
 186
 187        if (argc == 2)
 188                filename = argv[1];
 189
 190        ret = 0;
 191        if (cramfs_check(&part))
 192                ret = cramfs_ls (&part, filename);
 193        unmap_sysmem((void *)(uintptr_t)part.offset);
 194
 195        return ret ? 0 : 1;
 196}
 197
 198/* command line only */
 199
 200/***************************************************/
 201U_BOOT_CMD(
 202        cramfsload,     3,      0,      do_cramfs_load,
 203        "load binary file from a filesystem image",
 204        "[ off ] [ filename ]\n"
 205        "    - load binary file from address 'cramfsaddr'\n"
 206        "      with offset 'off'\n"
 207);
 208U_BOOT_CMD(
 209        cramfsls,       2,      1,      do_cramfs_ls,
 210        "list files in a directory (default /)",
 211        "[ directory ]\n"
 212        "    - list files in a directory.\n"
 213);
 214