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