用于基本数据types的copy_to_user()和copy_from_user()

我正在写一个Linux内核驱动程序,并为每个函数发送数据到用户空间或从用户空间读取数据,我使用copy_to_user()和copy_from_user()。 我的问题是:我是否需要使用这些调用,如果我只是复制一个基本的数据types,如u32或int?

如果函数接收到用户空间数据的指针 ,则必须使用copy_from_user()将用户空间中指向的数据复制到内核空间(反之亦然)。

请注意,指针值本身是通过值传递的(就像所有的C参数一样),所以在copy_from_user()指向的数据copy_from_user()之前,不需要做copy_from_user()来获取指针值。

数字参数的工作方式与指针参数相同。 用C术语来说,它们都是标量。 您不必使用copy_from_user()来复制参数的值; 那已经被复制了。 您只需要使用它来复制由传递的指针指向的数据。

所以如果你有一个int类型的参数,你可以直接使用它。 如果你的参数指向一个int ,那么int对象将在用户空间中,你需要使用copy_to_user将该对象的值复制到内核空间。

当用户将数据传递给内核空间时,可以将这些数据拆分成多个页面,这些页面甚至可以被换出内存 。 在这些情况下,你必须等待内核在页面中交换并访问数据所在的页面。对于基本数据类型(比如int或者指针),也可以使用一些体系结构(特别是x86英特尔)不强制用户对齐数据,所以即使是一个整数也可以围绕页面边界分开。 你可以访问你的第一部分整数,但等待第二个被内存管理器交换之前整个访问。

通过将所有用户数据放在一个指针传递给内核的结构中,可以节省一些往返。 你可以copy_from_user作为一个块,并保存访问(并冒着被阻止几次的风险)

所以,作为一个结论, 即使对于基本类型也使用这些函数 ,因为它们有很多。 在内核模式下运行时,不要假设用户数据的位置。 您可以访问它,但用户数据的内核虚拟地址与在用户模式下看到的虚拟地址无关。