aboutsummaryrefslogtreecommitdiffstats
path: root/usr
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /usr
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'usr')
-rw-r--r--usr/Makefile65
-rw-r--r--usr/gen_init_cpio.c512
-rw-r--r--usr/initramfs_data.S30
3 files changed, 607 insertions, 0 deletions
diff --git a/usr/Makefile b/usr/Makefile
new file mode 100644
index 000000000000..248d5551029d
--- /dev/null
+++ b/usr/Makefile
@@ -0,0 +1,65 @@
1
2obj-y := initramfs_data.o
3
4hostprogs-y := gen_init_cpio
5
6clean-files := initramfs_data.cpio.gz initramfs_list
7
8# initramfs_data.o contains the initramfs_data.cpio.gz image.
9# The image is included using .incbin, a dependency which is not
10# tracked automatically.
11$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE
12
13ifdef CONFIG_INITRAMFS_ROOT_UID
14gen_initramfs_args += -u $(CONFIG_INITRAMFS_ROOT_UID)
15endif
16
17ifdef CONFIG_INITRAMFS_ROOT_GID
18gen_initramfs_args += -g $(CONFIG_INITRAMFS_ROOT_GID)
19endif
20
21# The $(shell echo $(CONFIG_INITRAMFS_SOURCE)) is to remove the
22# gratuitous begin and end quotes from the Kconfig string type.
23# Internal, escaped quotes in the Kconfig string will loose the
24# escape and become active quotes.
25quotefixed_initramfs_source := $(shell echo $(CONFIG_INITRAMFS_SOURCE))
26
27filechk_initramfs_list = $(CONFIG_SHELL) \
28 $(srctree)/scripts/gen_initramfs_list.sh $(gen_initramfs_args) $(quotefixed_initramfs_source)
29
30$(obj)/initramfs_list: FORCE
31 $(call filechk,initramfs_list)
32
33quiet_cmd_cpio = CPIO $@
34 cmd_cpio = ./$< $(obj)/initramfs_list > $@
35
36
37# Check if the INITRAMFS_SOURCE is a cpio archive
38ifneq (,$(findstring .cpio,$(quotefixed_initramfs_source)))
39
40# INITRAMFS_SOURCE has a cpio archive - verify that it's a single file
41ifneq (1,$(words $(quotefixed_initramfs_source)))
42$(error Only a single file may be specified in CONFIG_INITRAMFS_SOURCE (="$(quotefixed_initramfs_source)") when a cpio archive is directly specified.)
43endif
44# Now use the cpio archive directly
45initramfs_data_cpio = $(quotefixed_initramfs_source)
46targets += $(quotefixed_initramfs_source)
47
48else
49
50# INITRAMFS_SOURCE is not a cpio archive - create one
51$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio \
52 $(initramfs-y) $(obj)/initramfs_list FORCE
53 $(call if_changed,cpio)
54
55targets += initramfs_data.cpio
56initramfs_data_cpio = $(obj)/initramfs_data.cpio
57
58endif
59
60
61$(obj)/initramfs_data.cpio.gz: $(initramfs_data_cpio) FORCE
62 $(call if_changed,gzip)
63
64targets += initramfs_data.cpio.gz
65
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
new file mode 100644
index 000000000000..33dbcbf77c5b
--- /dev/null
+++ b/usr/gen_init_cpio.c
@@ -0,0 +1,512 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <string.h>
6#include <unistd.h>
7#include <time.h>
8#include <fcntl.h>
9#include <errno.h>
10#include <ctype.h>
11#include <limits.h>
12
13/*
14 * Original work by Jeff Garzik
15 *
16 * External file lists, symlink, pipe and fifo support by Thayne Harbaugh
17 */
18
19#define xstr(s) #s
20#define str(s) xstr(s)
21
22static unsigned int offset;
23static unsigned int ino = 721;
24
25struct file_handler {
26 const char *type;
27 int (*handler)(const char *line);
28};
29
30static void push_string(const char *name)
31{
32 unsigned int name_len = strlen(name) + 1;
33
34 fputs(name, stdout);
35 putchar(0);
36 offset += name_len;
37}
38
39static void push_pad (void)
40{
41 while (offset & 3) {
42 putchar(0);
43 offset++;
44 }
45}
46
47static void push_rest(const char *name)
48{
49 unsigned int name_len = strlen(name) + 1;
50 unsigned int tmp_ofs;
51
52 fputs(name, stdout);
53 putchar(0);
54 offset += name_len;
55
56 tmp_ofs = name_len + 110;
57 while (tmp_ofs & 3) {
58 putchar(0);
59 offset++;
60 tmp_ofs++;
61 }
62}
63
64static void push_hdr(const char *s)
65{
66 fputs(s, stdout);
67 offset += 110;
68}
69
70static void cpio_trailer(void)
71{
72 char s[256];
73 const char name[] = "TRAILER!!!";
74
75 sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX"
76 "%08X%08X%08X%08X%08X%08X%08X",
77 "070701", /* magic */
78 0, /* ino */
79 0, /* mode */
80 (long) 0, /* uid */
81 (long) 0, /* gid */
82 1, /* nlink */
83 (long) 0, /* mtime */
84 0, /* filesize */
85 0, /* major */
86 0, /* minor */
87 0, /* rmajor */
88 0, /* rminor */
89 (unsigned)strlen(name)+1, /* namesize */
90 0); /* chksum */
91 push_hdr(s);
92 push_rest(name);
93
94 while (offset % 512) {
95 putchar(0);
96 offset++;
97 }
98}
99
100static int cpio_mkslink(const char *name, const char *target,
101 unsigned int mode, uid_t uid, gid_t gid)
102{
103 char s[256];
104 time_t mtime = time(NULL);
105
106 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
107 "%08X%08X%08X%08X%08X%08X%08X",
108 "070701", /* magic */
109 ino++, /* ino */
110 S_IFLNK | mode, /* mode */
111 (long) uid, /* uid */
112 (long) gid, /* gid */
113 1, /* nlink */
114 (long) mtime, /* mtime */
115 (unsigned)strlen(target)+1, /* filesize */
116 3, /* major */
117 1, /* minor */
118 0, /* rmajor */
119 0, /* rminor */
120 (unsigned)strlen(name) + 1,/* namesize */
121 0); /* chksum */
122 push_hdr(s);
123 push_string(name);
124 push_pad();
125 push_string(target);
126 push_pad();
127 return 0;
128}
129
130static int cpio_mkslink_line(const char *line)
131{
132 char name[PATH_MAX + 1];
133 char target[PATH_MAX + 1];
134 unsigned int mode;
135 int uid;
136 int gid;
137 int rc = -1;
138
139 if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, target, &mode, &uid, &gid)) {
140 fprintf(stderr, "Unrecognized dir format '%s'", line);
141 goto fail;
142 }
143 rc = cpio_mkslink(name, target, mode, uid, gid);
144 fail:
145 return rc;
146}
147
148static int cpio_mkgeneric(const char *name, unsigned int mode,
149 uid_t uid, gid_t gid)
150{
151 char s[256];
152 time_t mtime = time(NULL);
153
154 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
155 "%08X%08X%08X%08X%08X%08X%08X",
156 "070701", /* magic */
157 ino++, /* ino */
158 mode, /* mode */
159 (long) uid, /* uid */
160 (long) gid, /* gid */
161 2, /* nlink */
162 (long) mtime, /* mtime */
163 0, /* filesize */
164 3, /* major */
165 1, /* minor */
166 0, /* rmajor */
167 0, /* rminor */
168 (unsigned)strlen(name) + 1,/* namesize */
169 0); /* chksum */
170 push_hdr(s);
171 push_rest(name);
172 return 0;
173}
174
175enum generic_types {
176 GT_DIR,
177 GT_PIPE,
178 GT_SOCK
179};
180
181struct generic_type {
182 const char *type;
183 mode_t mode;
184};
185
186static struct generic_type generic_type_table[] = {
187 [GT_DIR] = {
188 .type = "dir",
189 .mode = S_IFDIR
190 },
191 [GT_PIPE] = {
192 .type = "pipe",
193 .mode = S_IFIFO
194 },
195 [GT_SOCK] = {
196 .type = "sock",
197 .mode = S_IFSOCK
198 }
199};
200
201static int cpio_mkgeneric_line(const char *line, enum generic_types gt)
202{
203 char name[PATH_MAX + 1];
204 unsigned int mode;
205 int uid;
206 int gid;
207 int rc = -1;
208
209 if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) {
210 fprintf(stderr, "Unrecognized %s format '%s'",
211 line, generic_type_table[gt].type);
212 goto fail;
213 }
214 mode |= generic_type_table[gt].mode;
215 rc = cpio_mkgeneric(name, mode, uid, gid);
216 fail:
217 return rc;
218}
219
220static int cpio_mkdir_line(const char *line)
221{
222 return cpio_mkgeneric_line(line, GT_DIR);
223}
224
225static int cpio_mkpipe_line(const char *line)
226{
227 return cpio_mkgeneric_line(line, GT_PIPE);
228}
229
230static int cpio_mksock_line(const char *line)
231{
232 return cpio_mkgeneric_line(line, GT_SOCK);
233}
234
235static int cpio_mknod(const char *name, unsigned int mode,
236 uid_t uid, gid_t gid, char dev_type,
237 unsigned int maj, unsigned int min)
238{
239 char s[256];
240 time_t mtime = time(NULL);
241
242 if (dev_type == 'b')
243 mode |= S_IFBLK;
244 else
245 mode |= S_IFCHR;
246
247 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
248 "%08X%08X%08X%08X%08X%08X%08X",
249 "070701", /* magic */
250 ino++, /* ino */
251 mode, /* mode */
252 (long) uid, /* uid */
253 (long) gid, /* gid */
254 1, /* nlink */
255 (long) mtime, /* mtime */
256 0, /* filesize */
257 3, /* major */
258 1, /* minor */
259 maj, /* rmajor */
260 min, /* rminor */
261 (unsigned)strlen(name) + 1,/* namesize */
262 0); /* chksum */
263 push_hdr(s);
264 push_rest(name);
265 return 0;
266}
267
268static int cpio_mknod_line(const char *line)
269{
270 char name[PATH_MAX + 1];
271 unsigned int mode;
272 int uid;
273 int gid;
274 char dev_type;
275 unsigned int maj;
276 unsigned int min;
277 int rc = -1;
278
279 if (7 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d %c %u %u",
280 name, &mode, &uid, &gid, &dev_type, &maj, &min)) {
281 fprintf(stderr, "Unrecognized nod format '%s'", line);
282 goto fail;
283 }
284 rc = cpio_mknod(name, mode, uid, gid, dev_type, maj, min);
285 fail:
286 return rc;
287}
288
289/* Not marked static to keep the compiler quiet, as no one uses this yet... */
290static int cpio_mkfile(const char *name, const char *location,
291 unsigned int mode, uid_t uid, gid_t gid)
292{
293 char s[256];
294 char *filebuf = NULL;
295 struct stat buf;
296 int file = -1;
297 int retval;
298 int rc = -1;
299
300 mode |= S_IFREG;
301
302 retval = stat (location, &buf);
303 if (retval) {
304 fprintf (stderr, "File %s could not be located\n", location);
305 goto error;
306 }
307
308 file = open (location, O_RDONLY);
309 if (file < 0) {
310 fprintf (stderr, "File %s could not be opened for reading\n", location);
311 goto error;
312 }
313
314 filebuf = malloc(buf.st_size);
315 if (!filebuf) {
316 fprintf (stderr, "out of memory\n");
317 goto error;
318 }
319
320 retval = read (file, filebuf, buf.st_size);
321 if (retval < 0) {
322 fprintf (stderr, "Can not read %s file\n", location);
323 goto error;
324 }
325
326 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
327 "%08X%08X%08X%08X%08X%08X%08X",
328 "070701", /* magic */
329 ino++, /* ino */
330 mode, /* mode */
331 (long) uid, /* uid */
332 (long) gid, /* gid */
333 1, /* nlink */
334 (long) buf.st_mtime, /* mtime */
335 (int) buf.st_size, /* filesize */
336 3, /* major */
337 1, /* minor */
338 0, /* rmajor */
339 0, /* rminor */
340 (unsigned)strlen(name) + 1,/* namesize */
341 0); /* chksum */
342 push_hdr(s);
343 push_string(name);
344 push_pad();
345
346 fwrite(filebuf, buf.st_size, 1, stdout);
347 offset += buf.st_size;
348 push_pad();
349 rc = 0;
350
351error:
352 if (filebuf) free(filebuf);
353 if (file >= 0) close(file);
354 return rc;
355}
356
357static int cpio_mkfile_line(const char *line)
358{
359 char name[PATH_MAX + 1];
360 char location[PATH_MAX + 1];
361 unsigned int mode;
362 int uid;
363 int gid;
364 int rc = -1;
365
366 if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, location, &mode, &uid, &gid)) {
367 fprintf(stderr, "Unrecognized file format '%s'", line);
368 goto fail;
369 }
370 rc = cpio_mkfile(name, location, mode, uid, gid);
371 fail:
372 return rc;
373}
374
375void usage(const char *prog)
376{
377 fprintf(stderr, "Usage:\n"
378 "\t%s <cpio_list>\n"
379 "\n"
380 "<cpio_list> is a file containing newline separated entries that\n"
381 "describe the files to be included in the initramfs archive:\n"
382 "\n"
383 "# a comment\n"
384 "file <name> <location> <mode> <uid> <gid>\n"
385 "dir <name> <mode> <uid> <gid>\n"
386 "nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n"
387 "slink <name> <target> <mode> <uid> <gid>\n"
388 "pipe <name> <mode> <uid> <gid>\n"
389 "sock <name> <mode> <uid> <gid>\n"
390 "\n"
391 "<name> name of the file/dir/nod/etc in the archive\n"
392 "<location> location of the file in the current filesystem\n"
393 "<target> link target\n"
394 "<mode> mode/permissions of the file\n"
395 "<uid> user id (0=root)\n"
396 "<gid> group id (0=root)\n"
397 "<dev_type> device type (b=block, c=character)\n"
398 "<maj> major number of nod\n"
399 "<min> minor number of nod\n"
400 "\n"
401 "example:\n"
402 "# A simple initramfs\n"
403 "dir /dev 0755 0 0\n"
404 "nod /dev/console 0600 0 0 c 5 1\n"
405 "dir /root 0700 0 0\n"
406 "dir /sbin 0755 0 0\n"
407 "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n",
408 prog);
409}
410
411struct file_handler file_handler_table[] = {
412 {
413 .type = "file",
414 .handler = cpio_mkfile_line,
415 }, {
416 .type = "nod",
417 .handler = cpio_mknod_line,
418 }, {
419 .type = "dir",
420 .handler = cpio_mkdir_line,
421 }, {
422 .type = "slink",
423 .handler = cpio_mkslink_line,
424 }, {
425 .type = "pipe",
426 .handler = cpio_mkpipe_line,
427 }, {
428 .type = "sock",
429 .handler = cpio_mksock_line,
430 }, {
431 .type = NULL,
432 .handler = NULL,
433 }
434};
435
436#define LINE_SIZE (2 * PATH_MAX + 50)
437
438int main (int argc, char *argv[])
439{
440 FILE *cpio_list;
441 char line[LINE_SIZE];
442 char *args, *type;
443 int ec = 0;
444 int line_nr = 0;
445
446 if (2 != argc) {
447 usage(argv[0]);
448 exit(1);
449 }
450
451 if (! (cpio_list = fopen(argv[1], "r"))) {
452 fprintf(stderr, "ERROR: unable to open '%s': %s\n\n",
453 argv[1], strerror(errno));
454 usage(argv[0]);
455 exit(1);
456 }
457
458 while (fgets(line, LINE_SIZE, cpio_list)) {
459 int type_idx;
460 size_t slen = strlen(line);
461
462 line_nr++;
463
464 if ('#' == *line) {
465 /* comment - skip to next line */
466 continue;
467 }
468
469 if (! (type = strtok(line, " \t"))) {
470 fprintf(stderr,
471 "ERROR: incorrect format, could not locate file type line %d: '%s'\n",
472 line_nr, line);
473 ec = -1;
474 }
475
476 if ('\n' == *type) {
477 /* a blank line */
478 continue;
479 }
480
481 if (slen == strlen(type)) {
482 /* must be an empty line */
483 continue;
484 }
485
486 if (! (args = strtok(NULL, "\n"))) {
487 fprintf(stderr,
488 "ERROR: incorrect format, newline required line %d: '%s'\n",
489 line_nr, line);
490 ec = -1;
491 }
492
493 for (type_idx = 0; file_handler_table[type_idx].type; type_idx++) {
494 int rc;
495 if (! strcmp(line, file_handler_table[type_idx].type)) {
496 if ((rc = file_handler_table[type_idx].handler(args))) {
497 ec = rc;
498 fprintf(stderr, " line %d\n", line_nr);
499 }
500 break;
501 }
502 }
503
504 if (NULL == file_handler_table[type_idx].type) {
505 fprintf(stderr, "unknown file type line %d: '%s'\n",
506 line_nr, line);
507 }
508 }
509 cpio_trailer();
510
511 exit(ec);
512}
diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S
new file mode 100644
index 000000000000..c2e1ad424f4a
--- /dev/null
+++ b/usr/initramfs_data.S
@@ -0,0 +1,30 @@
1/*
2 initramfs_data includes the compressed binary that is the
3 filesystem used for early user space.
4 Note: Older versions of "as" (prior to binutils 2.11.90.0.23
5 released on 2001-07-14) dit not support .incbin.
6 If you are forced to use older binutils than that then the
7 following trick can be applied to create the resulting binary:
8
9
10 ld -m elf_i386 --format binary --oformat elf32-i386 -r \
11 -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
12 ld -m elf_i386 -r -o built-in.o initramfs_data.o
13
14 initramfs_data.scr looks like this:
15SECTIONS
16{
17 .init.ramfs : { *(.data) }
18}
19
20 The above example is for i386 - the parameters vary from architectures.
21 Eventually look up LDFLAGS_BLOB in an older version of the
22 arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
23
24 Using .incbin has the advantage over ld that the correct flags are set
25 in the ELF header, as required by certain architectures.
26*/
27
28.section .init.ramfs,"a"
29.incbin "usr/initramfs_data.cpio.gz"
30