1 2 #include <linux/kernel.h> 3 #include <linux/fs.h> 4 #include <linux/minix_fs.h> 5 #include <linux/ext2_fs.h> 6 #include <linux/romfs_fs.h> 7 #include <linux/cramfs_fs.h> 8 #include <linux/initrd.h> 9 #include <linux/string.h> 10 11 #include "do_mounts.h" 12 13 int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ 14 15 static int __init prompt_ramdisk(char *str) 16 { 17 rd_prompt = simple_strtol(str,NULL,0) & 1; 18 return 1; 19 } 20 __setup("prompt_ramdisk=", prompt_ramdisk); 21 22 int __initdata rd_image_start; /* starting block # of image */ 23 24 static int __init ramdisk_start_setup(char *str) 25 { 26 rd_image_start = simple_strtol(str,NULL,0); 27 return 1; 28 } 29 __setup("ramdisk_start=", ramdisk_start_setup); 30 31 static int __init crd_load(int in_fd, int out_fd); 32 33 /* 34 * This routine tries to find a RAM disk image to load, and returns the 35 * number of blocks to read for a non-compressed image, 0 if the image 36 * is a compressed image, and -1 if an image with the right magic 37 * numbers could not be found. 38 * 39 * We currently check for the following magic numbers: 40 * minix 41 * ext2 42 * romfs 43 * cramfs 44 * gzip 45 */ 46 static int __init 47 identify_ramdisk_image(int fd, int start_block) 48 { 49 const int size = 512; 50 struct minix_super_block *minixsb; 51 struct ext2_super_block *ext2sb; 52 struct romfs_super_block *romfsb; 53 struct cramfs_super *cramfsb; 54 int nblocks = -1; 55 unsigned char *buf; 56 57 buf = kmalloc(size, GFP_KERNEL); 58 if (!buf) 59 return -1; 60 61 minixsb = (struct minix_super_block *) buf; 62 ext2sb = (struct ext2_super_block *) buf; 63 romfsb = (struct romfs_super_block *) buf; 64 cramfsb = (struct cramfs_super *) buf; 65 memset(buf, 0xe5, size); 66 67 /* 68 * Read block 0 to test for gzipped kernel 69 */ 70 sys_lseek(fd, start_block * BLOCK_SIZE, 0); 71 sys_read(fd, buf, size); 72 73 /* 74 * If it matches the gzip magic numbers, return 0 75 */ 76 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) { 77 printk(KERN_NOTICE 78 "RAMDISK: Compressed image found at block %d\n", 79 start_block); 80 nblocks = 0; 81 goto done; 82 } 83 84 /* romfs is at block zero too */ 85 if (romfsb->word0 == ROMSB_WORD0 && 86 romfsb->word1 == ROMSB_WORD1) { 87 printk(KERN_NOTICE 88 "RAMDISK: romfs filesystem found at block %d\n", 89 start_block); 90 nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; 91 goto done; 92 } 93 94 if (cramfsb->magic == CRAMFS_MAGIC) { 95 printk(KERN_NOTICE 96 "RAMDISK: cramfs filesystem found at block %d\n", 97 start_block); 98 nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; 99 goto done; 100 } 101 102 /* 103 * Read block 1 to test for minix and ext2 superblock 104 */ 105 sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); 106 sys_read(fd, buf, size); 107 108 /* Try minix */ 109 if (minixsb->s_magic == MINIX_SUPER_MAGIC || 110 minixsb->s_magic == MINIX_SUPER_MAGIC2) { 111 printk(KERN_NOTICE 112 "RAMDISK: Minix filesystem found at block %d\n", 113 start_block); 114 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size; 115 goto done; 116 } 117 118 /* Try ext2 */ 119 if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { 120 printk(KERN_NOTICE 121 "RAMDISK: ext2 filesystem found at block %d\n", 122 start_block); 123 nblocks = le32_to_cpu(ext2sb->s_blocks_count) << 124 le32_to_cpu(ext2sb->s_log_block_size); 125 goto done; 126 } 127 128 printk(KERN_NOTICE 129 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", 130 start_block); 131 132 done: 133 sys_lseek(fd, start_block * BLOCK_SIZE, 0); 134 kfree(buf); 135 return nblocks; 136 } 137 138 int __init rd_load_image(char *from) 139 { 140 int res = 0; 141 int in_fd, out_fd; 142 unsigned long rd_blocks, devblocks; 143 int nblocks, i, disk; 144 char *buf = NULL; 145 unsigned short rotate = 0; 146 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) 147 char rotator[4] = { '|' , '/' , '-' , '\\' }; 148 #endif 149 150 out_fd = sys_open("/dev/ram", O_RDWR, 0); 151 if (out_fd < 0) 152 goto out; 153 154 in_fd = sys_open(from, O_RDONLY, 0); 155 if (in_fd < 0) 156 goto noclose_input; 157 158 nblocks = identify_ramdisk_image(in_fd, rd_image_start); 159 if (nblocks < 0) 160 goto done; 161 162 if (nblocks == 0) { 163 if (crd_load(in_fd, out_fd) == 0) 164 goto successful_load; 165 goto done; 166 } 167 168 /* 169 * NOTE NOTE: nblocks is not actually blocks but 170 * the number of kibibytes of data to load into a ramdisk. 171 * So any ramdisk block size that is a multiple of 1KiB should 172 * work when the appropriate ramdisk_blocksize is specified 173 * on the command line. 174 * 175 * The default ramdisk_blocksize is 1KiB and it is generally 176 * silly to use anything else, so make sure to use 1KiB 177 * blocksize while generating ext2fs ramdisk-images. 178 */ 179 if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) 180 rd_blocks = 0; 181 else 182 rd_blocks >>= 1; 183 184 if (nblocks > rd_blocks) { 185 printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n", 186 nblocks, rd_blocks); 187 goto done; 188 } 189 190 /* 191 * OK, time to copy in the data 192 */ 193 if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) 194 devblocks = 0; 195 else 196 devblocks >>= 1; 197 198 if (strcmp(from, "/initrd.image") == 0) 199 devblocks = nblocks; 200 201 if (devblocks == 0) { 202 printk(KERN_ERR "RAMDISK: could not determine device size\n"); 203 goto done; 204 } 205 206 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); 207 if (!buf) { 208 printk(KERN_ERR "RAMDISK: could not allocate buffer\n"); 209 goto done; 210 } 211 212 printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ", 213 nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); 214 for (i = 0, disk = 1; i < nblocks; i++) { 215 if (i && (i % devblocks == 0)) { 216 printk("done disk #%d.\n", disk++); 217 rotate = 0; 218 if (sys_close(in_fd)) { 219 printk("Error closing the disk.\n"); 220 goto noclose_input; 221 } 222 change_floppy("disk #%d", disk); 223 in_fd = sys_open(from, O_RDONLY, 0); 224 if (in_fd < 0) { 225 printk("Error opening disk.\n"); 226 goto noclose_input; 227 } 228 printk("Loading disk #%d... ", disk); 229 } 230 sys_read(in_fd, buf, BLOCK_SIZE); 231 sys_write(out_fd, buf, BLOCK_SIZE); 232 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) 233 if (!(i % 16)) { 234 printk("%c\b", rotator[rotate & 0x3]); 235 rotate++; 236 } 237 #endif 238 } 239 printk("done.\n"); 240 241 successful_load: 242 res = 1; 243 done: 244 sys_close(in_fd); 245 noclose_input: 246 sys_close(out_fd); 247 out: 248 kfree(buf); 249 sys_unlink("/dev/ram"); 250 return res; 251 } 252 253 int __init rd_load_disk(int n) 254 { 255 if (rd_prompt) 256 change_floppy("root floppy disk to be loaded into RAM disk"); 257 create_dev("/dev/root", ROOT_DEV); 258 create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n)); 259 return rd_load_image("/dev/root"); 260 } 261 262 /* 263 * gzip declarations 264 */ 265 266 #define OF(args) args 267 268 #ifndef memzero 269 #define memzero(s, n) memset ((s), 0, (n)) 270 #endif 271 272 typedef unsigned char uch; 273 typedef unsigned short ush; 274 typedef unsigned long ulg; 275 276 #define INBUFSIZ 4096 277 #define WSIZE 0x8000 /* window size--must be a power of two, and */ 278 /* at least 32K for zip's deflate method */ 279 280 static uch *inbuf; 281 static uch *window; 282 283 static unsigned insize; /* valid bytes in inbuf */ 284 static unsigned inptr; /* index of next byte to be processed in inbuf */ 285 static unsigned outcnt; /* bytes in output buffer */ 286 static int exit_code; 287 static int unzip_error; 288 static long bytes_out; 289 static int crd_infd, crd_outfd; 290 291 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) 292 293 /* Diagnostic functions (stubbed out) */ 294 #define Assert(cond,msg) 295 #define Trace(x) 296 #define Tracev(x) 297 #define Tracevv(x) 298 #define Tracec(c,x) 299 #define Tracecv(c,x) 300 301 #define STATIC static 302 #define INIT __init 303 304 static int __init fill_inbuf(void); 305 static void __init flush_window(void); 306 static void __init error(char *m); 307 308 #define NO_INFLATE_MALLOC 309 310 #include "../lib/inflate.c" 311 312 /* =========================================================================== 313 * Fill the input buffer. This is called only when the buffer is empty 314 * and at least one byte is really needed. 315 * Returning -1 does not guarantee that gunzip() will ever return. 316 */ 317 static int __init fill_inbuf(void) 318 { 319 if (exit_code) return -1; 320 321 insize = sys_read(crd_infd, inbuf, INBUFSIZ); 322 if (insize == 0) { 323 error("RAMDISK: ran out of compressed data"); 324 return -1; 325 } 326 327 inptr = 1; 328 329 return inbuf[0]; 330 } 331 332 /* =========================================================================== 333 * Write the output window window[0..outcnt-1] and update crc and bytes_out. 334 * (Used for the decompressed data only.) 335 */ 336 static void __init flush_window(void) 337 { 338 ulg c = crc; /* temporary variable */ 339 unsigned n, written; 340 uch *in, ch; 341 342 written = sys_write(crd_outfd, window, outcnt); 343 if (written != outcnt && unzip_error == 0) { 344 printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", 345 written, outcnt, bytes_out); 346 unzip_error = 1; 347 } 348 in = window; 349 for (n = 0; n < outcnt; n++) { 350 ch = *in++; 351 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); 352 } 353 crc = c; 354 bytes_out += (ulg)outcnt; 355 outcnt = 0; 356 } 357 358 static void __init error(char *x) 359 { 360 printk(KERN_ERR "%s\n", x); 361 exit_code = 1; 362 unzip_error = 1; 363 } 364 365 static int __init crd_load(int in_fd, int out_fd) 366 { 367 int result; 368 369 insize = 0; /* valid bytes in inbuf */ 370 inptr = 0; /* index of next byte to be processed in inbuf */ 371 outcnt = 0; /* bytes in output buffer */ 372 exit_code = 0; 373 bytes_out = 0; 374 crc = (ulg)0xffffffffL; /* shift register contents */ 375 376 crd_infd = in_fd; 377 crd_outfd = out_fd; 378 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); 379 if (!inbuf) { 380 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); 381 return -1; 382 } 383 window = kmalloc(WSIZE, GFP_KERNEL); 384 if (!window) { 385 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); 386 kfree(inbuf); 387 return -1; 388 } 389 makecrc(); 390 result = gunzip(); 391 if (unzip_error) 392 result = 1; 393 kfree(inbuf); 394 kfree(window); 395 return result; 396 } 397