Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Linux的虚拟地址空间也为
0~4G。Linux内核将这4G字节的空间分为两部分。将最高的1G字节(从虚拟地址0xC0000000到
0xFFFFFFFF),供内核使用,称为"内核空间".而将较低的3G字节(从虚拟地址 0x00000000到
0xBFFFFFFF),供各个进程使用,称为"用户空间")。因为每个进程可以通过系统调用进入内核,
因此,Linux内核由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G
字节的虚拟空间。
Linux使用两级保护机制:0级供内核使用,3级供用户程序使用。每个进程有各自的私有用户
空间(0~3G),这个空间对系统中的其他进程是不可见的。最高的1GB字节虚拟内核空间则为所有
进程以及内核所共享。
内核空间中存放的是内核代码和数据,而进程的用户空间中存放的是用户程序的代码和数据。
不管是内核空间还是用户空间,它们都处于虚拟空间中。
虽然内核空间占据了每个虚拟空间中的最高1GB字节,但映射到物理内存却总是从最低地址
(0x00000000)开始。对内核空间来说,其地址映射是很简单的线性映射。
0xC0000000就是物理地址与线性地址之间的位移量,在Linux代码中就叫做PAGE_OFFSET.
=========================================================================
在嵌入式系统中,PAGE_OFFSET也是可配置的,比如修改为
CONFIG_PAGE_OFFSET=0x80000000,那么在压缩内核的工具中就需要做相应的修改,比如是
vmlinux,使用mkimage工具压缩#./mkimage -A ARM-O linux -T kernel -C gzip -a 0x80800000 -e
0x80801000 -n "Linux 2.6" -d vmlinux.bin.gz vmlinux.ub。PAGE_OFFSET后偏移8M是留做其他
用途,根据具体芯片设计的要求来改就可以了。
=========================================================================
PAGE_OFFSET 代表的是内核空间和用户空间对虚拟地址空间的划分,不同的体系结构定义
和值都不同。比如在32位系统中3G-4G属于内核使用的内存空间,所以 PAGE_OFFSET =
0xC0000000。在X86-64架构下是ffff880000000000。可以看到内核程序可以可以访问从
PAGE_OFFSET 之后的内存。