如何从用户空间访问内核空间?

用户内存和内核内存在Linux内核中究竟有什么区别 (就内核空间的安全性而言)?

有什么不同的方式可以在用户空间的内核地址空间写入?

我知道的一个方法是通过系统调用 。 有多个系统调用我们可以使用,但最后他们都是系统调用。 即使在系统调用中,我们也发送一个数据到内核空间,在那里它(驱动程序或相应的模块)调用函数copy_from_user()将数据从用户空间复制到内核空间。 这里我们完全没有写入地址空间。 我们只是传递一个包含需要复制到内核缓冲区的数据的用户指针。

我的问题是有什么办法可以访问内核空间中的物理地址,并对其进行操作?

其次, 除了系统调用之外,还有其他的方式可以从用户应用程序写入内核空间吗?

我从stackoverflow引用这个链接 。 但是我觉得我的问题没有在那里回答,而是从不同的angular度来看。 因此我想问一个不同的问题。

请分享你的知识…谢谢。

有什么不同的方式可以在用户空间的内核地址空间写入?

我不确定是否有其他方法,但是可以使用/dev/mem &system call mmap()来访问物理内存。

/ dev / mem是一个字符设备文件,是计算机主内存的映像。 例如,它可以用来检查(甚至打补丁)系统。 mem中的字节地址被解释为物理内存地址。

更多关于/dev/mem : http : //linux.about.com/library/cmd/blcmdl4_mem.htm

更多关于mmap() : http : //linux.die.net/man/2/mmap

您可以使用mmap()映射/dev/mem并在用户程序中使用。 一个简单的示例代码:

 #define MAPPED_SIZE //place the size here #define DDR_RAM_PHYS //place the physical address here int _fdmem; int *map = NULL; const char memDevice[] = "/dev/mem"; /* open /dev/mem and error checking */ _fdmem = open( memDevice, O_RDWR | O_SYNC ); if (_fdmem < 0){ printf("Failed to open the /dev/mem !\n"); return 0; } else{ printf("open /dev/mem successfully !\n"); } /* mmap() the opened /dev/mem */ map= (int *)(mmap(0,MAPPED_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,_fdmem,DDR_RAM_PHYS)); /* use 'map' pointer to access the mapped area! */ for (i=0,i<100;i++) printf("content: 0x%x\n",*(map+i)); /* unmap the area & error checking */ if (munmap(map,MAPPED_SIZE)==-1){ perror("Error un-mmapping the file"); } /* close the character device */ close(_fdmem); 

但是,请确保您正在映射的区域未被使用(例如内核),否则会导致系统崩溃/挂起,您将被迫使用硬件电源按钮重新启动。

希望能帮助到你。

用户内存和内核内存在Linux内核中究竟有什么区别(就内核空间的安全性而言)?

不知道我是否理解你的问题。

内核在技术上没有太大的差别,只是内存。 为什么? 因为运行在最高权限的CPU模式下的内核可以访问所有的内存。

有什么不同的方式可以在用户空间的内核地址空间写入?

除非内核或内核模式设备驱动程序存在安全漏洞,否则至少不能直接执行此操作。 然而,内核(或其驱动程序之一)可能会将数据从用户模式应用程序的内存复制到内核内存。

有什么方法可以访问内核空间中的物理地址并对其执行操作?

同样的事情,如果存在虚拟地址到物理地址的转换,则不能使用物理地址访问内存。 即使内核本身启用后也无法避免这种翻译。 它必须在页表中创建适当的虚拟到物理地址映射来访问任意物理地址的内存。

除了系统调用之外,还有其他的方法可以从用户应用程序写入内核空间吗?

您也可以强制CPU通过触发异常(例如除以0,页面错误,一般保护错误等)切换到内核代码。 内核是第一个处理异常的。 内核将根据需要更改其内存以响应异常。 它可能会从页面错误的某处(例如磁盘)加载数据。