Commit | Line | Data |
---|---|---|
9b67a3c4 | 1 | /* |
0983a88b | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
9b67a3c4 JD |
3 | * Licensed under the GPL |
4 | */ | |
5 | ||
6 | #include "linux/init.h" | |
7 | #include "linux/bootmem.h" | |
8 | #include "linux/initrd.h" | |
9 | #include "asm/types.h" | |
9b67a3c4 JD |
10 | #include "init.h" |
11 | #include "os.h" | |
12 | ||
13 | /* Changed by uml_initrd_setup, which is a setup */ | |
14 | static char *initrd __initdata = NULL; | |
549e78db | 15 | static int load_initrd(char *filename, void *buf, int size); |
9b67a3c4 JD |
16 | |
17 | static int __init read_initrd(void) | |
18 | { | |
19 | void *area; | |
20 | long long size; | |
21 | int err; | |
22 | ||
0983a88b | 23 | if (initrd == NULL) |
dc764e50 JD |
24 | return 0; |
25 | ||
9b67a3c4 | 26 | err = os_file_size(initrd, &size); |
0983a88b | 27 | if (err) |
dc764e50 JD |
28 | return 0; |
29 | ||
0983a88b JD |
30 | /* |
31 | * This is necessary because alloc_bootmem craps out if you | |
32 | * ask for no memory. | |
33 | */ | |
34 | if (size == 0) { | |
4631a9a1 | 35 | printk(KERN_ERR "\"%s\" is a zero-size initrd\n", initrd); |
0983a88b JD |
36 | return 0; |
37 | } | |
38 | ||
9b67a3c4 | 39 | area = alloc_bootmem(size); |
0983a88b | 40 | if (area == NULL) |
dc764e50 JD |
41 | return 0; |
42 | ||
0983a88b | 43 | if (load_initrd(initrd, area, size) == -1) |
dc764e50 JD |
44 | return 0; |
45 | ||
9b67a3c4 JD |
46 | initrd_start = (unsigned long) area; |
47 | initrd_end = initrd_start + size; | |
48 | return 0; | |
49 | } | |
50 | ||
51 | __uml_postsetup(read_initrd); | |
52 | ||
53 | static int __init uml_initrd_setup(char *line, int *add) | |
54 | { | |
55 | initrd = line; | |
56 | return 0; | |
57 | } | |
58 | ||
59 | __uml_setup("initrd=", uml_initrd_setup, | |
60 | "initrd=<initrd image>\n" | |
61 | " This is used to boot UML from an initrd image. The argument is the\n" | |
62 | " name of the file containing the image.\n\n" | |
63 | ); | |
64 | ||
549e78db | 65 | static int load_initrd(char *filename, void *buf, int size) |
9b67a3c4 JD |
66 | { |
67 | int fd, n; | |
68 | ||
69 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); | |
0983a88b JD |
70 | if (fd < 0) { |
71 | printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename, | |
72 | -fd); | |
dc764e50 | 73 | return -1; |
9b67a3c4 | 74 | } |
a6ea4cce | 75 | n = os_read_file(fd, buf, size); |
0983a88b JD |
76 | if (n != size) { |
77 | printk(KERN_ERR "Read of %d bytes from '%s' failed, " | |
78 | "err = %d\n", size, | |
9b67a3c4 | 79 | filename, -n); |
dc764e50 | 80 | return -1; |
9b67a3c4 JD |
81 | } |
82 | ||
83 | os_close_file(fd); | |
dc764e50 | 84 | return 0; |
9b67a3c4 | 85 | } |