Commit 91bb4ca665d2e0cf7f60c4b5b370990250ec0c43
1 parent
5a2f1098d8
Exists in
master
and in
54 other branches
[FS] Added support for ROMFS
Showing 5 changed files with 358 additions and 21 deletions Side-by-side Diff
Makefile
... | ... | @@ -199,7 +199,7 @@ |
199 | 199 | endif |
200 | 200 | LIBS += lib_$(ARCH)/lib$(ARCH).a |
201 | 201 | LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \ |
202 | - fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a | |
202 | + fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/romfs/libromfs.a | |
203 | 203 | LIBS += net/libnet.a |
204 | 204 | LIBS += disk/libdisk.a |
205 | 205 | LIBS += rtc/librtc.a |
206 | 206 | |
... | ... | @@ -316,14 +316,14 @@ |
316 | 316 | tags ctags: |
317 | 317 | ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) include \ |
318 | 318 | lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \ |
319 | - fs/cramfs fs/fat fs/fdos fs/jffs2 \ | |
319 | + fs/cramfs fs/fat fs/fdos fs/jffs2 fs/romfs\ | |
320 | 320 | net disk rtc dtt drivers drivers/sk98lin common \ |
321 | 321 | \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)` |
322 | 322 | |
323 | 323 | etags: |
324 | 324 | etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) include \ |
325 | 325 | lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \ |
326 | - fs/cramfs fs/fat fs/fdos fs/jffs2 \ | |
326 | + fs/cramfs fs/fat fs/fdos fs/jffs2 fs/romfs\ | |
327 | 327 | net disk rtc dtt drivers drivers/sk98lin common \ |
328 | 328 | \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)` |
329 | 329 |
common/cmd_jffs2.c
... | ... | @@ -28,7 +28,7 @@ |
28 | 28 | * |
29 | 29 | * This program is distributed in the hope that it will be useful, |
30 | 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
31 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
31 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32 | 32 | * GNU General Public License for more details. |
33 | 33 | * |
34 | 34 | * You should have received a copy of the GNU General Public License |
... | ... | @@ -85,7 +85,7 @@ |
85 | 85 | */ |
86 | 86 | |
87 | 87 | /* |
88 | - * JFFS2/CRAMFS support | |
88 | + * JFFS2/CRAMFS/ROMFS support | |
89 | 89 | */ |
90 | 90 | #include <common.h> |
91 | 91 | #include <command.h> |
... | ... | @@ -110,7 +110,7 @@ |
110 | 110 | #define DEBUG_JFFS |
111 | 111 | #undef DEBUG_JFFS |
112 | 112 | |
113 | -#ifdef DEBUG_JFFS | |
113 | +#ifdef DEBUG_JFFS | |
114 | 114 | # define DEBUGF(fmt, args...) printf(fmt ,##args) |
115 | 115 | #else |
116 | 116 | # define DEBUGF(fmt, args...) |
... | ... | @@ -175,6 +175,11 @@ |
175 | 175 | extern int cramfs_ls (struct part_info *info, char *filename); |
176 | 176 | extern int cramfs_info (struct part_info *info); |
177 | 177 | |
178 | +extern int romfs_check (struct part_info *info); | |
179 | +extern int romfs_load (char *loadoffset, struct part_info *info, char *filename); | |
180 | +extern int romfs_ls (struct part_info *info, char *filename); | |
181 | +extern int romfs_info (struct part_info *info); | |
182 | + | |
178 | 183 | static struct part_info* jffs2_part_info(struct mtd_device *dev, unsigned int part_num); |
179 | 184 | |
180 | 185 | /* command line only routines */ |
181 | 186 | |
... | ... | @@ -184,10 +189,10 @@ |
184 | 189 | static int device_del(struct mtd_device *dev); |
185 | 190 | |
186 | 191 | /** |
187 | - * Parses a string into a number. The number stored at ptr is | |
192 | + * Parses a string into a number. The number stored at ptr is | |
188 | 193 | * potentially suffixed with K (for kilobytes, or 1024 bytes), |
189 | 194 | * M (for megabytes, or 1048576 bytes), or G (for gigabytes, or |
190 | - * 1073741824). If the number is suffixed with K, M, or G, then | |
195 | + * 1073741824). If the number is suffixed with K, M, or G, then | |
191 | 196 | * the return value is the number multiplied by one kilobyte, one |
192 | 197 | * megabyte, or one gigabyte, respectively. |
193 | 198 | * |
... | ... | @@ -676,7 +681,7 @@ |
676 | 681 | return 1; |
677 | 682 | } |
678 | 683 | |
679 | - /* allocate memory */ | |
684 | + /* allocate memory */ | |
680 | 685 | part = (struct part_info *)malloc(sizeof(struct part_info) + name_len); |
681 | 686 | if (!part) { |
682 | 687 | printf("out of memory\n"); |
... | ... | @@ -1832,9 +1837,9 @@ |
1832 | 1837 | return NULL; |
1833 | 1838 | } |
1834 | 1839 | |
1835 | -/***************************************************/ | |
1836 | -/* U-boot commands */ | |
1837 | -/***************************************************/ | |
1840 | +/*************************************************/ | |
1841 | +/* U-boot commands */ | |
1842 | +/*************************************************/ | |
1838 | 1843 | |
1839 | 1844 | /** |
1840 | 1845 | * Routine implementing fsload u-boot command. This routine tries to load |
1841 | 1846 | |
1842 | 1847 | |
... | ... | @@ -1874,14 +1879,22 @@ |
1874 | 1879 | |
1875 | 1880 | if ((part = jffs2_part_info(current_dev, current_partnum))){ |
1876 | 1881 | |
1877 | - /* check partition type for cramfs */ | |
1878 | - fsname = (cramfs_check(part) ? "CRAMFS" : "JFFS2"); | |
1882 | + /* check partition type for JFFS2, cramfs, romfs */ | |
1883 | + if (cramfs_check(part)) { | |
1884 | + fsname = "CRAMFS"; | |
1885 | + } else if (romfs_check(part)) { | |
1886 | + fsname = "ROMFS"; | |
1887 | + } else { | |
1888 | + fsname = "JFFS2"; | |
1889 | + } | |
1879 | 1890 | printf("### %s loading '%s' to 0x%lx\n", fsname, filename, offset); |
1880 | 1891 | |
1881 | 1892 | if (cramfs_check(part)) { |
1882 | 1893 | size = cramfs_load ((char *) offset, part, filename); |
1894 | + } else if (romfs_check(part)){ | |
1895 | + size = romfs_load ((char *) offset, part, filename); | |
1883 | 1896 | } else { |
1884 | - /* if this is not cramfs assume jffs2 */ | |
1897 | + /* if this is not cramfs or romfs assume jffs2 */ | |
1885 | 1898 | size = jffs2_1pass_load((char *)offset, part, filename); |
1886 | 1899 | } |
1887 | 1900 | |
1888 | 1901 | |
... | ... | @@ -1928,8 +1941,10 @@ |
1928 | 1941 | /* check partition type for cramfs */ |
1929 | 1942 | if (cramfs_check(part)) { |
1930 | 1943 | ret = cramfs_ls (part, filename); |
1944 | + } else if (romfs_check(part)) { | |
1945 | + ret = romfs_ls (part, filename); | |
1931 | 1946 | } else { |
1932 | - /* if this is not cramfs assume jffs2 */ | |
1947 | + /* if this is not cramfs or romfs assume jffs2 */ | |
1933 | 1948 | ret = jffs2_1pass_ls(part, filename); |
1934 | 1949 | } |
1935 | 1950 | |
... | ... | @@ -1951,7 +1966,6 @@ |
1951 | 1966 | int do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
1952 | 1967 | { |
1953 | 1968 | struct part_info *part; |
1954 | - char *fsname; | |
1955 | 1969 | int ret; |
1956 | 1970 | |
1957 | 1971 | /* make sure we are in sync with env variables */ |
1958 | 1972 | |
1959 | 1973 | |
1960 | 1974 | |
... | ... | @@ -1961,13 +1975,17 @@ |
1961 | 1975 | if ((part = jffs2_part_info(current_dev, current_partnum))){ |
1962 | 1976 | |
1963 | 1977 | /* check partition type for cramfs */ |
1964 | - fsname = (cramfs_check(part) ? "CRAMFS" : "JFFS2"); | |
1965 | - printf("### filesystem type is %s\n", fsname); | |
1978 | + puts("### filesystem type is "); | |
1966 | 1979 | |
1967 | 1980 | if (cramfs_check(part)) { |
1981 | + puts("CRAMFS\n"); | |
1968 | 1982 | ret = cramfs_info (part); |
1983 | + } else if (romfs_check(part)) { | |
1984 | + puts("ROMFS\n"); | |
1985 | + ret = romfs_info (part); | |
1969 | 1986 | } else { |
1970 | - /* if this is not cramfs assume jffs2 */ | |
1987 | + /* if this is not cramfs or romfs assume jffs2 */ | |
1988 | + puts("JFFS2\n"); | |
1971 | 1989 | ret = jffs2_1pass_info(part); |
1972 | 1990 | } |
1973 | 1991 |
fs/Makefile
fs/romfs/Makefile
1 | +# | |
2 | +# (C) Copyright 2000-2006 | |
3 | +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | +# | |
5 | +# See file CREDITS for list of people who contributed to this | |
6 | +# project. | |
7 | +# | |
8 | +# This program is free software; you can redistribute it and/or | |
9 | +# modify it under the terms of the GNU General Public License as | |
10 | +# published by the Free Software Foundation; either version 2 of | |
11 | +# the License, or (at your option) any later version. | |
12 | +# | |
13 | +# This program is distributed in the hope that it will be useful, | |
14 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | +# GNU General Public License for more details. | |
17 | +# | |
18 | +# You should have received a copy of the GNU General Public License | |
19 | +# along with this program; if not, write to the Free Software | |
20 | +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | +# MA 02111-1307 USA | |
22 | +# | |
23 | + | |
24 | +include $(TOPDIR)/config.mk | |
25 | + | |
26 | +LIB = $(obj)libromfs.a | |
27 | + | |
28 | +AOBJS = | |
29 | +COBJS = romfs.o | |
30 | + | |
31 | +SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) | |
32 | +OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS)) | |
33 | + | |
34 | +#CPPFLAGS += | |
35 | + | |
36 | +all: $(LIB) $(AOBJS) | |
37 | + | |
38 | +$(LIB): $(obj).depend $(OBJS) | |
39 | + $(AR) $(ARFLAGS) $@ $(OBJS) | |
40 | + | |
41 | + | |
42 | +######################################################################### | |
43 | + | |
44 | +# defines $(obj).depend target | |
45 | +include $(SRCTREE)/rules.mk | |
46 | + | |
47 | +sinclude $(obj).depend | |
48 | + | |
49 | +######################################################################### |
fs/romfs/romfs.c
1 | +/* | |
2 | + * (C) Copyright 2007 Michal Simek | |
3 | + * | |
4 | + * Michal SIMEK <monstr@monstr.eu> | |
5 | + * | |
6 | + * See file CREDITS for list of people who contributed to this | |
7 | + * project. | |
8 | + * | |
9 | + * This program is free software; you can redistribute it and/or | |
10 | + * modify it under the terms of the GNU General Public License as | |
11 | + * published by the Free Software Foundation; either version 2 of | |
12 | + * the License, or (at your option) any later version. | |
13 | + * | |
14 | + * This program is distributed in the hope that it will be useful, | |
15 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | + * GNU General Public License for more details. | |
18 | + * | |
19 | + * You should have received a copy of the GNU General Public License | |
20 | + * along with this program; if not, write to the Free Software | |
21 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
22 | + * MA 02111-1307 USA | |
23 | + */ | |
24 | + | |
25 | +#include <common.h> | |
26 | +#include <malloc.h> | |
27 | +#include <command.h> | |
28 | + | |
29 | +#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) | |
30 | + | |
31 | +#include <asm/byteorder.h> | |
32 | +#include <linux/stat.h> | |
33 | +#include <jffs2/jffs2.h> | |
34 | +#include <jffs2/load_kernel.h> | |
35 | + | |
36 | +#undef DEBUG_ROMFS | |
37 | + | |
38 | +/* ROMFS superblock */ | |
39 | +struct romfs_super { | |
40 | + u32 word0; | |
41 | + u32 word1; | |
42 | + u32 size; | |
43 | + u32 checksum; | |
44 | + char name[0]; | |
45 | +}; | |
46 | + | |
47 | +struct romfs_inode { | |
48 | + u32 next; | |
49 | + u32 spec; | |
50 | + u32 size; | |
51 | + u32 checksum; | |
52 | + char name[0]; | |
53 | +}; | |
54 | + | |
55 | +extern flash_info_t flash_info[]; | |
56 | +#define PART_OFFSET(x) (x->offset + flash_info[x->dev->id->num].start[0]) | |
57 | +#define ALIGN(x) (((x) & 0xfffffff0)) | |
58 | +#define HEADERSIZE(name) (0x20 + ALIGN(strlen(name))) | |
59 | + | |
60 | +static unsigned long romfs_resolve (unsigned long begin, unsigned long offset, | |
61 | + unsigned long size, int raw, char *filename) | |
62 | +{ | |
63 | + unsigned long inodeoffset = 0, nextoffset; | |
64 | + struct romfs_inode *inode; | |
65 | +#ifdef DEBUG_ROMFS | |
66 | + printf ("ROMFS_resolve: begin 0x%x, offset 0x%x, size 0x%x, raw 0x%x, \ | |
67 | + filename %s\n", begin, offset, size, raw, filename); | |
68 | +#endif | |
69 | + | |
70 | + while (inodeoffset < size) { | |
71 | + inode = (struct romfs_inode *)(begin + offset + inodeoffset); | |
72 | + offset = 0; | |
73 | + nextoffset = ALIGN (inode->next); | |
74 | +#ifdef DEBUG_ROMFS | |
75 | + printf("inode 0x%x, name %s - len 0x%x, next inode 0x%x, \ | |
76 | + compare names 0x%x\n", | |
77 | + inode, inode->name, strlen (inode->name), nextoffset, | |
78 | + strncmp (filename, inode->name, strlen (filename))); | |
79 | +#endif | |
80 | + if (!strncmp (filename, inode->name, strlen (inode->name))) { | |
81 | + char *p = strtok (NULL, "/"); | |
82 | + if (raw && (p == NULL || *p == '\0')) { | |
83 | + return offset + inodeoffset; | |
84 | + } | |
85 | + return romfs_resolve (begin, | |
86 | + inodeoffset + HEADERSIZE (inode->name), | |
87 | + size, raw, p); | |
88 | + } | |
89 | + inodeoffset = nextoffset; | |
90 | + } | |
91 | + | |
92 | + printf ("can't find corresponding entry\n"); | |
93 | + return 0; | |
94 | +} | |
95 | + | |
96 | +int romfs_load (char *loadoffset, struct part_info *info, char *filename) | |
97 | +{ | |
98 | + struct romfs_inode *inode; | |
99 | + struct romfs_super *sb; | |
100 | + char *data; | |
101 | + int pocet; | |
102 | + sb = (struct romfs_super *) PART_OFFSET (info); | |
103 | + | |
104 | + unsigned long offset; | |
105 | + | |
106 | + offset = romfs_resolve (PART_OFFSET (info), HEADERSIZE (sb->name), | |
107 | + sb->size, 1, strtok (filename, "/")); | |
108 | + if (offset <= 0) | |
109 | + return offset; | |
110 | + | |
111 | + inode = (struct romfs_inode *)(PART_OFFSET (info) + offset); | |
112 | + data = (char *)((int)inode + HEADERSIZE (inode->name)); | |
113 | + pocet = inode->size; | |
114 | + while (pocet--) { | |
115 | + *loadoffset++ = *data++; | |
116 | + } | |
117 | + return inode->size; | |
118 | +} | |
119 | + | |
120 | +static int romfs_list_inode (struct part_info *info, unsigned long offset) | |
121 | +{ | |
122 | + struct romfs_inode *inode = | |
123 | + (struct romfs_inode *)(PART_OFFSET (info) + offset); | |
124 | + struct romfs_inode *hardlink = NULL; | |
125 | + char str[3], *data; | |
126 | + | |
127 | +/* mapping spec.info means | |
128 | + * 0 hard link link destination [file header] | |
129 | + * 1 directory first file's header | |
130 | + * 2 regular file unused, must be zero [MBZ] | |
131 | + * 3 symbolic link unused, MBZ (file data is the link content) | |
132 | + * 4 block device 16/16 bits major/minor number | |
133 | + * 5 char device - " - | |
134 | + * 6 socket unused, MBZ | |
135 | + * 7 fifo unused, MBZ | |
136 | + */ | |
137 | + switch (inode->next & 0x7) { | |
138 | + case 0: | |
139 | + str[0] = 'h'; | |
140 | + break; | |
141 | + case 1: | |
142 | + str[0] = 'd'; | |
143 | + break; | |
144 | + case 2: | |
145 | + str[0] = 'f'; | |
146 | + break; | |
147 | + case 3: | |
148 | + str[0] = 'l'; | |
149 | + break; | |
150 | + case 4: | |
151 | + str[0] = 'b'; | |
152 | + break; | |
153 | + case 5: | |
154 | + str[0] = 'c'; | |
155 | + break; | |
156 | + case 6: | |
157 | + str[0] = 's'; | |
158 | + break; | |
159 | + case 7: | |
160 | + str[0] = 'p'; | |
161 | + break; | |
162 | + default: | |
163 | + str[0] = '?'; | |
164 | + } | |
165 | + | |
166 | + if (inode->next & 0x8) { | |
167 | + str[1] = 'x'; | |
168 | + } else { | |
169 | + str[1] = '-'; | |
170 | + } | |
171 | + str[2] = '\0'; | |
172 | + | |
173 | + if ((str[0] == 'b') || (str[0] == 'c')) { | |
174 | +#ifdef DEBUG_ROMFS | |
175 | + printf (" %s %3d,%3d %12s 0x%08x 0x%08x", str, | |
176 | + (inode->spec & 0xffff0000) >> 16, | |
177 | + inode->spec & 0x0000ffff, inode->name, inode, | |
178 | + inode->spec); | |
179 | +#else | |
180 | + printf (" %s %3d,%3d %12s", str, | |
181 | + (inode->spec & 0xffff0000) >> 16, | |
182 | + inode->spec & 0x0000ffff); | |
183 | +#endif | |
184 | + } else { | |
185 | +#ifdef DEBUG_ROMFS | |
186 | + printf (" %s %7d %12s 0x%08x 0x%08x", str, inode->size, | |
187 | + inode->name, inode, inode->spec); | |
188 | +#else | |
189 | + printf (" %s %7d %12s", str, inode->size, inode->name); | |
190 | +#endif | |
191 | + if (str[0] == 'l') { | |
192 | + data = (char *)((int)inode + HEADERSIZE (inode->name)); | |
193 | + puts (" -> "); | |
194 | + puts (data); | |
195 | + } | |
196 | + if (str[0] == 'h') { | |
197 | + hardlink = (struct romfs_inode *)(PART_OFFSET (info) + | |
198 | + inode->spec); | |
199 | + puts (" -> "); | |
200 | + puts (hardlink->name); | |
201 | + } | |
202 | + } | |
203 | + puts ("\n"); | |
204 | + return ALIGN (inode->next); | |
205 | +} | |
206 | + | |
207 | +int romfs_ls (struct part_info *info, char *filename) | |
208 | +{ | |
209 | + struct romfs_inode *inode; | |
210 | + unsigned long inodeoffset = 0, nextoffset; | |
211 | + unsigned long offset, size; | |
212 | + struct romfs_super *sb; | |
213 | + sb = (struct romfs_super *)PART_OFFSET (info); | |
214 | + | |
215 | + if (strlen (filename) == 0 || !strcmp (filename, "/")) { | |
216 | + offset = HEADERSIZE (sb->name); | |
217 | + size = sb->size; | |
218 | + } else { | |
219 | + offset = romfs_resolve (PART_OFFSET (info), | |
220 | + HEADERSIZE (sb->name), sb->size, 1, | |
221 | + strtok (filename, "/")); | |
222 | + | |
223 | + if (offset == 0) { | |
224 | + return offset; | |
225 | + } | |
226 | + inode = (struct romfs_inode *)(PART_OFFSET (info) + offset); | |
227 | + if ((inode->next & 0x7) != 1) { | |
228 | + return (romfs_list_inode (info, offset) > 0); | |
229 | + } | |
230 | + | |
231 | + size = sb->size; | |
232 | + offset = offset + HEADERSIZE (inode->name); | |
233 | + } | |
234 | + | |
235 | + inodeoffset = offset + inodeoffset; | |
236 | + while (inodeoffset < size) { | |
237 | + nextoffset = romfs_list_inode (info, inodeoffset); | |
238 | + if (nextoffset == 0) | |
239 | + break; | |
240 | + inodeoffset = nextoffset; | |
241 | + } | |
242 | + return 1; | |
243 | +} | |
244 | + | |
245 | +int romfs_info (struct part_info *info) | |
246 | +{ | |
247 | + struct romfs_super *sb; | |
248 | + sb = (struct romfs_super *)PART_OFFSET (info); | |
249 | + | |
250 | + printf ("name: \t\t%s, len %d B\n", sb->name, strlen (sb->name)); | |
251 | + printf ("size of SB:\t%d B\n", HEADERSIZE (sb->name)); | |
252 | + printf ("full size:\t%d B\n", sb->size); | |
253 | + printf ("checksum:\t0x%x\n", sb->checksum); | |
254 | + return 0; | |
255 | +} | |
256 | + | |
257 | +int romfs_check (struct part_info *info) | |
258 | +{ | |
259 | + struct romfs_super *sb; | |
260 | + if (info->dev->id->type != MTD_DEV_TYPE_NOR) | |
261 | + return 0; | |
262 | + | |
263 | + sb = (struct romfs_super *)PART_OFFSET (info); | |
264 | + if ((sb->word0 != 0x2D726F6D) || (sb->word1 != 0x3166732D)) { | |
265 | + return 0; | |
266 | + } | |
267 | + return 1; | |
268 | +} | |
269 | + | |
270 | +#endif |