Chinaunix

标题: 如何将linux kernel指定的一段内存设置为只读 [打印本页]

作者: gong_yue    时间: 2014-12-09 17:56
标题: 如何将linux kernel指定的一段内存设置为只读
有谁指定如何将arm linux内核中的一段内存设置为只读?
多谢!!!
作者: arm-linux-gcc    时间: 2014-12-09 22:39
你想要将那段内存设置为只读?
作者: gong_yue    时间: 2014-12-10 09:02
自定义的一段缓冲区
作者: arm-linux-gcc    时间: 2014-12-10 12:56
这个缓冲区是动态分配的还是静态保留的?
作者: gong_yue    时间: 2014-12-10 15:38
静态保留的一段内存。
作者: arm-linux-gcc    时间: 2014-12-10 23:31
本帖最后由 arm-linux-gcc 于 2014-12-11 14:37 编辑

回复 5# gong_yue


    静态保留的又分为两种,事先知道虚拟地址的和事先不知道虚拟地址的


前者可以在paging_init阶段就建立为只读的,具体参考android的kernel,搜索CONFIG_DEBUG_RODATA





对于事先不知道虚拟地址的,一般都是通过mmap来使用
那么在mmap时,参数prot不要设置PROT_WRITE就能够设置为只读的(只设置PROT_READ)





作者: gong_yue    时间: 2014-12-11 09:41
我的需求是在内核中定义了一个全局的缓冲区如:
char buf[4096];
将这段缓冲区设置为只读的,安照你的方法使用mmap是直接调用remap_pfn_range函数吗?
多谢!!!
作者: arm-linux-gcc    时间: 2014-12-11 14:42
回复 7# gong_yue


    呃,这种保留的buffer不能用mmap的方法来设置只读,mmap只适合知道物理地址的情况,并且是设置为app访问这片物理内存时是只读的
你这种直接在内核中定义全局数组的方式,那么就属于内核空间了,我再看一下代码给你回答


作者: hejianet    时间: 2014-12-11 21:50
是让内核只读,还是让用户空间只读?
作者: gong_yue    时间: 2014-12-15 10:47
内核只读。
作者: hejianet    时间: 2014-12-15 11:39
不知道用内联汇编定义rodata section能否满足你的需求
作者: Tinnal    时间: 2014-12-15 21:39
回复 10# gong_yue

内核没有直接把内核所在内存更改为只读的函数,但可以同通过set_pte来更改对应的页表项来实现。前提必须找到对应的页表项,可以通过pxx_offeset来实现,如果你是X86的,那就方便一点,有人给你写好了--lookup_address。

整个过程,其实和kmemcheck相做的类似。可以参考一下它的实现:
  1. void kmemcheck_hide_pages(struct page *p, unsigned int n)
  2. {
  3.         unsigned int i;

  4.         for (i = 0; i < n; ++i) {
  5.                 unsigned long address;
  6.                 pte_t *pte;
  7.                 unsigned int level;

  8.                 address = (unsigned long) page_address(&p[i]);
  9.                 pte = lookup_address(address, &level);
  10.                 BUG_ON(!pte);
  11.                 BUG_ON(level != PG_LEVEL_4K);

  12.                 set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT));
  13.                 set_pte(pte, __pte(pte_val(*pte) | _PAGE_HIDDEN));
  14.                 __flush_tlb_one(address);
  15.         }
  16. }
复制代码
对你这个需求,你要去掉的是_PAGE_RW,而不是_PAGE_PRESENT。
还是比较简单的。

但的两点要注意。
1. 你的数组必须页对齐
2. 要搞清楚你的内核是采用大页还是小页。





   
作者: Tinnal    时间: 2014-12-15 21:42
看了一下,一下午了,论坛都没有人发贴了。很安静,安静得令人恐怖。
作者: gong_yue    时间: 2014-12-17 09:54
回复 13# Tinnal


    非常感谢回复!!!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2