访问用户态内存
copy_from_user和copy_to_user这两个函数相信做内核开发的人都非常熟悉,分别是将用户空间的数据拷贝到内核空间以及将内核空间中的数据拷贝到用户空间。
copy_from_user
该函数的功能就不只是从用户空间拷贝数据那样简单了,它还要做一些指针检查以及处理这些问题的方法。
内核文件http://lxr.linux.no/linux+v5.4.90/Documentation/arm64/memory.rst中展示了用户空间和内核空间。
AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit)::
30
31 Start End Size Use
32 -----------------------------------------------------------------------
33 0000000000000000 0000ffffffffffff 256TB user
34 ffff000000000000 ffff7fffffffffff 128TB kernel logical memory map
35 ffff800000000000 ffff9fffffffffff 32TB kasan shadow region
36 ffffa00000000000 ffffa00007ffffff 128MB bpf jit region
37 ffffa00008000000 ffffa0000fffffff 128MB modules
38 ffffa00010000000 fffffdffbffeffff ~93TB vmalloc
39 fffffdffbfff0000 fffffdfffe5f8fff ~998MB [guard region]
40 fffffdfffe5f9000 fffffdfffe9fffff 4124KB fixed mappings
41 fffffdfffea00000 fffffdfffebfffff 2MB [guard region]
42 fffffdfffec00000 fffffdffffbfffff 16MB PCI I/O space
43 fffffdffffc00000 fffffdffffdfffff 2MB [guard region]
44 fffffdffffe00000 ffffffffffdfffff 2TB vmemmap
45 ffffffffffe00000 ffffffffffffffff 2MB [guard region]
46
47
48AArch64 Linux memory layout with 64KB pages + 3 levels (52-bit with HW support)::
49
50 Start End Size Use
51 -----------------------------------------------------------------------
52 0000000000000000 000fffffffffffff 4PB user
53 fff0000000000000 fff7ffffffffffff 2PB kernel logical memory map
54 fff8000000000000 fffd9fffffffffff 1440TB [gap]
55 fffda00000000000 ffff9fffffffffff 512TB kasan shadow region
56 ffffa00000000000 ffffa00007ffffff 128MB bpf jit region
57 ffffa00008000000 ffffa0000fffffff 128MB modules
58 ffffa00010000000 fffff81ffffeffff ~88TB vmalloc
59 fffff81fffff0000 fffffc1ffe58ffff ~3TB [guard region]
60 fffffc1ffe590000 fffffc1ffe9fffff 4544KB fixed mappings
61 fffffc1ffea00000 fffffc1ffebfffff 2MB [guard region]
62 fffffc1ffec00000 fffffc1fffbfffff 16MB PCI I/O space
63 fffffc1fffc00000 fffffc1fffdfffff 2MB [guard region]
64 fffffc1fffe00000 ffffffffffdfffff 3968GB vmemmap
65 ffffffffffe00000 ffffffffffffffff 2MB [guard region]
copy_from_user函数失败返回没有被拷贝的字节数,成功返回0.
copy_from_user(void *to, const void __user *from, unsigned long n)
1. to 将数据拷贝到内核的地址
2. from 需要拷贝数据的地址
3. n 拷贝数据的长度(字节)
也就是将@form地址中的数据拷贝到@to地址中去,拷贝长度是n