xref: /openbmc/linux/init/do_mounts_rd.c (revision addee42a)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Many of the syscalls used in this file expect some of the arguments
4  * to be __user pointers not __kernel pointers.  To limit the sparse
5  * noise, turn off sparse checking for this file.
6  */
7 #ifdef __CHECKER__
8 #undef __CHECKER__
9 #warning "Sparse checking disabled for this file"
10 #endif
11 
12 #include <linux/kernel.h>
13 #include <linux/fs.h>
14 #include <linux/minix_fs.h>
15 #include <linux/ext2_fs.h>
16 #include <linux/romfs_fs.h>
17 #include <uapi/linux/cramfs_fs.h>
18 #include <linux/initrd.h>
19 #include <linux/string.h>
20 #include <linux/slab.h>
21 
22 #include "do_mounts.h"
23 #include "../fs/squashfs/squashfs_fs.h"
24 
25 #include <linux/decompress/generic.h>
26 
27 
28 int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
29 
30 static int __init prompt_ramdisk(char *str)
31 {
32 	rd_prompt = simple_strtol(str,NULL,0) & 1;
33 	return 1;
34 }
35 __setup("prompt_ramdisk=", prompt_ramdisk);
36 
37 int __initdata rd_image_start;		/* starting block # of image */
38 
39 static int __init ramdisk_start_setup(char *str)
40 {
41 	rd_image_start = simple_strtol(str,NULL,0);
42 	return 1;
43 }
44 __setup("ramdisk_start=", ramdisk_start_setup);
45 
46 static int __init crd_load(int in_fd, int out_fd, decompress_fn deco);
47 
48 /*
49  * This routine tries to find a RAM disk image to load, and returns the
50  * number of blocks to read for a non-compressed image, 0 if the image
51  * is a compressed image, and -1 if an image with the right magic
52  * numbers could not be found.
53  *
54  * We currently check for the following magic numbers:
55  *	minix
56  *	ext2
57  *	romfs
58  *	cramfs
59  *	squashfs
60  *	gzip
61  *	bzip2
62  *	lzma
63  *	xz
64  *	lzo
65  *	lz4
66  */
67 static int __init
68 identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor)
69 {
70 	const int size = 512;
71 	struct minix_super_block *minixsb;
72 	struct romfs_super_block *romfsb;
73 	struct cramfs_super *cramfsb;
74 	struct squashfs_super_block *squashfsb;
75 	int nblocks = -1;
76 	unsigned char *buf;
77 	const char *compress_name;
78 	unsigned long n;
79 
80 	buf = kmalloc(size, GFP_KERNEL);
81 	if (!buf)
82 		return -ENOMEM;
83 
84 	minixsb = (struct minix_super_block *) buf;
85 	romfsb = (struct romfs_super_block *) buf;
86 	cramfsb = (struct cramfs_super *) buf;
87 	squashfsb = (struct squashfs_super_block *) buf;
88 	memset(buf, 0xe5, size);
89 
90 	/*
91 	 * Read block 0 to test for compressed kernel
92 	 */
93 	ksys_lseek(fd, start_block * BLOCK_SIZE, 0);
94 	ksys_read(fd, buf, size);
95 
96 	*decompressor = decompress_method(buf, size, &compress_name);
97 	if (compress_name) {
98 		printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n",
99 		       compress_name, start_block);
100 		if (!*decompressor)
101 			printk(KERN_EMERG
102 			       "RAMDISK: %s decompressor not configured!\n",
103 			       compress_name);
104 		nblocks = 0;
105 		goto done;
106 	}
107 
108 	/* romfs is at block zero too */
109 	if (romfsb->word0 == ROMSB_WORD0 &&
110 	    romfsb->word1 == ROMSB_WORD1) {
111 		printk(KERN_NOTICE
112 		       "RAMDISK: romfs filesystem found at block %d\n",
113 		       start_block);
114 		nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
115 		goto done;
116 	}
117 
118 	if (cramfsb->magic == CRAMFS_MAGIC) {
119 		printk(KERN_NOTICE
120 		       "RAMDISK: cramfs filesystem found at block %d\n",
121 		       start_block);
122 		nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
123 		goto done;
124 	}
125 
126 	/* squashfs is at block zero too */
127 	if (le32_to_cpu(squashfsb->s_magic) == SQUASHFS_MAGIC) {
128 		printk(KERN_NOTICE
129 		       "RAMDISK: squashfs filesystem found at block %d\n",
130 		       start_block);
131 		nblocks = (le64_to_cpu(squashfsb->bytes_used) + BLOCK_SIZE - 1)
132 			 >> BLOCK_SIZE_BITS;
133 		goto done;
134 	}
135 
136 	/*
137 	 * Read 512 bytes further to check if cramfs is padded
138 	 */
139 	ksys_lseek(fd, start_block * BLOCK_SIZE + 0x200, 0);
140 	ksys_read(fd, buf, size);
141 
142 	if (cramfsb->magic == CRAMFS_MAGIC) {
143 		printk(KERN_NOTICE
144 		       "RAMDISK: cramfs filesystem found at block %d\n",
145 		       start_block);
146 		nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
147 		goto done;
148 	}
149 
150 	/*
151 	 * Read block 1 to test for minix and ext2 superblock
152 	 */
153 	ksys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
154 	ksys_read(fd, buf, size);
155 
156 	/* Try minix */
157 	if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
158 	    minixsb->s_magic == MINIX_SUPER_MAGIC2) {
159 		printk(KERN_NOTICE
160 		       "RAMDISK: Minix filesystem found at block %d\n",
161 		       start_block);
162 		nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
163 		goto done;
164 	}
165 
166 	/* Try ext2 */
167 	n = ext2_image_size(buf);
168 	if (n) {
169 		printk(KERN_NOTICE
170 		       "RAMDISK: ext2 filesystem found at block %d\n",
171 		       start_block);
172 		nblocks = n;
173 		goto done;
174 	}
175 
176 	printk(KERN_NOTICE
177 	       "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
178 	       start_block);
179 
180 done:
181 	ksys_lseek(fd, start_block * BLOCK_SIZE, 0);
182 	kfree(buf);
183 	return nblocks;
184 }
185 
186 int __init rd_load_image(char *from)
187 {
188 	int res = 0;
189 	int in_fd, out_fd;
190 	unsigned long rd_blocks, devblocks;
191 	int nblocks, i, disk;
192 	char *buf = NULL;
193 	unsigned short rotate = 0;
194 	decompress_fn decompressor = NULL;
195 #if !defined(CONFIG_S390)
196 	char rotator[4] = { '|' , '/' , '-' , '\\' };
197 #endif
198 
199 	out_fd = ksys_open("/dev/ram", O_RDWR, 0);
200 	if (out_fd < 0)
201 		goto out;
202 
203 	in_fd = ksys_open(from, O_RDONLY, 0);
204 	if (in_fd < 0)
205 		goto noclose_input;
206 
207 	nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor);
208 	if (nblocks < 0)
209 		goto done;
210 
211 	if (nblocks == 0) {
212 		if (crd_load(in_fd, out_fd, decompressor) == 0)
213 			goto successful_load;
214 		goto done;
215 	}
216 
217 	/*
218 	 * NOTE NOTE: nblocks is not actually blocks but
219 	 * the number of kibibytes of data to load into a ramdisk.
220 	 */
221 	if (ksys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
222 		rd_blocks = 0;
223 	else
224 		rd_blocks >>= 1;
225 
226 	if (nblocks > rd_blocks) {
227 		printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n",
228 		       nblocks, rd_blocks);
229 		goto done;
230 	}
231 
232 	/*
233 	 * OK, time to copy in the data
234 	 */
235 	if (ksys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
236 		devblocks = 0;
237 	else
238 		devblocks >>= 1;
239 
240 	if (strcmp(from, "/initrd.image") == 0)
241 		devblocks = nblocks;
242 
243 	if (devblocks == 0) {
244 		printk(KERN_ERR "RAMDISK: could not determine device size\n");
245 		goto done;
246 	}
247 
248 	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
249 	if (!buf) {
250 		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
251 		goto done;
252 	}
253 
254 	printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
255 		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
256 	for (i = 0, disk = 1; i < nblocks; i++) {
257 		if (i && (i % devblocks == 0)) {
258 			pr_cont("done disk #%d.\n", disk++);
259 			rotate = 0;
260 			if (ksys_close(in_fd)) {
261 				printk("Error closing the disk.\n");
262 				goto noclose_input;
263 			}
264 			change_floppy("disk #%d", disk);
265 			in_fd = ksys_open(from, O_RDONLY, 0);
266 			if (in_fd < 0)  {
267 				printk("Error opening disk.\n");
268 				goto noclose_input;
269 			}
270 			printk("Loading disk #%d... ", disk);
271 		}
272 		ksys_read(in_fd, buf, BLOCK_SIZE);
273 		ksys_write(out_fd, buf, BLOCK_SIZE);
274 #if !defined(CONFIG_S390)
275 		if (!(i % 16)) {
276 			pr_cont("%c\b", rotator[rotate & 0x3]);
277 			rotate++;
278 		}
279 #endif
280 	}
281 	pr_cont("done.\n");
282 
283 successful_load:
284 	res = 1;
285 done:
286 	ksys_close(in_fd);
287 noclose_input:
288 	ksys_close(out_fd);
289 out:
290 	kfree(buf);
291 	ksys_unlink("/dev/ram");
292 	return res;
293 }
294 
295 int __init rd_load_disk(int n)
296 {
297 	if (rd_prompt)
298 		change_floppy("root floppy disk to be loaded into RAM disk");
299 	create_dev("/dev/root", ROOT_DEV);
300 	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
301 	return rd_load_image("/dev/root");
302 }
303 
304 static int exit_code;
305 static int decompress_error;
306 static int crd_infd, crd_outfd;
307 
308 static long __init compr_fill(void *buf, unsigned long len)
309 {
310 	long r = ksys_read(crd_infd, buf, len);
311 	if (r < 0)
312 		printk(KERN_ERR "RAMDISK: error while reading compressed data");
313 	else if (r == 0)
314 		printk(KERN_ERR "RAMDISK: EOF while reading compressed data");
315 	return r;
316 }
317 
318 static long __init compr_flush(void *window, unsigned long outcnt)
319 {
320 	long written = ksys_write(crd_outfd, window, outcnt);
321 	if (written != outcnt) {
322 		if (decompress_error == 0)
323 			printk(KERN_ERR
324 			       "RAMDISK: incomplete write (%ld != %ld)\n",
325 			       written, outcnt);
326 		decompress_error = 1;
327 		return -1;
328 	}
329 	return outcnt;
330 }
331 
332 static void __init error(char *x)
333 {
334 	printk(KERN_ERR "%s\n", x);
335 	exit_code = 1;
336 	decompress_error = 1;
337 }
338 
339 static int __init crd_load(int in_fd, int out_fd, decompress_fn deco)
340 {
341 	int result;
342 	crd_infd = in_fd;
343 	crd_outfd = out_fd;
344 
345 	if (!deco) {
346 		pr_emerg("Invalid ramdisk decompression routine.  "
347 			 "Select appropriate config option.\n");
348 		panic("Could not decompress initial ramdisk image.");
349 	}
350 
351 	result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error);
352 	if (decompress_error)
353 		result = 1;
354 	return result;
355 }
356