1 // SPDX-License-Identifier: GPL-2.0 !! 1 2 #include <linux/kernel.h> 2 #include <linux/kernel.h> 3 #include <linux/fs.h> 3 #include <linux/fs.h> 4 #include <linux/minix_fs.h> 4 #include <linux/minix_fs.h> 5 #include <linux/ext2_fs.h> 5 #include <linux/ext2_fs.h> 6 #include <linux/romfs_fs.h> 6 #include <linux/romfs_fs.h> 7 #include <uapi/linux/cramfs_fs.h> !! 7 #include <linux/cramfs_fs.h> 8 #include <linux/initrd.h> 8 #include <linux/initrd.h> 9 #include <linux/string.h> 9 #include <linux/string.h> 10 #include <linux/slab.h> << 11 10 12 #include "do_mounts.h" 11 #include "do_mounts.h" 13 #include "../fs/squashfs/squashfs_fs.h" 12 #include "../fs/squashfs/squashfs_fs.h" 14 13 15 #include <linux/decompress/generic.h> 14 #include <linux/decompress/generic.h> 16 15 17 static struct file *in_file, *out_file; !! 16 18 static loff_t in_pos, out_pos; !! 17 int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ 19 18 20 static int __init prompt_ramdisk(char *str) 19 static int __init prompt_ramdisk(char *str) 21 { 20 { 22 pr_warn("ignoring the deprecated promp !! 21 rd_prompt = simple_strtol(str,NULL,0) & 1; 23 return 1; 22 return 1; 24 } 23 } 25 __setup("prompt_ramdisk=", prompt_ramdisk); 24 __setup("prompt_ramdisk=", prompt_ramdisk); 26 25 27 int __initdata rd_image_start; /* sta 26 int __initdata rd_image_start; /* starting block # of image */ 28 27 29 static int __init ramdisk_start_setup(char *st 28 static int __init ramdisk_start_setup(char *str) 30 { 29 { 31 rd_image_start = simple_strtol(str,NUL 30 rd_image_start = simple_strtol(str,NULL,0); 32 return 1; 31 return 1; 33 } 32 } 34 __setup("ramdisk_start=", ramdisk_start_setup) 33 __setup("ramdisk_start=", ramdisk_start_setup); 35 34 36 static int __init crd_load(decompress_fn deco) !! 35 static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); 37 36 38 /* 37 /* 39 * This routine tries to find a RAM disk image 38 * This routine tries to find a RAM disk image to load, and returns the 40 * number of blocks to read for a non-compress 39 * number of blocks to read for a non-compressed image, 0 if the image 41 * is a compressed image, and -1 if an image w 40 * is a compressed image, and -1 if an image with the right magic 42 * numbers could not be found. 41 * numbers could not be found. 43 * 42 * 44 * We currently check for the following magic 43 * We currently check for the following magic numbers: 45 * minix 44 * minix 46 * ext2 45 * ext2 47 * romfs 46 * romfs 48 * cramfs 47 * cramfs 49 * squashfs 48 * squashfs 50 * gzip 49 * gzip 51 * bzip2 << 52 * lzma << 53 * xz << 54 * lzo << 55 * lz4 << 56 */ 50 */ 57 static int __init 51 static int __init 58 identify_ramdisk_image(struct file *file, loff !! 52 identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) 59 decompress_fn *decompressor) << 60 { 53 { 61 const int size = 512; 54 const int size = 512; 62 struct minix_super_block *minixsb; 55 struct minix_super_block *minixsb; >> 56 struct ext2_super_block *ext2sb; 63 struct romfs_super_block *romfsb; 57 struct romfs_super_block *romfsb; 64 struct cramfs_super *cramfsb; 58 struct cramfs_super *cramfsb; 65 struct squashfs_super_block *squashfsb 59 struct squashfs_super_block *squashfsb; 66 int nblocks = -1; 60 int nblocks = -1; 67 unsigned char *buf; 61 unsigned char *buf; 68 const char *compress_name; 62 const char *compress_name; 69 unsigned long n; << 70 int start_block = rd_image_start; << 71 63 72 buf = kmalloc(size, GFP_KERNEL); 64 buf = kmalloc(size, GFP_KERNEL); 73 if (!buf) 65 if (!buf) 74 return -ENOMEM; !! 66 return -1; 75 67 76 minixsb = (struct minix_super_block *) 68 minixsb = (struct minix_super_block *) buf; >> 69 ext2sb = (struct ext2_super_block *) buf; 77 romfsb = (struct romfs_super_block *) 70 romfsb = (struct romfs_super_block *) buf; 78 cramfsb = (struct cramfs_super *) buf; 71 cramfsb = (struct cramfs_super *) buf; 79 squashfsb = (struct squashfs_super_blo 72 squashfsb = (struct squashfs_super_block *) buf; 80 memset(buf, 0xe5, size); 73 memset(buf, 0xe5, size); 81 74 82 /* 75 /* 83 * Read block 0 to test for compressed 76 * Read block 0 to test for compressed kernel 84 */ 77 */ 85 pos = start_block * BLOCK_SIZE; !! 78 sys_lseek(fd, start_block * BLOCK_SIZE, 0); 86 kernel_read(file, buf, size, &pos); !! 79 sys_read(fd, buf, size); 87 80 88 *decompressor = decompress_method(buf, 81 *decompressor = decompress_method(buf, size, &compress_name); 89 if (compress_name) { 82 if (compress_name) { 90 printk(KERN_NOTICE "RAMDISK: % 83 printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n", 91 compress_name, start_bl 84 compress_name, start_block); 92 if (!*decompressor) 85 if (!*decompressor) 93 printk(KERN_EMERG 86 printk(KERN_EMERG 94 "RAMDISK: %s de 87 "RAMDISK: %s decompressor not configured!\n", 95 compress_name); 88 compress_name); 96 nblocks = 0; 89 nblocks = 0; 97 goto done; 90 goto done; 98 } 91 } 99 92 100 /* romfs is at block zero too */ 93 /* romfs is at block zero too */ 101 if (romfsb->word0 == ROMSB_WORD0 && 94 if (romfsb->word0 == ROMSB_WORD0 && 102 romfsb->word1 == ROMSB_WORD1) { 95 romfsb->word1 == ROMSB_WORD1) { 103 printk(KERN_NOTICE 96 printk(KERN_NOTICE 104 "RAMDISK: romfs filesys 97 "RAMDISK: romfs filesystem found at block %d\n", 105 start_block); 98 start_block); 106 nblocks = (ntohl(romfsb->size) 99 nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; 107 goto done; 100 goto done; 108 } 101 } 109 102 110 if (cramfsb->magic == CRAMFS_MAGIC) { 103 if (cramfsb->magic == CRAMFS_MAGIC) { 111 printk(KERN_NOTICE 104 printk(KERN_NOTICE 112 "RAMDISK: cramfs filesy 105 "RAMDISK: cramfs filesystem found at block %d\n", 113 start_block); 106 start_block); 114 nblocks = (cramfsb->size + BLO 107 nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; 115 goto done; 108 goto done; 116 } 109 } 117 110 118 /* squashfs is at block zero too */ 111 /* squashfs is at block zero too */ 119 if (le32_to_cpu(squashfsb->s_magic) == 112 if (le32_to_cpu(squashfsb->s_magic) == SQUASHFS_MAGIC) { 120 printk(KERN_NOTICE 113 printk(KERN_NOTICE 121 "RAMDISK: squashfs file 114 "RAMDISK: squashfs filesystem found at block %d\n", 122 start_block); 115 start_block); 123 nblocks = (le64_to_cpu(squashf 116 nblocks = (le64_to_cpu(squashfsb->bytes_used) + BLOCK_SIZE - 1) 124 >> BLOCK_SIZE_BITS; 117 >> BLOCK_SIZE_BITS; 125 goto done; 118 goto done; 126 } 119 } 127 120 128 /* 121 /* 129 * Read 512 bytes further to check if << 130 */ << 131 pos = start_block * BLOCK_SIZE + 0x200 << 132 kernel_read(file, buf, size, &pos); << 133 << 134 if (cramfsb->magic == CRAMFS_MAGIC) { << 135 printk(KERN_NOTICE << 136 "RAMDISK: cramfs filesy << 137 start_block); << 138 nblocks = (cramfsb->size + BLO << 139 goto done; << 140 } << 141 << 142 /* << 143 * Read block 1 to test for minix and 122 * Read block 1 to test for minix and ext2 superblock 144 */ 123 */ 145 pos = (start_block + 1) * BLOCK_SIZE; !! 124 sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); 146 kernel_read(file, buf, size, &pos); !! 125 sys_read(fd, buf, size); 147 126 148 /* Try minix */ 127 /* Try minix */ 149 if (minixsb->s_magic == MINIX_SUPER_MA 128 if (minixsb->s_magic == MINIX_SUPER_MAGIC || 150 minixsb->s_magic == MINIX_SUPER_MA 129 minixsb->s_magic == MINIX_SUPER_MAGIC2) { 151 printk(KERN_NOTICE 130 printk(KERN_NOTICE 152 "RAMDISK: Minix filesys 131 "RAMDISK: Minix filesystem found at block %d\n", 153 start_block); 132 start_block); 154 nblocks = minixsb->s_nzones << 133 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size; 155 goto done; 134 goto done; 156 } 135 } 157 136 158 /* Try ext2 */ 137 /* Try ext2 */ 159 n = ext2_image_size(buf); !! 138 if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { 160 if (n) { << 161 printk(KERN_NOTICE 139 printk(KERN_NOTICE 162 "RAMDISK: ext2 filesyst 140 "RAMDISK: ext2 filesystem found at block %d\n", 163 start_block); 141 start_block); 164 nblocks = n; !! 142 nblocks = le32_to_cpu(ext2sb->s_blocks_count) << >> 143 le32_to_cpu(ext2sb->s_log_block_size); 165 goto done; 144 goto done; 166 } 145 } 167 146 168 printk(KERN_NOTICE 147 printk(KERN_NOTICE 169 "RAMDISK: Couldn't find valid R 148 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", 170 start_block); 149 start_block); 171 150 172 done: 151 done: >> 152 sys_lseek(fd, start_block * BLOCK_SIZE, 0); 173 kfree(buf); 153 kfree(buf); 174 return nblocks; 154 return nblocks; 175 } 155 } 176 156 177 static unsigned long nr_blocks(struct file *fi << 178 { << 179 struct inode *inode = file->f_mapping- << 180 << 181 if (!S_ISBLK(inode->i_mode)) << 182 return 0; << 183 return i_size_read(inode) >> 10; << 184 } << 185 << 186 int __init rd_load_image(char *from) 157 int __init rd_load_image(char *from) 187 { 158 { 188 int res = 0; 159 int res = 0; >> 160 int in_fd, out_fd; 189 unsigned long rd_blocks, devblocks; 161 unsigned long rd_blocks, devblocks; 190 int nblocks, i; !! 162 int nblocks, i, disk; 191 char *buf = NULL; 163 char *buf = NULL; 192 unsigned short rotate = 0; 164 unsigned short rotate = 0; 193 decompress_fn decompressor = NULL; 165 decompress_fn decompressor = NULL; 194 #if !defined(CONFIG_S390) !! 166 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) 195 char rotator[4] = { '|' , '/' , '-' , 167 char rotator[4] = { '|' , '/' , '-' , '\\' }; 196 #endif 168 #endif 197 169 198 out_file = filp_open("/dev/ram", O_RDW !! 170 out_fd = sys_open("/dev/ram", O_RDWR, 0); 199 if (IS_ERR(out_file)) !! 171 if (out_fd < 0) 200 goto out; 172 goto out; 201 173 202 in_file = filp_open(from, O_RDONLY, 0) !! 174 in_fd = sys_open(from, O_RDONLY, 0); 203 if (IS_ERR(in_file)) !! 175 if (in_fd < 0) 204 goto noclose_input; 176 goto noclose_input; 205 177 206 in_pos = rd_image_start * BLOCK_SIZE; !! 178 nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor); 207 nblocks = identify_ramdisk_image(in_fi << 208 if (nblocks < 0) 179 if (nblocks < 0) 209 goto done; 180 goto done; 210 181 211 if (nblocks == 0) { 182 if (nblocks == 0) { 212 if (crd_load(decompressor) == !! 183 if (crd_load(in_fd, out_fd, decompressor) == 0) 213 goto successful_load; 184 goto successful_load; 214 goto done; 185 goto done; 215 } 186 } 216 187 217 /* 188 /* 218 * NOTE NOTE: nblocks is not actually 189 * NOTE NOTE: nblocks is not actually blocks but 219 * the number of kibibytes of data to 190 * the number of kibibytes of data to load into a ramdisk. >> 191 * So any ramdisk block size that is a multiple of 1KiB should >> 192 * work when the appropriate ramdisk_blocksize is specified >> 193 * on the command line. >> 194 * >> 195 * The default ramdisk_blocksize is 1KiB and it is generally >> 196 * silly to use anything else, so make sure to use 1KiB >> 197 * blocksize while generating ext2fs ramdisk-images. 220 */ 198 */ 221 rd_blocks = nr_blocks(out_file); !! 199 if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) >> 200 rd_blocks = 0; >> 201 else >> 202 rd_blocks >>= 1; >> 203 222 if (nblocks > rd_blocks) { 204 if (nblocks > rd_blocks) { 223 printk("RAMDISK: image too big 205 printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n", 224 nblocks, rd_blocks); 206 nblocks, rd_blocks); 225 goto done; 207 goto done; 226 } 208 } 227 209 228 /* 210 /* 229 * OK, time to copy in the data 211 * OK, time to copy in the data 230 */ 212 */ >> 213 if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) >> 214 devblocks = 0; >> 215 else >> 216 devblocks >>= 1; >> 217 231 if (strcmp(from, "/initrd.image") == 0 218 if (strcmp(from, "/initrd.image") == 0) 232 devblocks = nblocks; 219 devblocks = nblocks; 233 else << 234 devblocks = nr_blocks(in_file) << 235 220 236 if (devblocks == 0) { 221 if (devblocks == 0) { 237 printk(KERN_ERR "RAMDISK: coul 222 printk(KERN_ERR "RAMDISK: could not determine device size\n"); 238 goto done; 223 goto done; 239 } 224 } 240 225 241 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); 226 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); 242 if (!buf) { 227 if (!buf) { 243 printk(KERN_ERR "RAMDISK: coul 228 printk(KERN_ERR "RAMDISK: could not allocate buffer\n"); 244 goto done; 229 goto done; 245 } 230 } 246 231 247 printk(KERN_NOTICE "RAMDISK: Loading % 232 printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ", 248 nblocks, ((nblocks-1)/devblock 233 nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); 249 for (i = 0; i < nblocks; i++) { !! 234 for (i = 0, disk = 1; i < nblocks; i++) { 250 if (i && (i % devblocks == 0)) 235 if (i && (i % devblocks == 0)) { 251 pr_cont("done disk #1. !! 236 printk("done disk #%d.\n", disk++); 252 rotate = 0; 237 rotate = 0; 253 fput(in_file); !! 238 if (sys_close(in_fd)) { 254 break; !! 239 printk("Error closing the disk.\n"); >> 240 goto noclose_input; >> 241 } >> 242 change_floppy("disk #%d", disk); >> 243 in_fd = sys_open(from, O_RDONLY, 0); >> 244 if (in_fd < 0) { >> 245 printk("Error opening disk.\n"); >> 246 goto noclose_input; >> 247 } >> 248 printk("Loading disk #%d... ", disk); 255 } 249 } 256 kernel_read(in_file, buf, BLOC !! 250 sys_read(in_fd, buf, BLOCK_SIZE); 257 kernel_write(out_file, buf, BL !! 251 sys_write(out_fd, buf, BLOCK_SIZE); 258 #if !defined(CONFIG_S390) !! 252 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) 259 if (!(i % 16)) { 253 if (!(i % 16)) { 260 pr_cont("%c\b", rotato !! 254 printk("%c\b", rotator[rotate & 0x3]); 261 rotate++; 255 rotate++; 262 } 256 } 263 #endif 257 #endif 264 } 258 } 265 pr_cont("done.\n"); !! 259 printk("done.\n"); 266 260 267 successful_load: 261 successful_load: 268 res = 1; 262 res = 1; 269 done: 263 done: 270 fput(in_file); !! 264 sys_close(in_fd); 271 noclose_input: 265 noclose_input: 272 fput(out_file); !! 266 sys_close(out_fd); 273 out: 267 out: 274 kfree(buf); 268 kfree(buf); 275 init_unlink("/dev/ram"); !! 269 sys_unlink("/dev/ram"); 276 return res; 270 return res; 277 } 271 } 278 272 279 int __init rd_load_disk(int n) 273 int __init rd_load_disk(int n) 280 { 274 { >> 275 if (rd_prompt) >> 276 change_floppy("root floppy disk to be loaded into RAM disk"); 281 create_dev("/dev/root", ROOT_DEV); 277 create_dev("/dev/root", ROOT_DEV); 282 create_dev("/dev/ram", MKDEV(RAMDISK_M 278 create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n)); 283 return rd_load_image("/dev/root"); 279 return rd_load_image("/dev/root"); 284 } 280 } 285 281 286 static int exit_code; 282 static int exit_code; 287 static int decompress_error; 283 static int decompress_error; >> 284 static int crd_infd, crd_outfd; 288 285 289 static long __init compr_fill(void *buf, unsig !! 286 static int __init compr_fill(void *buf, unsigned int len) 290 { 287 { 291 long r = kernel_read(in_file, buf, len !! 288 int r = sys_read(crd_infd, buf, len); 292 if (r < 0) 289 if (r < 0) 293 printk(KERN_ERR "RAMDISK: erro 290 printk(KERN_ERR "RAMDISK: error while reading compressed data"); 294 else if (r == 0) 291 else if (r == 0) 295 printk(KERN_ERR "RAMDISK: EOF 292 printk(KERN_ERR "RAMDISK: EOF while reading compressed data"); 296 return r; 293 return r; 297 } 294 } 298 295 299 static long __init compr_flush(void *window, u !! 296 static int __init compr_flush(void *window, unsigned int outcnt) 300 { 297 { 301 long written = kernel_write(out_file, !! 298 int written = sys_write(crd_outfd, window, outcnt); 302 if (written != outcnt) { 299 if (written != outcnt) { 303 if (decompress_error == 0) 300 if (decompress_error == 0) 304 printk(KERN_ERR 301 printk(KERN_ERR 305 "RAMDISK: incom !! 302 "RAMDISK: incomplete write (%d != %d)\n", 306 written, outcnt 303 written, outcnt); 307 decompress_error = 1; 304 decompress_error = 1; 308 return -1; 305 return -1; 309 } 306 } 310 return outcnt; 307 return outcnt; 311 } 308 } 312 309 313 static void __init error(char *x) 310 static void __init error(char *x) 314 { 311 { 315 printk(KERN_ERR "%s\n", x); 312 printk(KERN_ERR "%s\n", x); 316 exit_code = 1; 313 exit_code = 1; 317 decompress_error = 1; 314 decompress_error = 1; 318 } 315 } 319 316 320 static int __init crd_load(decompress_fn deco) !! 317 static int __init crd_load(int in_fd, int out_fd, decompress_fn deco) 321 { 318 { 322 int result; 319 int result; 323 !! 320 crd_infd = in_fd; 324 if (!deco) { !! 321 crd_outfd = out_fd; 325 pr_emerg("Invalid ramdisk deco << 326 "Select appropriate c << 327 panic("Could not decompress in << 328 } << 329 << 330 result = deco(NULL, 0, compr_fill, com 322 result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error); 331 if (decompress_error) 323 if (decompress_error) 332 result = 1; 324 result = 1; 333 return result; 325 return result; 334 } 326 } 335 327
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.