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