http://blog.chinaunix.net/uid-20514606-id-350141.html
*.地址空间的布局
okl4 3.0 地址空间 (arch\arm\pistachio\include\Config.h)
low addr
0x00000000 ----------------------
(14/16 ,3.54G) l4 user space
0xE0000000 ----------------------
(1/16,256M) KTCBs 18bits for thread id
#define UTCB_AREA_START USER_AREA_END
0xF0000000 ----------------------
(1/16,256M) (128M)kernel code and structures(CPD,root page table,bootstack)(128)
(64M) space for the copy area
(16M) store variables for space_t (kip_area,utcb_area=0xff000ff0
thread_count , domain )
(47M) for IO space mappings
(1M) reserved for mapping in the exception vectors
0xFFFFFFFF -----------------------
high addr
但实际最后一段0xf0000000开始256M:
/* 0xf0000000 64M kernel code and structures(CPD,root page table,bootstack) */
/* 0xf4000000 64M space for the copy area */
/* 0xf8000000 16M store variables for space_t */
/* 0xf9000000 96M for IO space mappings */
/* 0xff000000 15M misc area for UTCB reference page
* We reserve the next (14) entries for the UTCB used bit
* array. This limits us to 420 threads per space ( 14 * 30 used bits )
* { we can't use the bottom two bits in the pt entries, they must be 0 }
*
armv4,v5 =>#define USER_UTCB_REF (*(word_t *)(USER_UTCB_PAGE + 0xff0))
=0xff00 0ff0
15个section 14个section, 每个pte 30bit 做used flag !!!
其中第1个section entry 做USER_UTCB_REF 地址0xff000ff0
ref 只是当前utcb, 其实每个space 都有utcb array,包含若干utcb(max 420 see above)*/
/* 0xfff00000 1M Except page */
到了oklinux 中 l4 user space 又被分为 oklinux kernel 和 user 部分
小于#define TASK_SIZE 0x7fff8000UL 以下部分为 oklinux user space
* bootmem init
内存bootmem init :
在native 中这部分内存设置是从u-boot 传递过来的
而在oklinux 中是从 cell 中分配的:
heap = okl4_env_get_segment("MAIN_HEAP");
目前分配了20M
动态内存大小在oklinux script里设置
if env.name == "oklinux":
cell.set_program(vmlinux,
heap = cell.Heap(size = 20 * 1024 * 1024, attach="rwx"),
stack = 8 * 1024,
args = [command_line]
)
* oklinux 页表及其操作与nlinux的差异
native :
* pgd pte
* | |
* +--------+ +0
* | |-----> +------------+ +0
* +- - - - + +4 | h/w pt 0 |
* | |-----> +------------+ +1024
* +--------+ +8 | h/w pt 1 |
* | | +------------+ +2048
* +- - - - + | Linux pt 0 |
* | | +------------+ +3072
* +--------+ | Linux pt 1 |
* | | +------------+ +4096
但在oklinux 中所谓的shadow 页表中
只包含linux pt ,不包含hw pt ,一方面因为l4 kernel
里已经维护了hw pt,另外也可以节约空间,pt0+pt1多占了2K
操作部分:
* set_pte
1.oklinux asm-l4/pgtable.h
#define set_pte(pteptr, pteval) do { \
pte_t newpte = pteval; \
(*(pteptr)) = (newpte); \
} while (0);
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
2.arch\arm\mm\proc_macros.S
.macro armv6_set_pte_ext pfx
保存2048 到linux pte ,然后-2048,然后设置到硬件pte
* pte flag : oklinux
nlinux
#define _PAGE_VALID 0x001 /* Page is valid */
#define L_PTE_PRESENT (1 << 0)
#define _PAGE_FILE 0x002
#define L_PTE_FILE (1 << 1) /* only when !PRESENT 在文件中*/
#define _PAGE_ACCESSED 0x004 /* Page has been accessed? */
#define L_PTE_YOUNG (1 << 1)
#define _PAGE_DIRTY 0x008
#define L_PTE_DIRTY (1 << 7)
#define _PAGE_EXECUTE 0x010 /* Page is executeable */
#define L_PTE_EXEC (1 << 6)
#define _PAGE_WRITE 0x020 /* Page is writeable */
#define L_PTE_WRITE (1 << 5)
#define _PAGE_READ 0x040 /* Page is readable */
oklinux 有,好象也看到pte_mkread的地方
#define _PAGE_KERNEL 0x080 /* Page is priviledged */
被oklinux #define PAGE_KERNEL __pgprot(_PAGE_VALID | __ACCESS_BITS | __DIRTY_BITS | _PAGE_KERNEL | _PAGE_EXECUTE)
但是nlinux GFP_KERNEL 定义如下
#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS)
#define _PAGE_ATTRIBS 0x300 /* Page attributes, arch specific, 0 = Default */
oklinux 用的设置cache 属性
//_PAGE_ATTRIBS = 0x300 /* Page attributes, arch specific, 0 = Default */
#define _PAGE_NOCACHE 0x100
#define _PAGE_WRITECOMBINE 0x200
#define _PAGE_WRITETHROUGH 0x300
#define _PAGE_MAPPED 0x800 /* Page is mapped in the L4 address space */
改变mmu 上的页(真正操作)
update_mmu_cache => set this flag
#define _PAGE_FLAGS 0xfff /* All the above flags */
nlinux 2.6.24
#define L_PTE_PRESENT (1 << 0)
#define L_PTE_FILE (1 << 1) /* only when !PRESENT */
#define L_PTE_YOUNG (1 << 1)
#define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */
#define L_PTE_CACHEABLE (1 << 3) /* matches PTE */
#define L_PTE_USER (1 << 4) /**/
#define L_PTE_WRITE (1 << 5)
#define L_PTE_EXEC (1 << 6)
#define L_PTE_DIRTY (1 << 7)
#define L_PTE_SHARED (1 << 10) /* shared(v6), coherent(xsc3) */
nlinux 2.6.29
#define L_PTE_PRESENT (1 << 0)
#define L_PTE_FILE (1 << 1) /* only when !PRESENT */
#define L_PTE_YOUNG (1 << 1)
#define L_PTE_BUFFERABLE (1 << 2) /* obsolete, matches PTE */
#define L_PTE_CACHEABLE (1 << 3) /* obsolete, matches PTE */
#define L_PTE_DIRTY (1 << 6)
#define L_PTE_WRITE (1 << 7)
#define L_PTE_USER (1 << 8)
#define L_PTE_EXEC (1 << 9)
#define L_PTE_SHARED (1 << 10) /* shared(v6), coherent(xsc3) */
* copy from(to) user space
(以后有空补上)