編輯:關於android開發
【版權所有,轉載請注明出處。出處:http://www.cnblogs.com/joey-hua/p/5597705.html 】
Linux內核因為使用了內存分頁機制,所以相對來說好理解些。因為內存分頁就是為了方便管理內存。
說到內存分頁,最根部的要屬頁目錄表了,head.h中:
extern unsigned long pg_dir[1024]; // 內存頁目錄數組。每個目錄項為4 字節。從物理地址0 開始。
然後再看head.s:
/* * head.s 含有32 位啟動代碼。 * 注意!!! 32 位啟動代碼是從絕對地址0x00000000 開始的,這裡也同樣是頁目錄將存在的地方, * 因此這裡的啟動代碼將被頁目錄覆蓋掉。 */ .text .globl _idt,_gdt,_pg_dir,_tmp_floppy_area _pg_dir: # 頁目錄將會存放在這裡。 ...
頁目錄存放的地方是從絕對地址0開始的,接下來分配頁表:
/* Linus 將內核的內存頁表直接放在頁目錄之後,使用了4 個表來尋址16 Mb 的物理內存。 * 如果你有多於16 Mb 的內存,就需要在這裡進行擴充修改。 */ # 每個頁表長為4 Kb 字節(1 頁內存頁面),而每個頁表項需要4 個字節,因此一個頁表共可以存放 # 1024 個表項。如果一個頁表項尋址4 Kb 的地址空間,則一個頁表就可以尋址4 Mb 的物理內存。 # 頁表項的格式為:項的前0-11 位存放一些標志,例如是否在內存中(P 位0)、讀寫許可(R/W 位1)、 # 普通用戶還是超級用戶使用(U/S 位2)、是否修改過(是否髒了)(D 位6)等;表項的位12-31 是 # 頁框地址,用於指出一頁內存的物理起始地址。 .org 0x1000 # 從偏移0x1000 處開始是第1 個頁表(偏移0 開始處將存放頁表目錄)。 pg0: .org 0x2000 pg1: .org 0x3000 pg2: .org 0x4000 pg3: ...
分配了4個頁表空間,因為一個頁表項對應的是一個頁也就是4K,所以一個頁表就是4K*1024=4M,這裡有4個頁表所以就是16M。並且注意這裡是從.org 0x1000開始的,前面4K的空間是留給整個頁目錄的。
下面是設置四個頁目錄項的屬性,因為只有4個頁表,所以相應的就是4個頁目錄項:
# 下面4 句設置頁目錄表中的項,因為我們(內核)共有4 個頁表所以只需設置4 項。 # 頁目錄項的結構與頁表中項的結構一樣,4 個字節為1 項。參見上面113 行下的說明。 # "$pg0+7"表示:0x00001007,是頁目錄表中的第1 項。 # 則第1 個頁表所在的地址 = 0x00001007 & 0xfffff000 = 0x1000; # 第1 個頁表的屬性標志 = 0x00001007 & 0x00000fff = 0x07,表示該頁存在、用戶可讀寫。 movl $pg0+7,_pg_dir /* set present bit/user r/w */ movl $pg1+7,_pg_dir+4 /* --------- " " --------- */ movl $pg2+7,_pg_dir+8 /* --------- " " --------- */ movl $pg3+7,_pg_dir+12 /* --------- " " --------- */
注意這裡+7的意思是,先看PDE 頁目錄項格式 可知,每個頁目錄項的0-11位是屬性,12-31位才是基址,7對應的二進制是111,也就是P、R/W、U/S位都為1.
好,現在頁目錄和4個頁表都分配好了。接下來進入初始化程序mem_init(main_memory_start, memory_end);在main.c和memory.c中:
static long memory_end = 0; // 機器具有的物理內存(字節數)。 static long buffer_memory_end = 0; // 高速緩沖區末端地址。 static long main_memory_start = 0; // 主內存(將用於分頁)開始的位置。 memory_end = (1 << 20) + (EXT_MEM_K << 10); // 內存大小=1Mb 字節+擴展內存(k)*1024 字節。 memory_end &= 0xfffff000; // 忽略不到4Kb(1 頁)的內存數。 if (memory_end > 16 * 1024 * 1024) // 如果內存超過16Mb,則按16Mb 計。 memory_end = 16 * 1024 * 1024; if (memory_end > 12 * 1024 * 1024) // 如果內存>12Mb,則設置緩沖區末端=4Mb buffer_memory_end = 4 * 1024 * 1024; else if (memory_end > 6 * 1024 * 1024) // 否則如果內存>6Mb,則設置緩沖區末端=2Mb buffer_memory_end = 2 * 1024 * 1024; else buffer_memory_end = 1 * 1024 * 1024; // 否則則設置緩沖區末端=1Mb main_memory_start = buffer_memory_end; // 主內存起始位置=緩沖區末端; // 如果定義了內存虛擬盤,則初始化虛擬盤。此時主內存將減少。參見kernel/blk_drv/ramdisk.c。 #ifdef RAMDISK // 如果定義了內存虛擬盤,則主內存將減少。 main_memory_start += rd_init (main_memory_start, RAMDISK * 1024); #endif mem_init (main_memory_start, memory_end);
這裡結合下圖參考:
如果定義了內存虛擬盤,主內存區開始位置main_memory_start就從虛擬盤末端開始,否則就從高速緩沖區末端開始;而主內存區結尾memory_end則為16M。
/* 下面定義若需要改動,則需要與head.s 等文件中的相關信息一起改變 */ // linux 0.11 內核默認支持的最大內存容量是16M,可以修改這些定義以適合更多的內存。 #define LOW_MEM 0x100000 // 內存低端(1MB)。 #define PAGING_MEMORY (15*1024*1024) // 分頁內存15MB。主內存區最多15M。 #define PAGING_PAGES (PAGING_MEMORY>>12) // 分頁後的物理內存頁數。相當於除以4096 #define MAP_NR(addr) (((addr)-LOW_MEM)>>12) // 指定內存地址映射為頁號。 #define USED 100 // 頁面被占用標志,參見405 行。 static long HIGH_MEMORY = 0; // 全局變量,存放實際物理內存最高端地址。 // 內存映射字節圖(1 字節代表1 頁內存),每個頁面對應的字節用於標志頁面當前被引用(占用)次數。 static unsigned char mem_map[PAGING_PAGES] = { 0, }; //// 物理內存初始化。 // 參數:start_mem - 可用作分頁處理的物理內存起始位置(已去除RAMDISK 所占內存空間等)。 // end_mem - 實際物理內存最大地址。 // 在該版的linux 內核中,最多能使用16Mb 的內存,大於16Mb 的內存將不於考慮,棄置不用。 // 0 - 1Mb 內存空間用於內核系統(其實是0-640Kb)。 void mem_init (long start_mem, long end_mem) { int i; HIGH_MEMORY = end_mem; // 設置內存最高端。 for (i = 0; i < PAGING_PAGES; i++) // 首先置所有頁面為已占用(USED=100)狀態, mem_map[i] = USED; // 即將頁面映射數組全置成USED。 i = MAP_NR (start_mem); // 然後計算可使用起始內存的頁面號。 end_mem -= start_mem; // 再計算可分頁處理的內存塊大小。 end_mem >>= 12; // 從而計算出可用於分頁處理的頁面數。 while (end_mem-- > 0) // 最後將這些可用頁面對應的頁面映射數組清零。 mem_map[i++] = 0; }
首先注意PAGING_MEMORY,因為1M以下的內存空間是內核所用,不參與分頁,所以主內存大小最多為15M。所以PAGING_PAGES就是主內存大小除以4096(一頁就是4096字節)就是內存頁面總數。
所以mem_map的作用就是內存頁面映射。
這裡注意一下MAP_NR(start_mem)這個宏,用主內存區開始地址減去不參與分頁的1M空間,得到從可用於分頁的內存地址開始的容量,再除以4096(一頁就是4096字節)就可以得到頁號。
然後計算主內存區的大小,並把mem_map中從主內存區start_mem開始的頁號置為0.
到這裡為止,內存管理的初始化就算結束了!
Zabbix_agent部署參考文檔: 1. zabbix監控linux主機:http://www.osyunwei.com/archives/8035.html 一.
AIDL使用解析,aidl解析簡書本文地址:點擊跳轉到簡書查看 之前面試的時候被問到這個問題,然而當時只有一個大致的
安卓圖片滑動,實現帶小點的導航頁面效果,安卓小點今天給大家說說安卓中類似這樣的引導頁面怎麼實現,我自己簡單的添加了個跳過按鈕方便跳轉到主界面,圖片跟小點圖片資源大家自己去
Android 采用get方式提交數據到服務器,androidget首先搭建模擬web 服務器,新建動態web項目,servlet代碼如下: package com.w