在bootloader过程中,内核会被调入到物理地址0x100000(1M),开始执行的是head.S,
在这段指令的执行中,Paging会被激活,之后内核跳到PAGE_OFFSET+some_address,开始执行start_kernel
(start_kernel()将不会执行,直到Paging被激活??)。start_kernel()会初始化所有的内核数据,并且开始init内核
线程的运行。对MMU的初始化,是在setup_arch()里完成的,这个函数是平台相关的,主要完成底层的初始化,首先,此函数会计算总共的Low-
memory和High-memory的页数(在setup_memory()里完成),接下来,setup_arch()调用init_bootmem
()来初始化boot-time内存分配器(也称之为bootmem分配器),此分配器的工作是为内核的初始化和永久数据提供内存页,在boot之后,这
些页是不参与MMU的管理的。 (如果这些页是固定地址的,地址是如何分配的??)
在setup_arch()里,内核页表的初始化是调用paging_init()完成的。首先,内核尽可能地将所有的物理内存影射到
PAGE_OFFSET(3G)与4G之间。内核页表是存在于swapper_pg_dir,是表示一种影射关系,也称之为内核页目录。目录里的页主要用
于初始化Paging,在系统启动的时候。
接一下来,内核调用fixrange_init()来分配一些页表给预编译阶段就所需的虚存,其方法是set_fixmap(). 这些fixmap表会在运行时被影射到物理页上。
初始化fixmaps后,如果CONFIG_HIGHMEM被设置,内核会分配一些页表给kmap()分配器。kmap()分配器可以让内核映射任意物理页到内核虚拟地址空间,作为临时使用。
fixmap和kmap页表占据了内核虚拟空间里最顶端的部分,有最大128M在内核虚空间的顶部将为此保留。所以,所有物理页其被映射后的虚存地址如果
高于4G-128M(即如果访问大于896M的物理内存),将会当作HIGHMEM
zone的操作来处理(当然,前提是CONFIG_HIGMEM开关被打开)。内核访问HIGHMEM的页,需要通过kmap()来存取。如果
CONFIG_HIGMEM开关未打开,这部分物理页将访问不到,只是浪费而已,对2.4的最近版本,此开关是缺省打开的。
最后,对kmap/zone分配器进行初始化,然后是调用free_area_init()建立mem_map和Buddy free_lists, 此时,所有的free_list项都被初始化成空,并且标记为保留(即暂时VM还不能存取??)
3.
setup_arch()是在start_kernel()里被调用的,paging_init()是在setup_arch()被调用,当
paging_init()结束后,其他的一些内核子系统会继续用bootmem分配器申请一些内核内存段...,之后,Buddy
free_lists的保留状态标记将被清除,并释放所有可用的内存页在他们相应的Zone里,最后,free_all_bootmem()被调用,所有
被bootmem分配器申请的虚拟页将释放到他们相应的Zone里去。
4. Page Swap and Cache
A user process page is kept in either the page cache or the swap
cache, the kernel tries to keep as much as pages remain in the memory,
so that page faults can be serviced quickly, but, physical memory is
always limited resources, thus, swap cache can be a better-than-none
replacement.
Logically, the cache is a layer between the kernel memory
management code and the disk I/O code. Practically, the cache here
means, only freeing the memoryhas to be necessary, we swap the pages
to disk, otherwize, keeping the pages as long as they can.
The kernel maintains several page lists which comprise the whole page cache:
1. active_list: pages on the list have page->age > 0, may be
clean or dirty, and may be mapped by process page-table entries.
2. inactive_dirty_list: pages on the list have page->age == 0, may be clean or dirty, and are not mapped by any process PTE.
3. inactive_clean_list: each zone has its own inactive_clean_list,
which contains clean pages whose age == 0, not mapped by any process
PTE.
When a page fault isoccurred, the kernel first looks forthe
fault page in the page cache, if found, it can be moved directly to the
active_list.
Overall, the kernel performs the page replacement more like "not
recently used", rather than strict LRU. Furthermore, each page either
for an executable image or mmap()ed file is associated with a per-inode
cache, allowing the disk file to be used as backing storage for the
page. For those anonymous pages(i.e. the pages like malloc()ed memory)
are assigned an entry in the system swap file, and those pages are
maintained in the swap cache.
The life cycle of a user page:
1. Page loading, there are three ways that can lead to a page loaded from the disk.
a. The process attempts to access the page, it is then read in
by the page-fault handler and added to the page cache and to the
process page table.
b. The page is read in during a swap read-ahead operation. The
reason is simple as a cluster of blocks on disk is easy to read
sequentially.
c. The page is read in during a mmap cluster read-ahead
operation, in which case a sequential of adjacent pages following the
fault page in a mmaped file is read.
2. when the page is written by the process, it becomes dirty. At this point, the page is still on the active_list.
3. suppose the page is not used for a while, thus the page->age
count is gradually reduced by the periodic invocations(actually, the
prime is refill_inactive()) of the kernel swap daemon kswapd(). The
frequence of kswapd() invocations will increase as the memory pressure
increases.
4. if the physical memory is tight, kswapd() will call swap_out()
to try to evict pages from the process'svirtualaddress space.Since
the page hasn't been referenced and has age 0, the PTE will be dropped,
and the only remaining reference tothe pageis the one resulting from
its presence in the page cache (assuming, of course, that no other
process has mapped the file in the meantime). swap_out() does not
actually swap the page out; rather, it simply removes the process's
reference to the page, and depends upon the page cache and swap
machinery to ensure the page gets written to disk if necessary. (If a
PTE has been referenced when swap_out() examines it, the mapped page is
agedup - made younger - rather than being unmapped.)
5. Time passes... a little or a lot, depending on memory demand.
6. refill_inactive_scan() comes along, trying to find pages that
can be moved to the inactive_dirty list. Sincethe pageis not mapped
by any process and has age 0, it is moved from the active_list to the
inactive_dirty list.
7. Process A attempts to access the page, but it's not present in
the process VM since the PTE has been cleared by swap_out(). The fault
handler calls __find_page_nolock() to try to locatethe pagein the
page cache, and lo and behold, it's there, so the PTE can be
immediately restored, and the page is moved to the active_list, where
it remains as long as it is actively used by the process.
8. More time passes... swap_out() clears the process 's PTE for
the page, refill_inactive_scan() deactivates the page, moving it to the
inactive_dirty list.
9. More time passes... memory gets low.
10. page_launder() is invoked to clean some dirty pages. It finds
P on the inactive_dirty_list, notices that it's actually dirty, and
attempts to write it out to the disk. When the page has been written,
it can then be moved to the inactive_clean_list. The following sequence
of events occurs when page_launder() actually decides to write out a
page:
* Lock the page.
* We determine the page needs to be written, so we call the writepage
method of the page's mapping. That call invokes some
filesystem-specific code to perform an asynchronous write to disk with
the page locked. At that point, page_launder() is finished with the
page: it remains on the inactive_dirty_list, and will be unlocked once
the async write completes.
* Next time page_launder() is called it will find the page clean
and move it to the inactive_clean_list, assuming no process has found
it in the pagecache and started using it in the meantime.
11. page_launder() runs again, finds the page unused and clean, and moves it to the inactive_clean_list of the page's zone.
12. An attempt is made by someone to allocate a single free page
fromthe page'szone. Since the request is for a single page, it can be
satisfied by reclaiming an inactive_clean page;The pageis chosen for
reclamation. reclaim_page() removesthe pagefrom the page cache
(thereby ensuring that no other process will be able to gain a
reference to it during page fault handling), and it is given to the
caller as a free page.
Or:
kreclaimd comes along trying to create free memory. It reclaimsthe pageand then frees it.
Note that this is only one possible sequence of events: a page can
live in the page cache for a long time, aging, being deactivated, being
recovered by processes during page fault handling and thereby
reactivated, aging, being deactivated, being laundered, being recovered
and reactivated...
Pages can be recovered from the inactive_clean and active lists as
well as from the inactive_dirty list. Read-only pages, naturally, are
never dirty, so page_launder() can move them from the
inactive_dirty_list to the inactive_clean_list "for free," so to speak.
Pages on the inactive_clean list are periodically examined by the
kreclaimd kernel thread and freed. The purpose of this is to try to
produce larger contiguous free memory blocks, which are needed in some
situations.
Finally, note thatthe pageis in essence a logic page, though of course it is instantiated by some particular physical page.
相关推荐
ARM linux S3C2410 source code about mmu part.
Linux MMU 研究,主要阐述虚拟地址到物理地址的映射机制
清华大学-电子信息工程系-实验用ARM-linux-源代码-MMU篇
关于MMU的作用的讨论 关于MMU的作用的讨论
at91sam9263 Bootstrap uboot 到linux MMU 深入分析
GPRS arm920t 2410 mmu初始化
A9的MMU页表是由linux管理和创建的,ARM11运行的是rtthreaed,MMU页表是在系统启动前预先创建好的。ARM11属于ARMv6架构,其MMU需要两级页表来映射物理地址,第一级页表为段映射,一个页表条目表示1M空间;第二级页表...
Linux 虚拟内存管理的文档,详细描述了linux内存管理的具体细节
MMU、ELF的加载、linux的启动 文档
xtensa mmu stuff for Embedded Linux.
ARM芯片 mmu 详细资料
k210-linux-nommu简介这是一个面向初学者的教程,主要介绍如何编译内核以在k210上运行NOMMU linux。 并且,本教程将展示如何交叉编译tcc,以便您可以执行C k210-linux-nommu。简介这是面向初学者的教程,主要介绍...
本文针对Linux操作系统的内存管理机制设计了一款在TLB不命中时自动查询页表,填充TI B的MMU,并为它设 计了一条专门的验证、调试平台.经仿真验证后,本文所设计的MMU能很好的和Linux配合,高效的完成虚拟地址和物理...
wince MMU实现原理,wince MMU实现原理,wince MMU实现原理,
让你更深入的理解MMU的工作原理,有利于你理解MMU。
本文介绍了MMU的概念及相关原理,并引出了MMU与CACHE的区别和对比,深入剖析了二者的不同点。适合那些对MMU于CACHE不太了解的同学
ARM中MMU工作原理 ARM中MMU工作原理 ARM中MMU工作原理
MIPS的MMU工作原理,包括MIPS各个地址空间段的介绍,自己总结的资料,希望对大家有帮助
MMU的详细资料和DATA,还是不错的哦!
unix s3c2410 linux hard mmu 操作 代码