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