diff -ubr kernel-old/arch/armnommu/mm/Makefile kernel/arch/armnommu/mm/Makefile --- kernel-old/arch/armnommu/mm/Makefile Thu Oct 11 12:12:09 2001 +++ kernel/arch/armnommu/mm/Makefile Thu Oct 11 13:11:14 2001 @@ -28,6 +28,8 @@ obj-$(CONFIG_DISCONTIGMEM) += discontig.o +obj-$(MAGIC_ROM_PTR) += memory.o + # Select the processor-specific files p-$(CONFIG_CPU_26) += proc-arm2,3.o p-$(CONFIG_CPU_ARM610) += proc-arm6,7.o diff -ubr kernel-old/drivers/block/blkmem.c kernel/drivers/block/blkmem.c --- kernel-old/drivers/block/blkmem.c Thu Oct 11 12:13:27 2001 +++ kernel/drivers/block/blkmem.c Thu Oct 11 13:11:19 2001 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -2353,6 +2361,19 @@ } } +#ifdef MAGIC_ROM_PTR +static int +blkmem_romptr( struct file *filp, struct vm_area_struct * vma) +{ + struct arena_t * a = arena + MINOR(filp->f_dentry->d_inode->i_rdev); + + if (a->read_func) + return -ENOSYS; /* Can't do it, as this arena isn't in the main address space */ + + vma->vm_start = a->address + vma->vm_offset; + return 0; +} +#endif static int blkmem_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -2482,6 +2503,9 @@ open: blkmem_open, release: blkmem_release, ioctl: blkmem_ioctl, +#ifdef MAGIC_ROM_PTR + romptr: blkmem_romptr, +#endif }; diff -ubr kernel-old/fs/buffer.c kernel/fs/buffer.c --- kernel-old/fs/buffer.c Thu Oct 11 12:14:55 2001 +++ kernel/fs/buffer.c Thu Oct 11 13:11:21 2001 @@ -2771,4 +2771,18 @@ } module_init(bdflush_init) + +#ifdef MAGIC_ROM_PTR +int bromptr(kdev_t dev, struct vm_area_struct * vma) +{ + extern const struct block_device_operations *get_blkfops(unsigned int); + + if (get_blkfops(MAJOR(dev))->romptr!=NULL) + { + return get_blkfops(MAJOR(dev))->romptr(NULL, vma); + } + return -ENOSYS; +} +#endif /* MAGIC_ROM_PTR */ + diff -ubr kernel-old/fs/romfs/inode.c kernel/fs/romfs/inode.c --- kernel-old/fs/romfs/inode.c Thu Oct 11 12:15:10 2001 +++ kernel/fs/romfs/inode.c Thu Oct 11 13:11:21 2001 @@ -438,6 +438,20 @@ return result; } +#ifdef MAGIC_ROM_PTR +static int +romfs_romptr(struct file * filp, struct vm_area_struct * vma) +{ + struct inode * inode = filp->f_dentry->d_inode; + vma->vm_offset += inode->u.romfs_i.i_dataoffset; + + if ((vma->vm_flags & VM_WRITE) || bromptr(inode->i_dev, vma)) + return -ENOSYS; + + return 0; +} +#endif + /* Mapping from our types to the kernel */ static struct address_space_operations romfs_aops = { @@ -449,6 +463,14 @@ readdir: romfs_readdir, }; +struct file_operations romfs_file_operations = { + read: generic_file_read, + mmap: generic_file_mmap, +#ifdef MAGIC_ROM_PTR + romptr: romfs_romptr, +#endif +}; + static struct inode_operations romfs_dir_inode_operations = { lookup: romfs_lookup, }; @@ -467,7 +489,6 @@ ino = i->i_ino & ROMFH_MASK; i->i_mode = 0; - /* Loop for finding the real hard link */ for(;;) { if (romfs_copyfrom(i, &ri, ino, ROMFH_SIZE) <= 0) { @@ -511,7 +532,7 @@ i->i_mode = ino; break; case 2: - i->i_fop = &generic_ro_fops; + i->i_fop = &romfs_file_operations; i->i_data.a_ops = &romfs_aops; if (nextfh & ROMFH_EXEC) ino |= S_IXUGO; diff -ubr kernel-old/include/linux/fs.h kernel/include/linux/fs.h --- kernel-old/include/linux/fs.h Thu Oct 11 12:16:18 2001 +++ kernel/include/linux/fs.h Thu Oct 11 13:11:23 2001 @@ -768,6 +768,9 @@ int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long); int (*check_media_change) (kdev_t); int (*revalidate) (kdev_t); +#ifdef MAGIC_ROM_PTR + int (*romptr) (struct file *, struct vm_area_struct *); +#endif /* MAGIC_ROM_PTR */ }; /* @@ -794,6 +797,9 @@ ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); +#ifdef MAGIC_ROM_PTR + int (*romptr) (struct file *, struct vm_area_struct *); +#endif /* MAGIC_ROM_PTR */ }; struct inode_operations { diff -ubr kernel-old/mmnommu/mmap.c kernel/mmnommu/mmap.c --- kernel-old/mmnommu/mmap.c Thu Oct 11 12:16:41 2001 +++ kernel/mmnommu/mmap.c Thu Oct 11 13:11:24 2001 @@ -1123,13 +1126,29 @@ } vma.vm_offset = pgoff << PAGE_SHIFT; +#ifdef MAGIC_ROM_PTR + /* First, try simpler routine designed to give us a ROM pointer. */ + + if (file->f_op->romptr && !(prot & PROT_WRITE)) { + error = file->f_op->romptr(file, &vma); +#ifdef DEBUG + printk("romptr mmap returned %d, start 0x%.8x\n", error, vma.vm_start); +#endif + if (!error) + return vma.vm_start; + else if (error != -ENOSYS) + return error; + } else +#endif /* MAGIC_ROM_PTR */ /* Then try full mmap routine, which might return a RAM pointer, or do something truly complicated. */ if (file->f_op->mmap) { error = file->f_op->mmap(file, &vma); - /*printk("mmap mmap returned %d /%x\n", error, vma.vm_start);*/ +#ifdef DEBUG + printk("mmap mmap returned %d /%x\n", error, vma.vm_start); +#endif if (!error) return vma.vm_start; else if (error != -ENOSYS) @@ -1224,6 +1243,13 @@ { struct mm_tblock_struct * tblock, *tmp; +#ifdef MAGIC_ROM_PTR + /* For efficiency's sake, if the pointer is obviously in ROM, + don't bother walking the lists to free it */ + if (is_in_rom(addr)) + return 0; +#endif + #ifdef DEBUG printk("do_munmap:\n"); #endif