Multiple floppies compressed ramdisk patch



The problem

Booting a Linux compressed ramdisk from multiple floppies.


The code

The ramdisk loader is (kernel 2.2 and 2.4) in drivers/block/rd.c and the crd_load() routine is responsable to load a compressed ramdisk.

From 2.2.16 kernel source:

        nblocks = identify_ramdisk_image(device, &infile, offset);
        if (nblocks < 0)
                goto done;

        if (nblocks == 0) { 
#ifdef BUILD_CRAMDISK
                if (crd_load(&infile, &outfile) == 0)
                        goto successful_load;
#else
                printk(KERN_NOTICE
                       "RAMDISK: Kernel does not support compressed "
                       "RAM disk images\n");
#endif
                goto done;
        }
    

As you can see the support is identified as a compressed ramdisk and loaded from crd_load():

__initfunc(static int
crd_load(struct file * fp, struct file *outfp))
{
        int result;

        insize = 0;             /* valid bytes in inbuf */
        inptr = 0;              /* index of next byte to be processed in inbuf */
        outcnt = 0;             /* bytes in output buffer */
        exit_code = 0;
        bytes_out = 0;
        crc = (ulg)0xffffffffL; /* shift register contents */

        crd_infp = fp;
        crd_outfp = outfp;
        inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
        if (inbuf == 0) {
                printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
                return -1;
        }
        window = kmalloc(WSIZE, GFP_KERNEL);
        if (window == 0) {
                printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
                kfree(inbuf);
                return -1;
        }
        makecrc();
        result = gunzip();
        kfree(inbuf);
        kfree(window);
        return result;
}
  

The solution

The solution seems simple examining another fragment in rd.c:
        for (i=0; i < nblocks; i++) {
                if (i && (i % devblocks == 0)) {
                        printk("done disk #%d.\n", i/devblocks);
                        rotate = 0;
                        invalidate_buffers(device);
                        if (infile.f_op->release)
                                infile.f_op->release(&inode, &infile);
                        printk("Please insert disk #%d and press ENTER\n", i/devblocks+1);
                        wait_for_keypress();
                        if (blkdev_open(&inode, &infile) != 0)  {
                                printk("Error opening disk.\n");
                                goto done;
                        }
                        infile.f_pos = 0;
                        printk("Loading disk #%d... ", i/devblocks+1);
                }
                infile.f_op->read(&infile, buf, BLOCK_SIZE, &infile.f_pos);
                outfile.f_op->write(&outfile, buf, BLOCK_SIZE, &outfile.f_pos);
#ifndef CONFIG_ARCH_S390
                if (!(i % 16)) {
                        printk("%c\b", rotator[rotate & 0x3]);
                        rotate++;
                }
    

A look to the routine fill_inbuf reveals where the gzip magic is done:

__initfunc(static int fill_inbuf(void))
{
        if (exit_code) return -1;

        insize = crd_infp->f_op->read(crd_infp, inbuf, INBUFSIZ,
                                      &crd_infp->f_pos);
        if (insize == 0) return -1;

        inptr = 1;

        return inbuf[0];
}
   

Any patch already available floating around?

Anyone available to write and support it?