Back to home page

LXR

 
 

    


0001 /*
0002  * Many of the syscalls used in this file expect some of the arguments
0003  * to be __user pointers not __kernel pointers.  To limit the sparse
0004  * noise, turn off sparse checking for this file.
0005  */
0006 #ifdef __CHECKER__
0007 #undef __CHECKER__
0008 #warning "Sparse checking disabled for this file"
0009 #endif
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/fs.h>
0013 #include <linux/minix_fs.h>
0014 #include <linux/ext2_fs.h>
0015 #include <linux/romfs_fs.h>
0016 #include <uapi/linux/cramfs_fs.h>
0017 #include <linux/initrd.h>
0018 #include <linux/string.h>
0019 #include <linux/slab.h>
0020 
0021 #include "do_mounts.h"
0022 #include "../fs/squashfs/squashfs_fs.h"
0023 
0024 #include <linux/decompress/generic.h>
0025 
0026 
0027 int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
0028 
0029 static int __init prompt_ramdisk(char *str)
0030 {
0031     rd_prompt = simple_strtol(str,NULL,0) & 1;
0032     return 1;
0033 }
0034 __setup("prompt_ramdisk=", prompt_ramdisk);
0035 
0036 int __initdata rd_image_start;      /* starting block # of image */
0037 
0038 static int __init ramdisk_start_setup(char *str)
0039 {
0040     rd_image_start = simple_strtol(str,NULL,0);
0041     return 1;
0042 }
0043 __setup("ramdisk_start=", ramdisk_start_setup);
0044 
0045 static int __init crd_load(int in_fd, int out_fd, decompress_fn deco);
0046 
0047 /*
0048  * This routine tries to find a RAM disk image to load, and returns the
0049  * number of blocks to read for a non-compressed image, 0 if the image
0050  * is a compressed image, and -1 if an image with the right magic
0051  * numbers could not be found.
0052  *
0053  * We currently check for the following magic numbers:
0054  *  minix
0055  *  ext2
0056  *  romfs
0057  *  cramfs
0058  *  squashfs
0059  *  gzip
0060  *  bzip2
0061  *  lzma
0062  *  xz
0063  *  lzo
0064  *  lz4
0065  */
0066 static int __init
0067 identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor)
0068 {
0069     const int size = 512;
0070     struct minix_super_block *minixsb;
0071     struct romfs_super_block *romfsb;
0072     struct cramfs_super *cramfsb;
0073     struct squashfs_super_block *squashfsb;
0074     int nblocks = -1;
0075     unsigned char *buf;
0076     const char *compress_name;
0077     unsigned long n;
0078 
0079     buf = kmalloc(size, GFP_KERNEL);
0080     if (!buf)
0081         return -ENOMEM;
0082 
0083     minixsb = (struct minix_super_block *) buf;
0084     romfsb = (struct romfs_super_block *) buf;
0085     cramfsb = (struct cramfs_super *) buf;
0086     squashfsb = (struct squashfs_super_block *) buf;
0087     memset(buf, 0xe5, size);
0088 
0089     /*
0090      * Read block 0 to test for compressed kernel
0091      */
0092     sys_lseek(fd, start_block * BLOCK_SIZE, 0);
0093     sys_read(fd, buf, size);
0094 
0095     *decompressor = decompress_method(buf, size, &compress_name);
0096     if (compress_name) {
0097         printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n",
0098                compress_name, start_block);
0099         if (!*decompressor)
0100             printk(KERN_EMERG
0101                    "RAMDISK: %s decompressor not configured!\n",
0102                    compress_name);
0103         nblocks = 0;
0104         goto done;
0105     }
0106 
0107     /* romfs is at block zero too */
0108     if (romfsb->word0 == ROMSB_WORD0 &&
0109         romfsb->word1 == ROMSB_WORD1) {
0110         printk(KERN_NOTICE
0111                "RAMDISK: romfs filesystem found at block %d\n",
0112                start_block);
0113         nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
0114         goto done;
0115     }
0116 
0117     if (cramfsb->magic == CRAMFS_MAGIC) {
0118         printk(KERN_NOTICE
0119                "RAMDISK: cramfs filesystem found at block %d\n",
0120                start_block);
0121         nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
0122         goto done;
0123     }
0124 
0125     /* squashfs is at block zero too */
0126     if (le32_to_cpu(squashfsb->s_magic) == SQUASHFS_MAGIC) {
0127         printk(KERN_NOTICE
0128                "RAMDISK: squashfs filesystem found at block %d\n",
0129                start_block);
0130         nblocks = (le64_to_cpu(squashfsb->bytes_used) + BLOCK_SIZE - 1)
0131              >> BLOCK_SIZE_BITS;
0132         goto done;
0133     }
0134 
0135     /*
0136      * Read 512 bytes further to check if cramfs is padded
0137      */
0138     sys_lseek(fd, start_block * BLOCK_SIZE + 0x200, 0);
0139     sys_read(fd, buf, size);
0140 
0141     if (cramfsb->magic == CRAMFS_MAGIC) {
0142         printk(KERN_NOTICE
0143                "RAMDISK: cramfs filesystem found at block %d\n",
0144                start_block);
0145         nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
0146         goto done;
0147     }
0148 
0149     /*
0150      * Read block 1 to test for minix and ext2 superblock
0151      */
0152     sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
0153     sys_read(fd, buf, size);
0154 
0155     /* Try minix */
0156     if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
0157         minixsb->s_magic == MINIX_SUPER_MAGIC2) {
0158         printk(KERN_NOTICE
0159                "RAMDISK: Minix filesystem found at block %d\n",
0160                start_block);
0161         nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
0162         goto done;
0163     }
0164 
0165     /* Try ext2 */
0166     n = ext2_image_size(buf);
0167     if (n) {
0168         printk(KERN_NOTICE
0169                "RAMDISK: ext2 filesystem found at block %d\n",
0170                start_block);
0171         nblocks = n;
0172         goto done;
0173     }
0174 
0175     printk(KERN_NOTICE
0176            "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
0177            start_block);
0178 
0179 done:
0180     sys_lseek(fd, start_block * BLOCK_SIZE, 0);
0181     kfree(buf);
0182     return nblocks;
0183 }
0184 
0185 int __init rd_load_image(char *from)
0186 {
0187     int res = 0;
0188     int in_fd, out_fd;
0189     unsigned long rd_blocks, devblocks;
0190     int nblocks, i, disk;
0191     char *buf = NULL;
0192     unsigned short rotate = 0;
0193     decompress_fn decompressor = NULL;
0194 #if !defined(CONFIG_S390)
0195     char rotator[4] = { '|' , '/' , '-' , '\\' };
0196 #endif
0197 
0198     out_fd = sys_open("/dev/ram", O_RDWR, 0);
0199     if (out_fd < 0)
0200         goto out;
0201 
0202     in_fd = sys_open(from, O_RDONLY, 0);
0203     if (in_fd < 0)
0204         goto noclose_input;
0205 
0206     nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor);
0207     if (nblocks < 0)
0208         goto done;
0209 
0210     if (nblocks == 0) {
0211         if (crd_load(in_fd, out_fd, decompressor) == 0)
0212             goto successful_load;
0213         goto done;
0214     }
0215 
0216     /*
0217      * NOTE NOTE: nblocks is not actually blocks but
0218      * the number of kibibytes of data to load into a ramdisk.
0219      */
0220     if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
0221         rd_blocks = 0;
0222     else
0223         rd_blocks >>= 1;
0224 
0225     if (nblocks > rd_blocks) {
0226         printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n",
0227                nblocks, rd_blocks);
0228         goto done;
0229     }
0230 
0231     /*
0232      * OK, time to copy in the data
0233      */
0234     if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
0235         devblocks = 0;
0236     else
0237         devblocks >>= 1;
0238 
0239     if (strcmp(from, "/initrd.image") == 0)
0240         devblocks = nblocks;
0241 
0242     if (devblocks == 0) {
0243         printk(KERN_ERR "RAMDISK: could not determine device size\n");
0244         goto done;
0245     }
0246 
0247     buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
0248     if (!buf) {
0249         printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
0250         goto done;
0251     }
0252 
0253     printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
0254         nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
0255     for (i = 0, disk = 1; i < nblocks; i++) {
0256         if (i && (i % devblocks == 0)) {
0257             printk("done disk #%d.\n", disk++);
0258             rotate = 0;
0259             if (sys_close(in_fd)) {
0260                 printk("Error closing the disk.\n");
0261                 goto noclose_input;
0262             }
0263             change_floppy("disk #%d", disk);
0264             in_fd = sys_open(from, O_RDONLY, 0);
0265             if (in_fd < 0)  {
0266                 printk("Error opening disk.\n");
0267                 goto noclose_input;
0268             }
0269             printk("Loading disk #%d... ", disk);
0270         }
0271         sys_read(in_fd, buf, BLOCK_SIZE);
0272         sys_write(out_fd, buf, BLOCK_SIZE);
0273 #if !defined(CONFIG_S390)
0274         if (!(i % 16)) {
0275             pr_cont("%c\b", rotator[rotate & 0x3]);
0276             rotate++;
0277         }
0278 #endif
0279     }
0280     printk("done.\n");
0281 
0282 successful_load:
0283     res = 1;
0284 done:
0285     sys_close(in_fd);
0286 noclose_input:
0287     sys_close(out_fd);
0288 out:
0289     kfree(buf);
0290     sys_unlink("/dev/ram");
0291     return res;
0292 }
0293 
0294 int __init rd_load_disk(int n)
0295 {
0296     if (rd_prompt)
0297         change_floppy("root floppy disk to be loaded into RAM disk");
0298     create_dev("/dev/root", ROOT_DEV);
0299     create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
0300     return rd_load_image("/dev/root");
0301 }
0302 
0303 static int exit_code;
0304 static int decompress_error;
0305 static int crd_infd, crd_outfd;
0306 
0307 static long __init compr_fill(void *buf, unsigned long len)
0308 {
0309     long r = sys_read(crd_infd, buf, len);
0310     if (r < 0)
0311         printk(KERN_ERR "RAMDISK: error while reading compressed data");
0312     else if (r == 0)
0313         printk(KERN_ERR "RAMDISK: EOF while reading compressed data");
0314     return r;
0315 }
0316 
0317 static long __init compr_flush(void *window, unsigned long outcnt)
0318 {
0319     long written = sys_write(crd_outfd, window, outcnt);
0320     if (written != outcnt) {
0321         if (decompress_error == 0)
0322             printk(KERN_ERR
0323                    "RAMDISK: incomplete write (%ld != %ld)\n",
0324                    written, outcnt);
0325         decompress_error = 1;
0326         return -1;
0327     }
0328     return outcnt;
0329 }
0330 
0331 static void __init error(char *x)
0332 {
0333     printk(KERN_ERR "%s\n", x);
0334     exit_code = 1;
0335     decompress_error = 1;
0336 }
0337 
0338 static int __init crd_load(int in_fd, int out_fd, decompress_fn deco)
0339 {
0340     int result;
0341     crd_infd = in_fd;
0342     crd_outfd = out_fd;
0343 
0344     if (!deco) {
0345         pr_emerg("Invalid ramdisk decompression routine.  "
0346              "Select appropriate config option.\n");
0347         panic("Could not decompress initial ramdisk image.");
0348     }
0349 
0350     result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error);
0351     if (decompress_error)
0352         result = 1;
0353     return result;
0354 }