Messages in this thread Patch in this message | | | Date | Tue, 31 Mar 1998 01:42:32 -0500 (EST) | From | Adam Heath <> | Subject | Patch: 2.1.92pre2: slram_device (fwd) |
| |
This allows for upper memory to be turned into a device. Then, during boot up, the init scripts can run mkswap /dev/slram or mkfs /dev/slram or whatever. It is particularly useful on chipsets that don't cache all available ram, as slow ram will always be faster than a fast disk.
Command line options: fastmem=64M mem=96M This makes all memory between 64M and 96M a device(32M).
You must 'mknod /dev/slram b 123 0'
Adam
diff -ruN linux/arch/i386/config.in 2.1.92/arch/i386/config.in --- linux/arch/i386/config.in Mon Mar 30 15:29:04 1998 +++ 2.1.92/arch/i386/config.in Mon Mar 30 15:43:45 1998 @@ -18,6 +18,7 @@ PPro/K6/6x86MX CONFIG_M686" Pentium bool 'Math emulation' CONFIG_MATH_EMULATION int ' Max physical memory in MB' CONFIG_MAX_MEMSIZE 1024 +bool 'Use slow memory as a ramdisk' CONFIG_BLK_DEV_SLRAM endmenu mainmenu_option next_comment diff -ruN linux/arch/i386/kernel/setup.c 2.1.92/arch/i386/kernel/setup.c --- linux/arch/i386/kernel/setup.c Mon Mar 30 15:28:47 1998 +++ 2.1.92/arch/i386/kernel/setup.c Sun Mar 29 00:46:44 1998 @@ -29,7 +29,7 @@ #ifdef CONFIG_APM #include <linux/apm_bios.h> #endif -#ifdef CONFIG_BLK_DEV_RAM +#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_SLRAM) #include <linux/blk.h> #endif #include <asm/uaccess.h> @@ -42,6 +42,10 @@ char ignore_irq13 = 0; /* set if exception 16 works */ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; +#ifdef CONFIG_BLK_DEV_SLRAM +int end_fast_mem = 0; /* end of fast memory - in case something + is not cached this is interesting */ +#endif /* * Bus types .. @@ -75,6 +79,12 @@ extern int rd_image_start; /* starting block # of image */ #endif +#ifdef CONFIG_BLK_DEV_SLRAM +/* +unsigned long slram_size = 0, slram_phys, slram_virt; +*/ +#endif + extern int root_mountflags; extern int _etext, _edata, _end; @@ -184,6 +194,21 @@ } } } +#ifdef CONFIG_BLK_DEV_SLRAM + if (c == ' ' && *(const unsigned long *)from == *(const unsigned long *)"fastmem=") { + if (to != command_line) to--; + { + end_fast_mem = simple_strtoul(from+8, &from, 0); + if ( *from == 'K' || *from == 'k' ) { + end_fast_mem = end_fast_mem << 10; + from++; + } else if ( *from == 'M' || *from == 'm' ) { + end_fast_mem = end_fast_mem << 20; + from++; + } + } + } +#endif c = *(from++); if (!c) break; @@ -193,6 +218,18 @@ } *to = '\0'; *cmdline_p = command_line; +#ifdef CONFIG_BLK_DEV_SLRAM + if (!end_fast_mem) + end_fast_mem = memory_end; + if (!slram_size && (memory_end > end_fast_mem)) { + slram_size = memory_end - end_fast_mem; + printk("RAM above %luk declared slow, reserving %luk for slram\n", end_fast_mem >>10, slram_size >>10 ); + slram_phys = end_fast_mem; + } else { + slram_phys = 0; + } + slram_virt = 0; +#endif memory_end += PAGE_OFFSET; *memory_start_p = memory_start; *memory_end_p = memory_end; diff -ruN linux/arch/i386/mm/init.c 2.1.92/arch/i386/mm/init.c --- linux/arch/i386/mm/init.c Mon Mar 30 15:29:05 1998 +++ 2.1.92/arch/i386/mm/init.c Sat Mar 28 23:55:57 1998 @@ -31,6 +31,9 @@ extern void die_if_kernel(char *,struct pt_regs *,long); extern void show_net_buffers(void); +#ifdef CONFIG_BLK_DEV_SLRAM +extern int end_fast_mem; +#endif /* * BAD_PAGE is the page that is used for page faults when linux @@ -337,11 +340,17 @@ start_low_mem += PAGE_SIZE; } - while (start_mem < end_mem) { + while (start_mem < +#ifdef CONFIG_BLK_DEV_SLRAM + ((end_fast_mem+PAGE_OFFSET) & PAGE_MASK) +#else + end_mem +#endif + ) { clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags); start_mem += PAGE_SIZE; } - for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) { + for (tmp = end_mem - PAGE_SIZE; tmp >= PAGE_OFFSET ; tmp -= PAGE_SIZE) { if (tmp >= MAX_DMA_ADDRESS) clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags); if (PageReserved(mem_map+MAP_NR(tmp))) { diff -ruN linux/drivers/block/Makefile 2.1.92/drivers/block/Makefile --- linux/drivers/block/Makefile Mon Mar 30 15:28:47 1998 +++ 2.1.92/drivers/block/Makefile Sun Mar 29 00:45:00 1998 @@ -70,6 +70,14 @@ endif endif +ifeq ($(CONFIG_BLK_DEV_SLRAM),y) +L_OBJS += slram.o +else + ifeq ($(CONFIG_BLK_DEV_SLRAM),m) + M_OBJS += slram.o + endif +endif + ifeq ($(CONFIG_BLK_DEV_LOOP),y) L_OBJS += loop.o else diff -ruN linux/drivers/block/ll_rw_blk.c 2.1.92/drivers/block/ll_rw_blk.c --- linux/drivers/block/ll_rw_blk.c Mon Mar 30 15:29:05 1998 +++ 2.1.92/drivers/block/ll_rw_blk.c Sun Mar 29 00:41:48 1998 @@ -789,6 +789,9 @@ #ifdef CONFIG_DDV ddv_init(); #endif +#ifdef CONFIG_BLK_DEV_SLRAM + slram_init(); +#endif return 0; }; diff -ruN linux/drivers/block/slram.c 2.1.92/drivers/block/slram.c --- linux/drivers/block/slram.c Wed Dec 31 19:00:00 1969 +++ 2.1.92/drivers/block/slram.c Sun Mar 29 00:39:08 1998 @@ -0,0 +1,190 @@ +/* + * slram (slow RAM): a way to use large amounts of RAM on 486 and Pentium + * systems without slowing the system down. Reserves all RAM above a specified + * amount for a special ramdisk. Takes advantage of Larry Augustin's RAM + * detection patch (BIOS int 15h, ah=c7h returns amount of cached RAM; support + * for this in slram is untested, however) + * + * written by Brad Keryan <keryan@andrew.cmu.edu> + * + * Heavily based on z2ram by Ingo Wilken + * (Ingo.Wilken@informatik.uni-oldenburg.de) and on + * drivers/block/rd.c. Also drivers/block/ide.c. + */ + +/* the original z2ram copyright is as follows: */ +/* Copyright (C) 1994 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + + +#include <linux/config.h> +#include <linux/fs.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/mman.h> +#include <linux/malloc.h> +#include <linux/ioctl.h> +#include <linux/fd.h> +#include <linux/module.h> + +#include <asm/system.h> +#include <asm/segment.h> +#include <asm/uaccess.h> +#include <asm/io.h> + +/* note: this is a very unofficial major number. Maybe would sharing +z2ram's major number be a good idea? After all, this driver is +i386-only and z2ram is m68k-only . . . */ +#ifndef SLRAM_MAJOR +#define SLRAM_MAJOR 123 +#endif + +#define MAJOR_NR SLRAM_MAJOR +#define MINOR_NR 0 +#define DEVICE_NAME "slram" +#define DEVICE_REQUEST do_slram_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) +#define DEVICE_NO_RANDOM + +#include <linux/blk.h> + +#define BLKSIZE 1024 + +unsigned long slram_size = 0, slram_phys, slram_virt; + +static int slram_blksizes[1]; /* only one device is possible right now */ + +static void do_slram_request (void) +{ + unsigned int minor; + unsigned int offset, len; + + repeat: + INIT_REQUEST; + + minor = MINOR(CURRENT->rq_dev); + if (minor != MINOR_NR) { + end_request(0); + goto repeat; + } + + offset = CURRENT->sector << 9; + len = CURRENT->current_nr_sectors << 9; + + if ((offset + len) > slram_size) { + end_request(0); + goto repeat; + } + + switch(CURRENT->cmd) { + case READ : + memcpy(CURRENT->buffer, (char *) slram_virt + offset, len); + break; + case WRITE : + memcpy((char *) slram_virt + offset, CURRENT->buffer, len); + break; + default : + printk("do_slram_request: unknown command\n"); + } + end_request(1); + goto repeat; +} + +static int slram_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + /* more or less copied from rd.c */ + int err; + + /* printk(KERN_NOTICE "slram ioctl(0x%x, 0x%x)\n", cmd, + arg); */ + + if (!inode || !inode->i_rdev) + return -EINVAL; + + switch (cmd) { + case BLKFLSBUF: + if (!suser()) return -EACCES; + invalidate_buffers(inode->i_rdev); + break; + case BLKGETSIZE: /* Return device size */ + if (!arg) return -EINVAL; + err = verify_area(VERIFY_WRITE, (long *) arg, + sizeof(long)); + if (err) + return err; + put_user(slram_size / 512, (long *) arg); + return 0; + default: + break; + }; + + return 0; +} + +static int slram_open(struct inode *inode, struct file *file) +{ + if (MINOR(inode->i_rdev) != MINOR_NR) + return -ENXIO; + + /* perhaps this driver could be modularized */ + /* maybe use mem=64M and then specify the memory range for the module + to use */ + /* MOD_INC_USE_COUNT? */ + return 0; +} + +static int slram_release(struct inode *inode, struct file *file) +{ + /* MOD_DEC_USE_COUNT? */ + return 0; +} + +static struct file_operations slram_fops = { + NULL, /* lseek - default */ + block_read, /* read - general block-dev read */ + block_write, /* write - general block-dev write */ + NULL, /* readdir - bad */ + NULL, /* select */ + slram_ioctl, /* ioctl */ + NULL, /* mmap */ + slram_open, /* open */ + slram_release, /* release */ + block_fsync, /* fsync */ +}; + +void slram_init(void) +{ + if (register_blkdev(MAJOR_NR, DEVICE_NAME, &slram_fops)) { + printk("Unable to allocate major %d for slram\n", + MAJOR_NR); + return; + } + blk_dev[MAJOR_NR].request_fn = do_slram_request; + slram_blksizes[MINOR_NR] = BLKSIZE; + blksize_size[MAJOR_NR] = slram_blksizes; + slram_virt = (unsigned long) __va(slram_phys); + printk("Slow RAM %luk-%luk mapped to %lx for slram disk\n", + (slram_phys)>>10, + (slram_phys + slram_size)>>10, + slram_virt ); +} + +void slram_unregister(void) +{ + unregister_blkdev(MAJOR_NR, DEVICE_NAME); + + blk_dev[MAJOR_NR].request_fn = NULL; + blksize_size[MAJOR_NR] = NULL; +} + diff -ruN linux/include/linux/blk.h 2.1.92/include/linux/blk.h --- linux/include/linux/blk.h Mon Mar 30 15:28:39 1998 +++ 2.1.92/include/linux/blk.h Mon Mar 30 15:53:58 1998 @@ -72,6 +72,7 @@ extern int z2_init(void); extern int swim3_init(void); extern int ps2esdi_init(void); +extern void slram_init(void); extern void set_device_ro(kdev_t dev,int flag); void add_blkdev_randomness(int major); @@ -92,6 +93,12 @@ extern int initrd_below_start_ok; /* 1 if it is not an error if initrd_start < memory_start */ void initrd_init(void); +#endif + +#ifdef CONFIG_BLK_DEV_SLRAM +extern unsigned long slram_size, slram_phys, slram_virt; +void slram_init(void); +void slram_unregister(void); #endif #define RO_IOCTLS(dev,where) \ | |