【问题标题】:All the drivers in Linux works in the same context or in a different contexts?Linux 中的所有驱动程序都在相同的上下文中工作还是在不同的上下文中工作?
【发布时间】:2013-11-22 10:21:54
【问题描述】:

Linux 中的所有驱动程序都运行在相同的上下文中(内核空间的地址空间),还是各自运行在不同的上下文中(类似于不同进程如何在用户空间的不同地址空间中工作)?

【问题讨论】:

    标签: c linux linux-kernel kernel virtual-address-space


    【解决方案1】:

    在 32 位 x86-Linux 中,所有驱动程序都在所谓的内核模式下运行(有时称为 Ring 0 模式,因为英特尔组织其 CPU 保护方案的方式)。 当进程调用驱动程序时(例如,您向设备驱动程序发出read() 系统调用),驱动程序内部有一个函数会被执行。该函数被称为在该进程的上下文中执行

    这意味着驱动函数在调用进程的内存映射中执行。这意味着驱动函数不仅可以访问存储在内核保留地址(虚拟地址 0xC0000000 及以上)中的自己的变量和结构,还可以访问用户调用进程的变量和代码。这使得copy_to_user()copy_from_user() 等函数能够与用户调用进程交换信息。

    回想一下,Linux 中任何进程的内存映射都包含两部分:用户进程可用的最大 3GB 内存中的一大部分。该内存对于该进程是私有的。 1GB 的另一部分用于内核。这部分在所有用户进程的内存映射之间共享。驱动程序的代码、堆栈和全局变量驻留在这 1GB 空间内。

    还有另一个上下文:中断上下文。 Linux 驱动程序可以为硬件中断安装处理程序。当这个中断被触发时,处理程序被执行,但这一次,它将在当时正在执行的任何进程的上下文中执行(即处理程序尚未从用户进程中调用)

    典型的驱动程序是函数的集合,它们中的大多数是根据用户进程发出系统调用的请求执行的,所以大多数时候,驱动程序正在执行(实际上是它的一个实例)在特定用户进程的上下文中(但与用户进程中的代码不同,驱动程序以所有权限执行)。驱动程序的某些部分可能被其他内核函数异步调用,因此它们可能在另一个上下文中执行,与属于使用驱动程序的进程的上下文无关。

    还请记住,可能有多个用户进程在使用驱动程序,因此每个进程在其自己的上下文中执行相同的代码。应该编写驱动程序以便可以重新输入,从而避免副作用。

    【讨论】:

    • 非常感谢!但是有两个澄清:1.“这意味着驱动函数不仅可以访问它自己的变量和存储在内核保留地址(虚拟地址 0xC0000000 及以上)中的结构......” - 内核保留地址位于 0xC0000000 及以上,或 0x0 - 0xC0000000?
    • 2. "** 处理程序已被执行,但这一次,它将在当时正在执行的任何进程的上下文中执行**" - 是吗意味着中断的处理程序可以访问某些上下文的数据,或者它不能 - 即处理程序被执行,但它不会在任何进程的任何上下文中执行,而此时正在执行?
    • 在进程上下文中运行的驱动程序可以访问分配给该进程的所有内存,除了它自己的(内核)内存。
    • 好的,但是硬件中断是由硬件发生的,而不是由来自用户空间的任何进程发生的。
    • 中断上下文意味着处理程序正在一个未知的进程上下文中执行(以中断到达时正在执行的那个为准)。可能与当前与驱动程序交互的用户进程的上下文不同(并且其操作可能导致设备生成中断)。在编写设备驱动程序时,假设如果一个进程打开了一个驱动程序,驱动程序中的每个函数,包括中断处理程序,都可以访问用户进程的内存,这是一个常见的错误。中断到达时,用户进程可能已被换出。
    猜你喜欢
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 2015-09-30
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    相关资源
    最近更新 更多