免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6831 | 回复: 5
打印 上一主题 下一主题

谁能一句话说明这几个内存操作的区别?(kmalloc,kmap,ioremap) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-30 23:08 |只看该作者 |倒序浏览
只看了相对简单的kmap函数,理解的结果是,这个函数是把某块高端内存映射到页表,然后返回给用户一个填好vitual字段的 page结构




然后听说ioremap的功能是把io空间映射出来,疑问: ioremap只能操作io空间而不能操作ram空间?  该函数实现原理是? 能否以最简要的句子概括,谢谢!

论坛徽章:
0
2 [报告]
发表于 2010-05-31 01:06 |只看该作者
lz仔细看kmap()了?
它是建立永久地址映射,不是简单的返回virtual字段的page

而kmalloc则是slab机制来分配内核对象

因为驱动程序无法直接访问io物理地址,所以ioremap是为了使将其映射到虚拟内存,然后直接像访问内存那样访问io
lz说不能操作ram空间,是??

论坛徽章:
0
3 [报告]
发表于 2010-06-01 01:11 |只看该作者
然后听说ioremap的功能是把io空间映射出来,疑问: ioremap只能操作io空间而不能操作ram空间?  该函数实现原理是? 能否以最简要的句子概括,谢谢!wilbur512 发表于 2010-05-30 23:08



看ioremap的代码实现,应该能操作ram空间吧(当开启了CONFIG_HIGHMEM时,能操作大于896M的RAM)

  1. void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
  2. {
  3.         void __iomem * addr;
  4.         struct vm_struct * area;
  5.         unsigned long offset, last_addr;

  6.         /* Don't allow wraparound or zero size */
  7.         last_addr = phys_addr + size - 1;
  8.         if (!size || last_addr < phys_addr)
  9.                 return NULL;

  10.         /*
  11.          * Don't remap the low PCI/ISA area, it's always mapped..
  12.          */
  13.         if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
  14.                 return (void __iomem *) phys_to_virt(phys_addr);

  15.         /*
  16.          * Don't allow anybody to remap normal RAM that we're using..
  17.          */
  18.         if (phys_addr <= virt_to_phys(high_memory - 1)) {
  19.                 char *t_addr, *t_end;
  20.                 struct page *page;

  21.                 t_addr = __va(phys_addr);
  22.                 t_end = t_addr + (size - 1);
  23.           
  24.                 for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
  25.                         if(!PageReserved(page))
  26.                                 return NULL;
  27.         }

  28.         /*
  29.          * Mappings have to be page-aligned
  30.          */
  31.         offset = phys_addr & ~PAGE_MASK;
  32.         phys_addr &= PAGE_MASK;
  33.         size = PAGE_ALIGN(last_addr+1) - phys_addr;

  34.         /*
  35.          * Ok, go for it..
  36.          */
  37.         area = get_vm_area(size, VM_IOREMAP | (flags << 20));
  38.         if (!area)
  39.                 return NULL;
  40.         area->phys_addr = phys_addr;
  41.         addr = (void __iomem *) area->addr;
  42.         if (ioremap_page_range((unsigned long) addr,
  43.                         (unsigned long) addr + size, phys_addr, flags)) {
  44.                 vunmap((void __force *) addr);
  45.                 return NULL;
  46.         }
  47.         return (void __iomem *) (offset + (char __iomem *)addr);
  48. }
复制代码
if判断中:

  1. if (phys_addr <= virt_to_phys(high_memory - 1))
复制代码
看high_memory的赋值:

  1. mem_init()

  2. #ifdef CONFIG_HIGHMEM
  3.         high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
  4. #else
  5.         high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
  6. #endif
复制代码
所以当物理内存大于896M且内核开启了CONFIG_HIGHMEM,ioremap传入的phys_addr参数可以为高端的ram地址(当然大部分IO空间本身就处于高端RAM地址范围中)

论坛徽章:
0
4 [报告]
发表于 2010-06-01 04:30 |只看该作者
回复 3# new_learner


    没有什么RAM空间一说。空间都是指的寻址,前面加的RAM指的是实实在在的存储介质,我觉得你想说的是MEM空间。所谓mem空间和io空间的区别就是:
(在x86上)
mem空间:mov,add等指令当操作码是一个地址时,那么这条指令寻址的是mem空间。32位,其实也是常说的物理地址空间,总线地址空间等
i/o空间:只有in,out等指令寻址的地址是i/o空间。16位

现在的linux几乎只有一些遗留设备(并口貌是是一个)占用的i/o空间,还有一些vga的寄存器也是占用的i/o空间以外,绝大大部分设备都是被北桥映射到mem空间,不然你在代码中访问它们的寄存器时是用的就是out而非mov了。所以4G的mem空间不仅会被实实在在的ram介质占用,还有各种device的寄存器等可读写资源等,ioremap根本就不管你映射的是什么,只要是mem空间就行了。

论坛徽章:
0
5 [报告]
发表于 2010-06-01 09:42 |只看该作者
回复  new_learner


    没有什么RAM空间一说。空间都是指的寻址,前面加的RAM指的是实实在在的存储介 ...
snail_314 发表于 2010-06-01 04:30



我完全同意你的看法
我没表达清楚。。。

看下这本书《Intel&reg; 64 and IA-32 Architectures Software Developer's Manual Volume 1 Basic Architecture》的"CHAPTER 13 INPUT/OUTPUT"就更清楚了,呵呵。

论坛徽章:
0
6 [报告]
发表于 2010-06-01 23:05 |只看该作者
从2楼开始,把我想说的全说完鸟。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP