我如果能在内核中很方便地使用HIGHUSER内存该有多好...一个例子

简介:

话说用户态访问内核内存很简单,将这块内核内存映射到用户地址空间即可。依托一个字符设备,实现其mmap回调函数,在用户进程打开那个设备,mmap之,很容易实现用户进程直接访问内核内存。
       但是反过来呢?内核访问用户内存。理论上也很简单,因为所有进程的内核态地址空间都是共享的,所以想访问哪个进程的内存,就切换到那个进程的地址空间,这 将丝毫不会影响当前的执行流。事实上也是这么简单,use_mm就是干这个的,不过既然要切换地址空间,那么当前task的地址空间就必须是明确的,因此 就不能在任意上下文调用use_mm(这从user mm会缺页导致睡眠之外的另一个视角说明了任意上下文不好调用use_mm)。但是这么用的很少,AIO算一个,以至于use_mm竟然没有被 EXPORT出来...不过有办法。我写了一个例子

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kthread.h>

int exit_ = 0;

/*
 * 我所测试的内核版本太老,老到下面两个API还没有被导出。
 * (还没有被导出的符号可以叫做API吗??)
 * 在2.6.34内核版本and newer,就可以直接使用了
 **/
void (*use_mm)(struct mm_struct *mm);
void (*unuse_mm)(struct mm_struct *mm);

static int main_loop(void)
{
    struct task_struct *t = NULL;
    while (exit_) {
        /* 正确的做法是:pid应该由netlink或者procfs等U/K通信接口告知内核 */
        struct pid *pid = find_get_pid(3881);
        t = pid_task(pid, PIDTYPE_PID);
        if (t) {
            /* 正确的做法是:内存指针应该通过U/K通信接口告知内核 */
            char *pshare = (char *)0x22d7010;
            struct mm_struct *mm = t->mm;
            /* 
             * 注意!这是在具体的task上下文而不是任意上下文,否则use_mm就不行!
             * 因为用户内存是可被换出的,也是可能缺页的,缺页的处理可能会睡眠
             * 所以不要指望在网络协议栈接收/发送软中断中进行用户内存的操作,除非
             * 你能确认它们处在task上下文。
             **/
            use_mm(mm);
            /* 
             * 访问用户进程的内存
             * 这里仅仅是一个最简单的例子,事实上,在这里可以任意的像在用户进程自身一样
             * 访问这个地址空间,关键是你要知道符号名称以及位置,这需要设计一个机制,使
             * 符号的位置可以映射到一个名称...
             *
             * 此时,只要用户进程维护一个内存表,该内存表的物理内存当然可以在HIGHUSER区域
             * 被分配!实际上这只是一块虚拟地址空间,缺页中断会映射物理内存。
             *
             * 最好存些什么呢?我知道,在这里-内核空间可以访问sqlite数据库了...
             **/
            printk("kernel info:%s  %p\n", pshare, pshare);
            unuse_mm(mm);
        }  
        schedule_timeout(1000);
    }  
    return 0;
}

static int __init tt_init(void)
{
    exit_ = 1;
    struct task_struct *tsk;
    /* 不要直接用kernel_thread创建内核线程,而应该委托专门的线程来做这件事 */
    /* pid = kernel_thread(test_it, NULL, SIGCHLD); */
    tsk = kthread_run((void *)main_loop, NULL, "KERNEL-ACCESS-USER");
    if (IS_ERR(tsk)) {
        return -1;
    }
    /* 由于接口没有导出,下面的信息来自/proc/kallsyms,
     * 但是起码也要通过模块参数传递过来吧 ...
     **/
    use_mm = 0xffffffff810c7282;
    unuse_mm = 0xffffffff810c7240;
    return 0;
}

static void tt_cleanup(void)
{
    exit_ = 0;
    return;
}

module_init(tt_init);
module_exit(tt_cleanup);
MODULE_LICENSE("GPL");


配合一个用户态程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
        char *pshare = (char *)calloc(1, 32);
        strcpy(pshare, "kernel can read!");
        while(1) {
                sleep(1);
                printf("user info:%s    %p\n", pshare, pshare);
        }
}


我在先运行了用户态程序test之后,获取它的pid为3881,pshare指针地址为0x22d7010,我将这两个值写入内核模块,编译,加载,然后内核就可以和用户态进程共享这块内存了。当然,标准的做法肯定没有这么龌龊,我只是写点代码...



 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1601783

相关文章
|
4月前
|
算法 安全 Linux
探索Linux内核的虚拟内存管理
【5月更文挑战第20天】 在本文中,我们将深入探讨Linux操作系统的核心组成部分之一——虚拟内存管理。通过剖析其关键组件和运作机制,揭示虚拟内存如何提供高效的内存抽象,支持庞大的地址空间,以及实现内存保护和共享。文章将重点讨论分页机制、虚拟内存区域(VMAs)的管理、页面置换算法,并简要分析这些技术是如何支撑起现代操作系统复杂而多变的内存需求的。
|
12天前
|
算法 安全 UED
探索操作系统的内核空间:虚拟内存管理
【7月更文挑战第50天】 在现代操作系统中,虚拟内存管理是核心功能之一,它允许操作系统高效地使用物理内存,并为应用程序提供独立的地址空间。本文将深入探讨操作系统虚拟内存管理的机制,包括分页、分段以及内存交换等关键技术,并分析它们如何共同作用以实现内存的有效管理和保护。通过理解这些原理,读者可以更好地把握操作系统的内部工作原理及其对应用程序性能的影响。
|
4月前
|
机器学习/深度学习 算法 Linux
xenomai内核解析--实时内存管理--xnheap
Xenomai是一个实时操作系统(RTOS)层,用于Linux,旨在提供确定性的任务调度和服务。其内存管理机制包括一个名为xnheap的内存池,确保内存分配和释放的时间确定性,以满足硬实时系统的严格需求。
127 0
xenomai内核解析--实时内存管理--xnheap
|
4月前
|
缓存 算法 安全
探索Linux内核的虚拟内存管理
【5月更文挑战第29天】 在现代操作系统中,虚拟内存是支持多任务处理和内存保护的关键组件。本文深入分析了Linux操作系统中的虚拟内存管理机制,包括其地址空间布局、分页系统以及内存分配策略。我们将探讨虚拟内存如何允许多个进程独立地访问它们自己的地址空间,同时由操作系统管理物理内存资源。此外,文章还将涉及虚拟内存所带来的性能影响及其优化方法。
|
4月前
|
算法 安全 Linux
深度解析:Linux内核内存管理机制
【4月更文挑战第30天】 在操作系统领域,内存管理是核心功能之一,尤其对于多任务操作系统来说更是如此。本文将深入探讨Linux操作系统的内核内存管理机制,包括物理内存的分配与回收、虚拟内存的映射以及页面替换算法等关键技术。通过对这些技术的详细剖析,我们不仅能够理解操作系统如何高效地利用有限的硬件资源,还能领会到系统设计中的性能与复杂度之间的权衡。
|
4月前
|
缓存 运维 算法
深入理解Linux内核的虚拟内存管理
【5月更文挑战第6天】 在现代操作系统中,尤其是类Unix系统如Linux中,虚拟内存管理是一项核心功能,它不仅支持了多任务环境,还提供了内存保护和抽象。本文将深入探讨Linux操作系统的虚拟内存子系统,包括分页机制、虚拟地址空间布局、页面置换算法以及内存分配策略。通过对这些概念的剖析,我们旨在为读者揭示Linux如何有效地管理和优化物理内存资源,并确保系统的稳定运行与高效性能。
|
4月前
|
缓存 监控 算法
Linux内核的SLAB内存管理机制
Linux内核的SLAB内存管理机制
246 4
|
12天前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
|
2月前
|
存储 分布式计算 Hadoop
HadoopCPU、内存、存储限制
【7月更文挑战第13天】
126 14
|
2天前
|
存储 监控 Docker
如何限制docker使用的cpu,内存,存储
如何限制docker使用的cpu,内存,存储

热门文章

最新文章

下一篇
云函数