mem.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:15k
源码类别:

嵌入式Linux

开发平台:

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