前言
copy_from_user和copy_to_user这两个函数相信做内核开发的人都非常熟悉,分别是将用户空间的数据拷贝到内核空间以及将内核空间中的数据拷贝到用户空间。这两个函数一般用于系统调用中,前者将用户空间参数拷贝到内核,后者将系统用的结果返回到用户空间。
用户空间和内核空间
Linux将地址空间分为用户空间和内核空间,内核文档Documentation/arm64/memory.txt中定义了内核地址空间和用户地址空间的范围,比如4K Page +4 level页表时,地址空间分布如下:
AArch64 Linux memory layout with 4KB pages + 4 levels:
Start End Size Use
-----------------------------------------------------------------------
0000000000000000 0000ffffffffffff 256TB user
ffff000000000000 ffffffffffffffff 256TB kernel
用户空间占用低地址,内核空间占用高地址。
用户态和内核态地址空间访问权限
这个问题,做个内核开发的人也一定非常清楚,用户态只能访问用户空间,内核态可以访问用户空间和内核空间。那么在ARM64架构下这是如何实现的呢?
首先,ARM64定义了多种地址转换策略,即translation regime。而Linux内核选择的地址转换策略是Non-secure EL1&0 translation regime,如下图所示: