12e192b24SSimon Glass /* 22e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 32e192b24SSimon Glass * 42e192b24SSimon Glass * based on: cmd_jffs2.c 52e192b24SSimon Glass * 62e192b24SSimon Glass * Add support for a CRAMFS located in RAM 72e192b24SSimon Glass */ 82e192b24SSimon Glass 92e192b24SSimon Glass 102e192b24SSimon Glass /* 112e192b24SSimon Glass * CRAMFS support 122e192b24SSimon Glass */ 132e192b24SSimon Glass #include <common.h> 142e192b24SSimon Glass #include <command.h> 152e192b24SSimon Glass #include <malloc.h> 162e192b24SSimon Glass #include <linux/list.h> 172e192b24SSimon Glass #include <linux/ctype.h> 182e192b24SSimon Glass #include <jffs2/jffs2.h> 192e192b24SSimon Glass #include <jffs2/load_kernel.h> 202e192b24SSimon Glass #include <cramfs/cramfs_fs.h> 212e192b24SSimon Glass 222e192b24SSimon Glass /* enable/disable debugging messages */ 232e192b24SSimon Glass #define DEBUG_CRAMFS 242e192b24SSimon Glass #undef DEBUG_CRAMFS 252e192b24SSimon Glass 262e192b24SSimon Glass #ifdef DEBUG_CRAMFS 272e192b24SSimon Glass # define DEBUGF(fmt, args...) printf(fmt ,##args) 282e192b24SSimon Glass #else 292e192b24SSimon Glass # define DEBUGF(fmt, args...) 302e192b24SSimon Glass #endif 312e192b24SSimon Glass 322e192b24SSimon Glass #include <flash.h> 332e192b24SSimon Glass 34*e856bdcfSMasahiro Yamada #ifndef CONFIG_MTD_NOR_FLASH 352e192b24SSimon Glass # define OFFSET_ADJUSTMENT 0 362e192b24SSimon Glass #else 372e192b24SSimon Glass # define OFFSET_ADJUSTMENT (flash_info[id.num].start[0]) 382e192b24SSimon Glass #endif 392e192b24SSimon Glass 402e192b24SSimon Glass #ifndef CONFIG_CMD_JFFS2 412e192b24SSimon Glass #include <linux/stat.h> 422e192b24SSimon Glass char *mkmodestr(unsigned long mode, char *str) 432e192b24SSimon Glass { 442e192b24SSimon Glass static const char *l = "xwr"; 452e192b24SSimon Glass int mask = 1, i; 462e192b24SSimon Glass char c; 472e192b24SSimon Glass 482e192b24SSimon Glass switch (mode & S_IFMT) { 492e192b24SSimon Glass case S_IFDIR: str[0] = 'd'; break; 502e192b24SSimon Glass case S_IFBLK: str[0] = 'b'; break; 512e192b24SSimon Glass case S_IFCHR: str[0] = 'c'; break; 522e192b24SSimon Glass case S_IFIFO: str[0] = 'f'; break; 532e192b24SSimon Glass case S_IFLNK: str[0] = 'l'; break; 542e192b24SSimon Glass case S_IFSOCK: str[0] = 's'; break; 552e192b24SSimon Glass case S_IFREG: str[0] = '-'; break; 562e192b24SSimon Glass default: str[0] = '?'; 572e192b24SSimon Glass } 582e192b24SSimon Glass 592e192b24SSimon Glass for(i = 0; i < 9; i++) { 602e192b24SSimon Glass c = l[i%3]; 612e192b24SSimon Glass str[9-i] = (mode & mask)?c:'-'; 622e192b24SSimon Glass mask = mask<<1; 632e192b24SSimon Glass } 642e192b24SSimon Glass 652e192b24SSimon Glass if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S'; 662e192b24SSimon Glass if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S'; 672e192b24SSimon Glass if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T'; 682e192b24SSimon Glass str[10] = '\0'; 692e192b24SSimon Glass return str; 702e192b24SSimon Glass } 712e192b24SSimon Glass #endif /* CONFIG_CMD_JFFS2 */ 722e192b24SSimon Glass 732e192b24SSimon Glass extern int cramfs_check (struct part_info *info); 742e192b24SSimon Glass extern int cramfs_load (char *loadoffset, struct part_info *info, char *filename); 752e192b24SSimon Glass extern int cramfs_ls (struct part_info *info, char *filename); 762e192b24SSimon Glass extern int cramfs_info (struct part_info *info); 772e192b24SSimon Glass 782e192b24SSimon Glass /***************************************************/ 79a187559eSBin Meng /* U-Boot commands */ 802e192b24SSimon Glass /***************************************************/ 812e192b24SSimon Glass 822e192b24SSimon Glass /** 832e192b24SSimon Glass * Routine implementing fsload u-boot command. This routine tries to load 842e192b24SSimon Glass * a requested file from cramfs filesystem at location 'cramfsaddr'. 852e192b24SSimon Glass * cramfsaddr is an evironment variable. 862e192b24SSimon Glass * 872e192b24SSimon Glass * @param cmdtp command internal data 882e192b24SSimon Glass * @param flag command flag 892e192b24SSimon Glass * @param argc number of arguments supplied to the command 902e192b24SSimon Glass * @param argv arguments list 912e192b24SSimon Glass * @return 0 on success, 1 otherwise 922e192b24SSimon Glass */ 932e192b24SSimon Glass int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 942e192b24SSimon Glass { 952e192b24SSimon Glass char *filename; 962e192b24SSimon Glass int size; 972e192b24SSimon Glass ulong offset = load_addr; 982e192b24SSimon Glass 992e192b24SSimon Glass struct part_info part; 1002e192b24SSimon Glass struct mtd_device dev; 1012e192b24SSimon Glass struct mtdids id; 1022e192b24SSimon Glass 1032e192b24SSimon Glass ulong addr; 1042e192b24SSimon Glass addr = simple_strtoul(getenv("cramfsaddr"), NULL, 16); 1052e192b24SSimon Glass 1062e192b24SSimon Glass /* hack! */ 1072e192b24SSimon Glass /* cramfs_* only supports NOR flash chips */ 1082e192b24SSimon Glass /* fake the device type */ 1092e192b24SSimon Glass id.type = MTD_DEV_TYPE_NOR; 1102e192b24SSimon Glass id.num = 0; 1112e192b24SSimon Glass dev.id = &id; 1122e192b24SSimon Glass part.dev = &dev; 1132e192b24SSimon Glass /* fake the address offset */ 1142e192b24SSimon Glass part.offset = addr - OFFSET_ADJUSTMENT; 1152e192b24SSimon Glass 1162e192b24SSimon Glass /* pre-set Boot file name */ 1172e192b24SSimon Glass if ((filename = getenv("bootfile")) == NULL) { 1182e192b24SSimon Glass filename = "uImage"; 1192e192b24SSimon Glass } 1202e192b24SSimon Glass 1212e192b24SSimon Glass if (argc == 2) { 1222e192b24SSimon Glass filename = argv[1]; 1232e192b24SSimon Glass } 1242e192b24SSimon Glass if (argc == 3) { 1252e192b24SSimon Glass offset = simple_strtoul(argv[1], NULL, 0); 1262e192b24SSimon Glass load_addr = offset; 1272e192b24SSimon Glass filename = argv[2]; 1282e192b24SSimon Glass } 1292e192b24SSimon Glass 1302e192b24SSimon Glass size = 0; 1312e192b24SSimon Glass if (cramfs_check(&part)) 1322e192b24SSimon Glass size = cramfs_load ((char *) offset, &part, filename); 1332e192b24SSimon Glass 1342e192b24SSimon Glass if (size > 0) { 1352e192b24SSimon Glass printf("### CRAMFS load complete: %d bytes loaded to 0x%lx\n", 1362e192b24SSimon Glass size, offset); 1372e192b24SSimon Glass setenv_hex("filesize", size); 1382e192b24SSimon Glass } else { 1392e192b24SSimon Glass printf("### CRAMFS LOAD ERROR<%x> for %s!\n", size, filename); 1402e192b24SSimon Glass } 1412e192b24SSimon Glass 1422e192b24SSimon Glass return !(size > 0); 1432e192b24SSimon Glass } 1442e192b24SSimon Glass 1452e192b24SSimon Glass /** 1462e192b24SSimon Glass * Routine implementing u-boot ls command which lists content of a given 1472e192b24SSimon Glass * directory at location 'cramfsaddr'. 1482e192b24SSimon Glass * cramfsaddr is an evironment variable. 1492e192b24SSimon Glass * 1502e192b24SSimon Glass * @param cmdtp command internal data 1512e192b24SSimon Glass * @param flag command flag 1522e192b24SSimon Glass * @param argc number of arguments supplied to the command 1532e192b24SSimon Glass * @param argv arguments list 1542e192b24SSimon Glass * @return 0 on success, 1 otherwise 1552e192b24SSimon Glass */ 1562e192b24SSimon Glass int do_cramfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1572e192b24SSimon Glass { 1582e192b24SSimon Glass char *filename = "/"; 1592e192b24SSimon Glass int ret; 1602e192b24SSimon Glass struct part_info part; 1612e192b24SSimon Glass struct mtd_device dev; 1622e192b24SSimon Glass struct mtdids id; 1632e192b24SSimon Glass 1642e192b24SSimon Glass ulong addr; 1652e192b24SSimon Glass addr = simple_strtoul(getenv("cramfsaddr"), NULL, 16); 1662e192b24SSimon Glass 1672e192b24SSimon Glass /* hack! */ 1682e192b24SSimon Glass /* cramfs_* only supports NOR flash chips */ 1692e192b24SSimon Glass /* fake the device type */ 1702e192b24SSimon Glass id.type = MTD_DEV_TYPE_NOR; 1712e192b24SSimon Glass id.num = 0; 1722e192b24SSimon Glass dev.id = &id; 1732e192b24SSimon Glass part.dev = &dev; 1742e192b24SSimon Glass /* fake the address offset */ 1752e192b24SSimon Glass part.offset = addr - OFFSET_ADJUSTMENT; 1762e192b24SSimon Glass 1772e192b24SSimon Glass if (argc == 2) 1782e192b24SSimon Glass filename = argv[1]; 1792e192b24SSimon Glass 1802e192b24SSimon Glass ret = 0; 1812e192b24SSimon Glass if (cramfs_check(&part)) 1822e192b24SSimon Glass ret = cramfs_ls (&part, filename); 1832e192b24SSimon Glass 1842e192b24SSimon Glass return ret ? 0 : 1; 1852e192b24SSimon Glass } 1862e192b24SSimon Glass 1872e192b24SSimon Glass /* command line only */ 1882e192b24SSimon Glass 1892e192b24SSimon Glass /***************************************************/ 1902e192b24SSimon Glass U_BOOT_CMD( 1912e192b24SSimon Glass cramfsload, 3, 0, do_cramfs_load, 1922e192b24SSimon Glass "load binary file from a filesystem image", 1932e192b24SSimon Glass "[ off ] [ filename ]\n" 1942e192b24SSimon Glass " - load binary file from address 'cramfsaddr'\n" 1952e192b24SSimon Glass " with offset 'off'\n" 1962e192b24SSimon Glass ); 1972e192b24SSimon Glass U_BOOT_CMD( 1982e192b24SSimon Glass cramfsls, 2, 1, do_cramfs_ls, 1992e192b24SSimon Glass "list files in a directory (default /)", 2002e192b24SSimon Glass "[ directory ]\n" 2012e192b24SSimon Glass " - list files in a directory.\n" 2022e192b24SSimon Glass ); 203