mem.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/char/mem.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *
  6.  *  Added devfs support. 
  7.  *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
  8.  *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
  9.  */
  10. #include <linux/config.h>
  11. #include <linux/mm.h>
  12. #include <linux/miscdevice.h>
  13. #include <linux/tpqic02.h>
  14. #include <linux/ftape.h>
  15. #include <linux/slab.h>
  16. #include <linux/vmalloc.h>
  17. #include <linux/mman.h>
  18. #include <linux/random.h>
  19. #include <linux/init.h>
  20. #include <linux/raw.h>
  21. #include <linux/tty.h>
  22. #include <linux/capability.h>
  23. #include <asm/uaccess.h>
  24. #include <asm/io.h>
  25. #include <asm/pgalloc.h>
  26. #ifdef CONFIG_I2C
  27. extern int i2c_init_all(void);
  28. #endif
  29. #ifdef CONFIG_FB
  30. extern void fbmem_init(void);
  31. #endif
  32. #ifdef CONFIG_PROM_CONSOLE
  33. extern void prom_con_init(void);
  34. #endif
  35. #ifdef CONFIG_MDA_CONSOLE
  36. extern void mda_console_init(void);
  37. #endif
  38. #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
  39. extern void tapechar_init(void);
  40. #endif
  41.      
  42. static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
  43.     const char * buf, size_t count, loff_t *ppos)
  44. {
  45. ssize_t written;
  46. written = 0;
  47. #if defined(__sparc__) || defined(__mc68000__)
  48. /* we don't have page 0 mapped on sparc and m68k.. */
  49. if (realp < PAGE_SIZE) {
  50. unsigned long sz = PAGE_SIZE-realp;
  51. if (sz > count) sz = count; 
  52. /* Hmm. Do something? */
  53. buf+=sz;
  54. p+=sz;
  55. count-=sz;
  56. written+=sz;
  57. }
  58. #endif
  59. if (copy_from_user(p, buf, count))
  60. return -EFAULT;
  61. written += count;
  62. *ppos += written;
  63. return written;
  64. }
  65. /*
  66.  * This funcion reads the *physical* memory. The f_pos points directly to the 
  67.  * memory location. 
  68.  */
  69. static ssize_t read_mem(struct file * file, char * buf,
  70. size_t count, loff_t *ppos)
  71. {
  72. unsigned long p = *ppos;
  73. unsigned long end_mem;
  74. ssize_t read;
  75. end_mem = __pa(high_memory);
  76. if (p >= end_mem)
  77. return 0;
  78. if (count > end_mem - p)
  79. count = end_mem - p;
  80. read = 0;
  81. #if defined(__sparc__) || defined(__mc68000__)
  82. /* we don't have page 0 mapped on sparc and m68k.. */
  83. if (p < PAGE_SIZE) {
  84. unsigned long sz = PAGE_SIZE-p;
  85. if (sz > count) 
  86. sz = count; 
  87. if (sz > 0) {
  88. if (clear_user(buf, sz))
  89. return -EFAULT;
  90. buf += sz; 
  91. p += sz; 
  92. count -= sz; 
  93. read += sz; 
  94. }
  95. }
  96. #endif
  97. if (copy_to_user(buf, __va(p), count))
  98. return -EFAULT;
  99. read += count;
  100. *ppos += read;
  101. return read;
  102. }
  103. static ssize_t write_mem(struct file * file, const char * buf, 
  104.  size_t count, loff_t *ppos)
  105. {
  106. unsigned long p = *ppos;
  107. unsigned long end_mem;
  108. end_mem = __pa(high_memory);
  109. if (p >= end_mem)
  110. return 0;
  111. if (count > end_mem - p)
  112. count = end_mem - p;
  113. return do_write_mem(file, __va(p), p, buf, count, ppos);
  114. }
  115. #ifndef pgprot_noncached
  116. /*
  117.  * This should probably be per-architecture in <asm/pgtable.h>
  118.  */
  119. static inline pgprot_t pgprot_noncached(pgprot_t _prot)
  120. {
  121. unsigned long prot = pgprot_val(_prot);
  122. #if defined(__i386__) || defined(__x86_64__)
  123. /* On PPro and successors, PCD alone doesn't always mean 
  124.     uncached because of interactions with the MTRRs. PCD | PWT
  125.     means definitely uncached. */ 
  126. if (boot_cpu_data.x86 > 3)
  127. prot |= _PAGE_PCD | _PAGE_PWT;
  128. #elif defined(__powerpc__)
  129. prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
  130. #elif defined(__mc68000__)
  131. #ifdef SUN3_PAGE_NOCACHE
  132. if (MMU_IS_SUN3)
  133. prot |= SUN3_PAGE_NOCACHE;
  134. else
  135. #endif
  136. if (MMU_IS_851 || MMU_IS_030)
  137. prot |= _PAGE_NOCACHE030;
  138. /* Use no-cache mode, serialized */
  139. else if (MMU_IS_040 || MMU_IS_060)
  140. prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
  141. #endif
  142. return __pgprot(prot);
  143. }
  144. #endif /* !pgprot_noncached */
  145. /*
  146.  * Architectures vary in how they handle caching for addresses 
  147.  * outside of main memory.
  148.  */
  149. static inline int noncached_address(unsigned long addr)
  150. {
  151. #if defined(__i386__)
  152. /* 
  153.  * On the PPro and successors, the MTRRs are used to set
  154.  * memory types for physical addresses outside main memory, 
  155.  * so blindly setting PCD or PWT on those pages is wrong.
  156.  * For Pentiums and earlier, the surround logic should disable 
  157.  * caching for the high addresses through the KEN pin, but
  158.  * we maintain the tradition of paranoia in this code.
  159.  */
  160.   return !( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ||
  161.   test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ||
  162.   test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ||
  163.   test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) )
  164.   && addr >= __pa(high_memory);
  165. #else
  166. return addr >= __pa(high_memory);
  167. #endif
  168. }
  169. static int mmap_mem(struct file * file, struct vm_area_struct * vma)
  170. {
  171. unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  172. /*
  173.  * Accessing memory above the top the kernel knows about or
  174.  * through a file pointer that was marked O_SYNC will be
  175.  * done non-cached.
  176.  */
  177. if (noncached_address(offset) || (file->f_flags & O_SYNC))
  178. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  179. /* Don't try to swap out physical pages.. */
  180. vma->vm_flags |= VM_RESERVED;
  181. /*
  182.  * Don't dump addresses that are not real memory to a core file.
  183.  */
  184. if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
  185. vma->vm_flags |= VM_IO;
  186. if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
  187.      vma->vm_page_prot))
  188. return -EAGAIN;
  189. return 0;
  190. }
  191. /*
  192.  * This function reads the *virtual* memory as seen by the kernel.
  193.  */
  194. static ssize_t read_kmem(struct file *file, char *buf, 
  195.  size_t count, loff_t *ppos)
  196. {
  197. unsigned long p = *ppos;
  198. ssize_t read = 0;
  199. ssize_t virtr = 0;
  200. char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
  201. if (p < (unsigned long) high_memory) {
  202. read = count;
  203. if (count > (unsigned long) high_memory - p)
  204. read = (unsigned long) high_memory - p;
  205. #if defined(__sparc__) || defined(__mc68000__)
  206. /* we don't have page 0 mapped on sparc and m68k.. */
  207. if (p < PAGE_SIZE && read > 0) {
  208. size_t tmp = PAGE_SIZE - p;
  209. if (tmp > read) tmp = read;
  210. if (clear_user(buf, tmp))
  211. return -EFAULT;
  212. buf += tmp;
  213. p += tmp;
  214. read -= tmp;
  215. count -= tmp;
  216. }
  217. #endif
  218. if (copy_to_user(buf, (char *)p, read))
  219. return -EFAULT;
  220. p += read;
  221. buf += read;
  222. count -= read;
  223. }
  224. if (count > 0) {
  225. kbuf = (char *)__get_free_page(GFP_KERNEL);
  226. if (!kbuf)
  227. return -ENOMEM;
  228. while (count > 0) {
  229. int len = count;
  230. if (len > PAGE_SIZE)
  231. len = PAGE_SIZE;
  232. len = vread(kbuf, (char *)p, len);
  233. if (!len)
  234. break;
  235. if (copy_to_user(buf, kbuf, len)) {
  236. free_page((unsigned long)kbuf);
  237. return -EFAULT;
  238. }
  239. count -= len;
  240. buf += len;
  241. virtr += len;
  242. p += len;
  243. }
  244. free_page((unsigned long)kbuf);
  245. }
  246.   *ppos = p;
  247.   return virtr + read;
  248. }
  249. extern long vwrite(char *buf, char *addr, unsigned long count);
  250. /*
  251.  * This function writes to the *virtual* memory as seen by the kernel.
  252.  */
  253. static ssize_t write_kmem(struct file * file, const char * buf, 
  254.   size_t count, loff_t *ppos)
  255. {
  256. unsigned long p = *ppos;
  257. ssize_t wrote = 0;
  258. ssize_t virtr = 0;
  259. char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
  260. if (p < (unsigned long) high_memory) {
  261. wrote = count;
  262. if (count > (unsigned long) high_memory - p)
  263. wrote = (unsigned long) high_memory - p;
  264. wrote = do_write_mem(file, (void*)p, p, buf, wrote, ppos);
  265. p += wrote;
  266. buf += wrote;
  267. count -= wrote;
  268. }
  269. if (count > 0) {
  270. kbuf = (char *)__get_free_page(GFP_KERNEL);
  271. if (!kbuf)
  272. return -ENOMEM;
  273. while (count > 0) {
  274. int len = count;
  275. if (len > PAGE_SIZE)
  276. len = PAGE_SIZE;
  277. if (len && copy_from_user(kbuf, buf, len)) {
  278. free_page((unsigned long)kbuf);
  279. return -EFAULT;
  280. }
  281. len = vwrite(kbuf, (char *)p, len);
  282. count -= len;
  283. buf += len;
  284. virtr += len;
  285. p += len;
  286. }
  287. free_page((unsigned long)kbuf);
  288. }
  289.   *ppos = p;
  290.   return virtr + wrote;
  291. }
  292. #if defined(CONFIG_ISA) || !defined(__mc68000__)
  293. static ssize_t read_port(struct file * file, char * buf,
  294.  size_t count, loff_t *ppos)
  295. {
  296. unsigned long i = *ppos;
  297. char *tmp = buf;
  298. if (verify_area(VERIFY_WRITE,buf,count))
  299. return -EFAULT; 
  300. while (count-- > 0 && i < 65536) {
  301. if (__put_user(inb(i),tmp) < 0) 
  302. return -EFAULT;  
  303. i++;
  304. tmp++;
  305. }
  306. *ppos = i;
  307. return tmp-buf;
  308. }
  309. static ssize_t write_port(struct file * file, const char * buf,
  310.   size_t count, loff_t *ppos)
  311. {
  312. unsigned long i = *ppos;
  313. const char * tmp = buf;
  314. if (verify_area(VERIFY_READ,buf,count))
  315. return -EFAULT;
  316. while (count-- > 0 && i < 65536) {
  317. char c;
  318. if (__get_user(c, tmp)) 
  319. return -EFAULT; 
  320. outb(c,i);
  321. i++;
  322. tmp++;
  323. }
  324. *ppos = i;
  325. return tmp-buf;
  326. }
  327. #endif
  328. static ssize_t read_null(struct file * file, char * buf,
  329.  size_t count, loff_t *ppos)
  330. {
  331. return 0;
  332. }
  333. static ssize_t write_null(struct file * file, const char * buf,
  334.   size_t count, loff_t *ppos)
  335. {
  336. return count;
  337. }
  338. /*
  339.  * For fun, we are using the MMU for this.
  340.  */
  341. static inline size_t read_zero_pagealigned(char * buf, size_t size)
  342. {
  343. struct mm_struct *mm;
  344. struct vm_area_struct * vma;
  345. unsigned long addr=(unsigned long)buf;
  346. mm = current->mm;
  347. /* Oops, this was forgotten before. -ben */
  348. down_read(&mm->mmap_sem);
  349. /* For private mappings, just map in zero pages. */
  350. for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
  351. unsigned long count;
  352. if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
  353. goto out_up;
  354. if (vma->vm_flags & VM_SHARED)
  355. break;
  356. count = vma->vm_end - addr;
  357. if (count > size)
  358. count = size;
  359. zap_page_range(mm, addr, count);
  360.          zeromap_page_range(addr, count, PAGE_COPY);
  361. size -= count;
  362. buf += count;
  363. addr += count;
  364. if (size == 0)
  365. goto out_up;
  366. }
  367. up_read(&mm->mmap_sem);
  368. /* The shared case is hard. Let's do the conventional zeroing. */ 
  369. do {
  370. unsigned long unwritten = clear_user(buf, PAGE_SIZE);
  371. if (unwritten)
  372. return size + unwritten - PAGE_SIZE;
  373. if (current->need_resched)
  374. schedule();
  375. buf += PAGE_SIZE;
  376. size -= PAGE_SIZE;
  377. } while (size);
  378. return size;
  379. out_up:
  380. up_read(&mm->mmap_sem);
  381. return size;
  382. }
  383. static ssize_t read_zero(struct file * file, char * buf, 
  384.  size_t count, loff_t *ppos)
  385. {
  386. unsigned long left, unwritten, written = 0;
  387. if (!count)
  388. return 0;
  389. if (!access_ok(VERIFY_WRITE, buf, count))
  390. return -EFAULT;
  391. left = count;
  392. /* do we want to be clever? Arbitrary cut-off */
  393. if (count >= PAGE_SIZE*4) {
  394. unsigned long partial;
  395. /* How much left of the page? */
  396. partial = (PAGE_SIZE-1) & -(unsigned long) buf;
  397. unwritten = clear_user(buf, partial);
  398. written = partial - unwritten;
  399. if (unwritten)
  400. goto out;
  401. left -= partial;
  402. buf += partial;
  403. unwritten = read_zero_pagealigned(buf, left & PAGE_MASK);
  404. written += (left & PAGE_MASK) - unwritten;
  405. if (unwritten)
  406. goto out;
  407. buf += left & PAGE_MASK;
  408. left &= ~PAGE_MASK;
  409. }
  410. unwritten = clear_user(buf, left);
  411. written += left - unwritten;
  412. out:
  413. return written ? written : -EFAULT;
  414. }
  415. static int mmap_zero(struct file * file, struct vm_area_struct * vma)
  416. {
  417. if (vma->vm_flags & VM_SHARED)
  418. return shmem_zero_setup(vma);
  419. if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
  420. return -EAGAIN;
  421. return 0;
  422. }
  423. static ssize_t write_full(struct file * file, const char * buf,
  424.   size_t count, loff_t *ppos)
  425. {
  426. return -ENOSPC;
  427. }
  428. /*
  429.  * Special lseek() function for /dev/null and /dev/zero.  Most notably, you
  430.  * can fopen() both devices with "a" now.  This was previously impossible.
  431.  * -- SRB.
  432.  */
  433. static loff_t null_lseek(struct file * file, loff_t offset, int orig)
  434. {
  435. return file->f_pos = 0;
  436. }
  437. /*
  438.  * The memory devices use the full 32/64 bits of the offset, and so we cannot
  439.  * check against negative addresses: they are ok. The return value is weird,
  440.  * though, in that case (0).
  441.  *
  442.  * also note that seeking relative to the "end of file" isn't supported:
  443.  * it has no meaning, so it returns -EINVAL.
  444.  */
  445. static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
  446. {
  447. switch (orig) {
  448. case 0:
  449. file->f_pos = offset;
  450. return file->f_pos;
  451. case 1:
  452. file->f_pos += offset;
  453. return file->f_pos;
  454. default:
  455. return -EINVAL;
  456. }
  457. }
  458. static int open_port(struct inode * inode, struct file * filp)
  459. {
  460. return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
  461. }
  462. #define mmap_kmem mmap_mem
  463. #define zero_lseek null_lseek
  464. #define full_lseek      null_lseek
  465. #define write_zero write_null
  466. #define read_full       read_zero
  467. #define open_mem open_port
  468. #define open_kmem open_mem
  469. static struct file_operations mem_fops = {
  470. llseek: memory_lseek,
  471. read: read_mem,
  472. write: write_mem,
  473. mmap: mmap_mem,
  474. open: open_mem,
  475. };
  476. static struct file_operations kmem_fops = {
  477. llseek: memory_lseek,
  478. read: read_kmem,
  479. write: write_kmem,
  480. mmap: mmap_kmem,
  481. open: open_kmem,
  482. };
  483. static struct file_operations null_fops = {
  484. llseek: null_lseek,
  485. read: read_null,
  486. write: write_null,
  487. };
  488. #if defined(CONFIG_ISA) || !defined(__mc68000__)
  489. static struct file_operations port_fops = {
  490. llseek: memory_lseek,
  491. read: read_port,
  492. write: write_port,
  493. open: open_port,
  494. };
  495. #endif
  496. static struct file_operations zero_fops = {
  497. llseek: zero_lseek,
  498. read: read_zero,
  499. write: write_zero,
  500. mmap: mmap_zero,
  501. };
  502. static struct file_operations full_fops = {
  503. llseek: full_lseek,
  504. read: read_full,
  505. write: write_full,
  506. };
  507. static int memory_open(struct inode * inode, struct file * filp)
  508. {
  509. switch (MINOR(inode->i_rdev)) {
  510. case 1:
  511. filp->f_op = &mem_fops;
  512. break;
  513. case 2:
  514. filp->f_op = &kmem_fops;
  515. break;
  516. case 3:
  517. filp->f_op = &null_fops;
  518. break;
  519. #if defined(CONFIG_ISA) || !defined(__mc68000__)
  520. case 4:
  521. filp->f_op = &port_fops;
  522. break;
  523. #endif
  524. case 5:
  525. filp->f_op = &zero_fops;
  526. break;
  527. case 7:
  528. filp->f_op = &full_fops;
  529. break;
  530. case 8:
  531. filp->f_op = &random_fops;
  532. break;
  533. case 9:
  534. filp->f_op = &urandom_fops;
  535. break;
  536. default:
  537. return -ENXIO;
  538. }
  539. if (filp->f_op && filp->f_op->open)
  540. return filp->f_op->open(inode,filp);
  541. return 0;
  542. }
  543. void __init memory_devfs_register (void)
  544. {
  545.     /*  These are never unregistered  */
  546.     static const struct {
  547. unsigned short minor;
  548. char *name;
  549. umode_t mode;
  550. struct file_operations *fops;
  551.     } list[] = { /* list of minor devices */
  552. {1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
  553. {2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
  554. {3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
  555. #if defined(CONFIG_ISA) || !defined(__mc68000__)
  556. {4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
  557. #endif
  558. {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
  559. {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
  560. {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
  561. {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
  562.     };
  563.     int i;
  564.     for (i=0; i<(sizeof(list)/sizeof(*list)); i++)
  565. devfs_register (NULL, list[i].name, DEVFS_FL_NONE,
  566. MEM_MAJOR, list[i].minor,
  567. list[i].mode | S_IFCHR,
  568. list[i].fops, NULL);
  569. }
  570. static struct file_operations memory_fops = {
  571. open: memory_open, /* just a selector for the real open */
  572. };
  573. int __init chr_dev_init(void)
  574. {
  575. if (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops))
  576. printk("unable to get major %d for memory devsn", MEM_MAJOR);
  577. memory_devfs_register();
  578. rand_initialize();
  579. #ifdef CONFIG_I2C
  580. i2c_init_all();
  581. #endif
  582. #if defined (CONFIG_FB)
  583. fbmem_init();
  584. #endif
  585. #if defined (CONFIG_PROM_CONSOLE)
  586. prom_con_init();
  587. #endif
  588. #if defined (CONFIG_MDA_CONSOLE)
  589. mda_console_init();
  590. #endif
  591. tty_init();
  592. #ifdef CONFIG_M68K_PRINTER
  593. lp_m68k_init();
  594. #endif
  595. misc_init();
  596. #if CONFIG_QIC02_TAPE
  597. qic02_tape_init();
  598. #endif
  599. #ifdef CONFIG_FTAPE
  600. ftape_init();
  601. #endif
  602. #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
  603. tapechar_init();
  604. #endif
  605. return 0;
  606. }
  607. __initcall(chr_dev_init);