亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? memory.c

?? linux 0.11 內核源碼。kernel-011-src.tar
?? C
?? 第 1 頁 / 共 2 頁
字號:
/** linux/mm/memory.c** (C) 1991 Linus Torvalds*//** demand-loading started 01.12.91 - seems it is high on the list of* things wanted, and it should be easy to implement. - Linus*//** 需求加載是從01.12.91 開始編寫的 - 在程序編制表中是呼是最重要的程序,* 并且應該是很容易編制的 - linus*//** Ok, demand-loading was easy, shared pages a little bit tricker. Shared* pages started 02.12.91, seems to work. - Linus.** Tested sharing by executing about 30 /bin/sh: under the old kernel it* would have taken more than the 6M I have free, but it worked well as* far as I could see.** Also corrected some "invalidate()"s - I wasn't doing enough of them.*//** OK,需求加載是比較容易編寫的,而共享頁面卻需要有點技巧。共享頁面程序是* 02.12.91 開始編寫的,好象能夠工作 - Linus。** 通過執行大約30 個/bin/sh 對共享操作進行了測試:在老內核當中需要占用多于* 6M 的內存,而目前卻不用。現在看來工作得很好。** 對"invalidate()"函數也進行了修正 - 在這方面我還做的不夠。*/#include <signal.h> // 信號頭文件。定義信號符號常量,信號結構以及信號操作函數原型。#include <asm/system.h> // 系統頭文件。定義了設置或修改描述符/中斷門等的嵌入式匯編宏。#include <linux/sched.h> // 調度程序頭文件,定義了任務結構task_struct、初始任務0 的數據,// 還有一些有關描述符參數設置和獲取的嵌入式匯編函數宏語句。#include <linux/head.h> // head 頭文件,定義了段描述符的簡單結構,和幾個選擇符常量。#include <linux/kernel.h> // 內核頭文件。含有一些內核常用函數的原形定義。volatile void do_exit(long code); // 進程退出處理函數,在kernel/exit.c,102 行。//// 顯示內存已用完出錯信息,并退出。static inline volatile void oom(void){printk( "out of memory\n\r");do_exit(SIGSEGV); // do_exit()應該使用退出代碼,這里用了信號值SIGSEGV(11)} // 相同值的出錯碼含義是“資源暫時不可用”,正好同義。// 刷新頁變換高速緩沖宏函數。// 為了提高地址轉換的效率,CPU 將最近使用的頁表數據存放在芯片中高速緩沖中。在修改過頁表// 信息之后,就需要刷新該緩沖區。這里使用重新加載頁目錄基址寄存器cr3 的方法來進行刷新。// 下面eax = 0,是頁目錄的基址。#define invalidate() \__asm__( "movl %%eax,%%cr3":: "a" (0))/* these are not to be changed without changing head.s etc *//* 下面定義若需要改動,則需要與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) // 分頁后的物理內存頁數。#define MAP_NR(addr) (((addr)-LOW_MEM)>>12) // 指定內存地址映射為頁號。#define USED 100 // 頁面被占用標志,參見405 行。// CODE_SPACE(addr) ((((addr)+0xfff)&~0xfff) < current->start_code + current->end_code)。// 該宏用于判斷給定地址是否位于當前進程的代碼段中,參見252 行。#define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \current->start_code + current->end_code)static long HIGH_MEMORY = 0; // 全局變量,存放實際物理內存最高端地址。// 復制1 頁內存(4K 字節)。#define copy_page(from,to) \__asm__( "cld ; rep ; movsl":: "S" (from), "D" (to), "c" (1024): "cx", "di", "si")// 內存映射字節圖(1 字節代表1 頁內存),每個頁面對應的字節用于標志頁面當前被引用(占用)次數。static unsigned char mem_map [ PAGING_PAGES ] = {0,};/** Get physical address of first (actually last :-) free page, and mark it* used. If no free pages left, return 0.*//** 獲取首個(實際上是最后1 個:-)空閑頁面,并標記為已使用。如果沒有空閑頁面,* 就返回0。*///// 取空閑頁面。如果已經沒有可用內存了,則返回0。// 輸入:%1(ax=0) - 0;%2(LOW_MEM);%3(cx=PAGING PAGES);%4(edi=mem_map+PAGING_PAGES-1)。// 輸出:返回%0(ax=頁面起始地址)。// 上面%4 寄存器實際指向mem_map[]內存字節圖的最后一個字節。本函數從字節圖末端開始向前掃描// 所有頁面標志(頁面總數為PAGING_PAGES),若有頁面空閑(其內存映像字節為0)則返回頁面地址。// 注意!本函數只是指出在主內存區的一頁空閑頁面,但并沒有映射到某個進程的線性地址去。后面// 的put_page()函數就是用來作映射的。unsigned long get_free_page(void){register unsigned long __res asm( "ax");__asm__( "std ; repne ; scasb\n\t" // 方向位置位,將al(0)與對應每個頁面的(di)內容比較,"jne 1f\n\t" // 如果沒有等于0 的字節,則跳轉結束(返回0)。"movb $1,1(%%edi)\n\t" // 將對應頁面的內存映像位置1。"sall $12,%%ecx\n\t" // 頁面數*4K = 相對頁面起始地址。"addl %2,%%ecx\n\t" // 再加上低端內存地址,即獲得頁面實際物理起始地址。"movl %%ecx,%%edx\n\t" // 將頁面實際起始地址??edx 寄存器。"movl $1024,%%ecx\n\t" // 寄存器ecx 置計數值1024。"leal 4092(%%edx),%%edi\n\t" // 將4092+edx 的位置??edi(該頁面的末端)。"rep ; stosl\n\t" // 將edi 所指內存清零(反方向,也即將該頁面清零)。"movl %%edx,%%eax\n" // 將頁面起始地址??eax(返回值)。"1:": "=a" (__res): "" (0), "i" (LOW_MEM), "c" (PAGING_PAGES),"D" (mem_map+PAGING_PAGES-1): "di", "cx", "dx");return __res; // 返回空閑頁面地址(如果無空閑也則返回0)。}/** Free a page of memory at physical address 'addr'. Used by* 'free_page_tables()'*//** 釋放物理地址'addr'開始的一頁內存。用于函數'free_page_tables()'。*///// 釋放物理地址addr 開始的一頁面內存。// 1MB 以下的內存空間用于內核程序和緩沖,不作為分配頁面的內存空間。void free_page(unsigned long addr){if (addr < LOW_MEM) return; // 如果物理地址addr 小于內存低端(1MB),則返回。if (addr >= HIGH_MEMORY) // 如果物理地址addr>=內存最高端,則顯示出錯信息。panic( "trying to free nonexistent page");addr -= LOW_MEM; // 物理地址減去低端內存位置,再除以4KB,得頁面號。addr >>= 12;if (mem_map[addr]--) return; // 如果對應內存頁面映射字節不等于0,則減1 返回。mem_map[addr]=0; // 否則置對應頁面映射字節為0,并顯示出錯信息,死機。panic( "trying to free free page");}/** This function frees a continuos block of page tables, as needed* by 'exit()'. As does copy_page_tables(), this handles only 4Mb blocks.*//** 下面函數釋放頁表連續的內存塊,'exit()'需要該函數。與copy_page_tables()* 類似,該函數僅處理4Mb 的內存塊。*///// 根據指定的線性地址和限長(頁表個數),釋放對應內存頁表所指定的內存塊并置表項空閑。// 頁目錄位于物理地址0 開始處,共1024 項,占4K 字節。每個目錄項指定一個頁表。// 頁表從物理地址0x1000 處開始(緊接著目錄空間),每個頁表有1024 項,也占4K 內存。// 每個頁表項對應一頁物理內存(4K)。目錄項和頁表項的大小均為4 個字節。// 參數:from - 起始基地址;size - 釋放的長度。int free_page_tables(unsigned long from,unsigned long size){unsigned long *pg_table;unsigned long * dir, nr;if (from & 0x3fffff) // 要釋放內存塊的地址需以4M 為邊界。panic( "free_page_tables called with wrong alignment");if (!from) // 出錯,試圖釋放內核和緩沖所占空間。panic( "Trying to free up swapper memory space");// 計算所占頁目錄項數(4M 的進位整數倍),也即所占頁表數。size = (size + 0x3fffff) >> 22;// 下面一句計算起始目錄項。對應的目錄項號=from>>22,因每項占4 字節,并且由于頁目錄是從// 物理地址0 開始,因此實際的目錄項指針=目錄項號<<2,也即(from>>20)。與上0xffc 確保// 目錄項指針范圍有效。dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */for ( ; size-->0 ; dir++) { // size 現在是需要被釋放內存的目錄項數。if (!(1 & *dir)) // 如果該目錄項無效(P 位=0),則繼續。continue; // 目錄項的位0(P 位)表示對應頁表是否存在。pg_table = (unsigned long *) (0xfffff000 & *dir); // 取目錄項中頁表地址。for (nr=0 ; nr<1024 ; nr++) { // 每個頁表有1024 個頁項。if (1 & *pg_table) // 若該頁表項有效(P 位=1),則釋放對應內存頁。free_page(0xfffff000 & *pg_table);*pg_table = 0; // 該頁表項內容清零。pg_table++; // 指向頁表中下一項。}free_page(0xfffff000 & *dir); // 釋放該頁表所占內存頁面。但由于頁表在// 物理地址1M 以內,所以這句什么都不做。*dir = 0; // 對相應頁表的目錄項清零。}invalidate(); // 刷新頁變換高速緩沖。return 0;}/** Well, here is one of the most complicated functions in mm. It* copies a range of linerar addresses by copying only the pages.* Let's hope this is bug-free, 'cause this one I don't want to debug :-)** Note! We don't copy just any chunks of memory - addresses have to* be divisible by 4Mb (one page-directory entry), as this makes the* function easier. It's used only by fork anyway.** NOTE 2!! When from==0 we are copying kernel space for the first* fork(). Then we DONT want to copy a full page-directory entry, as* that would lead to some serious memory waste - we just copy the* first 160 pages - 640kB. Even that is more than we need, but it* doesn't take any more memory - we don't copy-on-write in the low* 1 Mb-range, so the pages can be shared with the kernel. Thus the* special case for nr=xxxx.*//** 好了,下面是內存管理mm 中最為復雜的程序之一。它通過只復制內存頁面* 來拷貝一定范圍內線性地址中的內容。希望代碼中沒有錯誤,因為我不想* 再調試這塊代碼了?。** 注意!我們并不是僅復制任何內存塊 - 內存塊的地址需要是4Mb 的倍數(正好* 一個頁目錄項對應的內存大小),因為這樣處理可使函數很簡單。不管怎樣,* 它僅被fork()使用(fork.c 第56 行)。** 注意2!!當from==0 時,是在為第一次fork()調用復制內核空間。此時我們* 不想復制整個頁目錄項對應的內存,因為這樣做會導致內存嚴重的浪費 - 我們* 只復制頭160 個頁面 - 對應640kB。即使是復制這些頁面也已經超出我們的需求,* 但這不會占用更多的內存 - 在低1Mb 內存范圍內我們不執行寫時復制操作,所以* 這些頁面可以與內核共享。因此這是nr=xxxx 的特殊情況(nr 在程序中指頁面數)。*///// 復制指定線性地址和長度(頁表個數)內存對應的頁目錄項和頁表,從而被復制的頁目錄和//// 頁表對應的原物理內存區被共享使用。// 復制指定地址和長度的內存對應的頁目錄項和頁表項。需申請頁面來存放新頁表,原內存區被共享;// 此后兩個進程將共享內存區,直到有一個進程執行寫操作時,才分配新的內存頁(寫時復制機制)。int copy_page_tables(unsigned long from,unsigned long to,long size){unsigned long * from_page_table;unsigned long * to_page_table;unsigned long this_page;unsigned long * from_dir, * to_dir;unsigned long nr;// 源地址和目的地址都需要是在4Mb 的內存邊界地址上。否則出錯,死機。if ((from&0x3fffff) || (to&0x3fffff))panic( "copy_page_tables called with wrong alignment");// 取得源地址和目的地址的目錄項(from_dir 和to_dir)。參見對115 句的注釋。from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */to_dir = (unsigned long *) ((to>>20) & 0xffc);// 計算要復制的內存塊占用的頁表數(也即目錄項數)。size = ((unsigned) (size+0x3fffff)) >> 22;// 下面開始對每個占用的頁表依次進行復制操作。for( ; size-->0 ; from_dir++,to_dir++) {// 如果目的目錄項指定的頁表已經存在(P=1),則出錯,死機。if (1 & *to_dir)panic( "copy_page_tables: already exist");// 如果此源目錄項未被使用,則不用復制對應頁表,跳過。if (!(1 & *from_dir))continue;// 取當前源目錄項中頁表的地址??from_page_table。from_page_table = (unsigned long *) (0xfffff000 & *from_dir);// 為目的頁表取一頁空閑內存,如果返回是0 則說明沒有申請到空閑內存頁面。返回值=-1,退出。if (!(to_page_table = (unsigned long *) get_free_page()))return -1; /* Out of memory, see freeing */// 設置目的目錄項信息。7 是標志信息,表示(Usr, R/W, Present)。*to_dir = ((unsigned long) to_page_table) | 7;// 針對當前處理的頁表,設置需復制的頁面數。如果是在內核空間,則僅需復制頭160 頁,否則需要// 復制1 個頁表中的所有1024 頁面。nr = (from==0)?0xA0:1024;// 對于當前頁表,開始復制指定數目nr 個內存頁面。for ( ; nr-- > 0 ; from_page_table++,to_page_table++) {this_page = *from_page_table; // 取源頁表項內容。if (!(1 & this_page)) // 如果當前源頁面沒有使用,則不用復制。continue;// 復位頁表項中R/W 標志(置0)。(如果U/S 位是0,則R/W 就沒有作用。如果U/S 是1,而R/W 是0,// 那么運行在用戶層的代碼就只能讀頁面。如果U/S 和R/W 都置位,則就有寫的權限。)this_page &= ~2;*to_page_table = this_page; // 將該頁表項復制到目的頁表中。// 如果該頁表項所指頁面的地址在1M 以上,則需要設置內存頁面映射數組mem_map[],于是計算// 頁面號,并以它為索引在頁面映射數組相應項中增加引用次數。if (this_page > LOW_MEM) {// 下面這句的含義是令源頁表項所指內存頁也為只讀。因為現在開始有兩個進程共用內存區了。// 若其中一個內存需要進行寫操作,則可以通過頁異常的寫保護處理,為執行寫操作的進程分配// 一頁新的空閑頁面,也即進行寫時復制的操作。*from_page_table = this_page; // 令源頁表項也只讀。this_page -= LOW_MEM;this_page >>= 12;mem_map[this_page]++;}}}invalidate(); // 刷新頁變換高速緩沖。return 0;}/** This function puts a page in memory at the wanted address.* It returns the physical address of the page gotten, 0 if* out of memory (either when trying to access page-table or* page.)*//** 下面函數將一內存頁面放置在指定地址處。它返回頁面的物理地址,如果* 內存不夠(在訪問頁表或頁面時),則返回0。*///// 把一物理內存頁面映射到指定的線性地址處。// 主要工作是在頁目錄和頁表中設置指定頁面的信息。若成功則返回頁面地址。unsigned long put_page(unsigned long page,unsigned long address){unsigned long tmp, *page_table;/* NOTE !!! This uses the fact that _pg_dir=0 *//* 注意!!!這里使用了頁目錄基址_pg_dir=0 的條件 */// 如果申請的頁面位置低于LOW_MEM(1Mb)或超出系統實際含有內存高端HIGH_MEMORY,則發出警告。if (page < LOW_MEM || page >= HIGH_MEMORY)printk( "Trying to put page %p at %p\n",page,address);// 如果申請的頁面在內存頁面映射字節圖中沒有置位,則顯示警告信息。if (mem_map[(page-LOW_MEM)>>12] != 1)printk( "mem_map disagrees with %p at %p\n",page,address);// 計算指定地址在頁目錄表中對應的目錄項指針。page_table = (unsigned long *) ((address>>20) & 0xffc);// 如果該目錄項有效(P=1)(也即指定的頁表在內存中),則從中取得指定頁表的地址??page_table。if ((*page_table)&1)page_table = (unsigned long *) (0xfffff000 & *page_table);else {// 否則,申請空閑頁面給頁表使用,并在對應目錄項中置相應標志7(User, U/S, R/W)。然后將// 該頁表的地址??page_table。if (!(tmp=get_free_page()))return 0;*page_table = tmp|7;page_table = (unsigned long *) tmp;}// 在頁表中設置指定地址的物理內存頁面的頁表項內容。每個頁表共可有1024 項(0x3ff)。

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
视频在线在亚洲| 91精品国产综合久久香蕉麻豆| 91蝌蚪porny| 欧美日韩另类国产亚洲欧美一级| 欧美一区二区三区公司| 久久精品视频网| 亚洲色图一区二区| 天天亚洲美女在线视频| 国产一区二区电影| 在线影视一区二区三区| 欧美大片拔萝卜| 中文字幕在线播放不卡一区| 五月婷婷欧美视频| 国产一区高清在线| 91蜜桃传媒精品久久久一区二区| 3atv一区二区三区| 国产精品人成在线观看免费| 亚洲bt欧美bt精品| 国产成人免费视频| 51久久夜色精品国产麻豆| 欧美国产在线观看| 婷婷开心久久网| 成人精品小蝌蚪| 91精品国产欧美一区二区成人| 欧美极品少妇xxxxⅹ高跟鞋 | 亚洲va在线va天堂| 国产成都精品91一区二区三| 欧美日韩一区小说| 中文字幕久久午夜不卡| 日本成人中文字幕| 色天天综合久久久久综合片| 2021中文字幕一区亚洲| 亚洲成人黄色小说| 99久精品国产| 久久精品一区二区三区不卡| 午夜成人在线视频| 97精品超碰一区二区三区| 精品国产一区久久| 午夜a成v人精品| 91福利精品第一导航| 国产欧美va欧美不卡在线| 久久精品久久久精品美女| 欧美揉bbbbb揉bbbbb| 国产精品不卡视频| 国产a视频精品免费观看| 日韩精品一区二区三区中文精品| 亚洲综合色丁香婷婷六月图片| 国产成人综合网| 日韩精品一区二区三区视频在线观看 | 亚洲精品你懂的| 国产69精品久久久久毛片| 日韩欧美国产不卡| 视频在线观看国产精品| 日本精品裸体写真集在线观看| 国产精品免费免费| 久久久精品免费观看| 日韩va欧美va亚洲va久久| 在线亚洲欧美专区二区| 亚洲欧美乱综合| 成人av在线资源网站| 国产亚洲午夜高清国产拍精品| 青青草国产精品亚洲专区无| 欧美三级视频在线| 午夜精品久久久久影视| 欧美日韩免费观看一区二区三区 | 色94色欧美sute亚洲13| 亚洲三级小视频| 91亚洲精品一区二区乱码| 中文字幕一区二区在线观看 | 自拍偷拍欧美激情| 99riav久久精品riav| 日韩一区欧美一区| 色婷婷国产精品| 亚洲综合色成人| 欧美在线你懂的| 亚洲福利视频三区| 欧美三级日韩在线| 日韩av一区二区在线影视| 337p亚洲精品色噜噜噜| 美女网站视频久久| 精品国产免费视频| 国产精品一区久久久久| 久久精品欧美日韩| eeuss国产一区二区三区| 国产精品国产自产拍高清av | 一区二区免费看| 在线观看视频91| 午夜电影网一区| xf在线a精品一区二区视频网站| 国内精品伊人久久久久av一坑| 国产亚洲人成网站| 99久久综合精品| 一区二区三区在线观看欧美| 欧美电影影音先锋| 久久国产免费看| 亚洲国产精品99久久久久久久久| 99精品久久99久久久久| 一区二区三区日韩在线观看| 337p亚洲精品色噜噜| 国产一区福利在线| 亚洲女人****多毛耸耸8| 91精品国产综合久久福利| 老色鬼精品视频在线观看播放| 久久久久久久综合色一本| 成熟亚洲日本毛茸茸凸凹| 亚洲自拍与偷拍| 日韩一区二区三区四区| 国产传媒日韩欧美成人| 亚洲精品videosex极品| 91精品国产一区二区| 高清不卡在线观看| 亚洲成人你懂的| 久久久久久影视| 欧美自拍偷拍午夜视频| 久久精品国产亚洲5555| 亚洲国产精品t66y| 欧美日韩1区2区| 国产盗摄一区二区| 亚洲国产日产av| 久久色.com| 欧美日本不卡视频| 国产成人超碰人人澡人人澡| 亚洲一区二区视频在线| 2022国产精品视频| 欧美日韩在线播放三区| 国产不卡视频在线播放| 亚洲成人免费看| 国产欧美综合在线观看第十页| 欧美三级视频在线| 成人午夜伦理影院| 全部av―极品视觉盛宴亚洲| 国产精品国产三级国产专播品爱网 | 中文字幕精品综合| 777色狠狠一区二区三区| 成人黄色网址在线观看| 日本成人中文字幕在线视频| 亚洲三级在线观看| 久久综合九色综合欧美98| 欧美日韩国产在线观看| 成人免费看黄yyy456| 美女视频免费一区| 尤物av一区二区| 国产欧美中文在线| 日韩一区二区在线看| 在线亚洲精品福利网址导航| 东方aⅴ免费观看久久av| 秋霞影院一区二区| 亚洲国产日韩在线一区模特| 中文字幕制服丝袜一区二区三区| 精品国产欧美一区二区| 欧美美女黄视频| 91视频www| 成人av先锋影音| 国产精品一二三在| 精品一区二区日韩| 丝袜亚洲另类丝袜在线| 亚洲精品视频在线观看免费| 国产日韩精品一区二区浪潮av| 日韩三级视频中文字幕| 欧美色网站导航| 91色.com| 99视频一区二区| 成人黄色综合网站| 成人免费视频免费观看| 国产福利91精品| 国产精品中文字幕一区二区三区| 青青草国产成人av片免费| 亚洲午夜在线视频| 亚洲午夜羞羞片| 亚洲精选视频在线| 亚洲视频一区二区免费在线观看| 中文字幕va一区二区三区| 久久综合精品国产一区二区三区| 日韩欧美三级在线| 日韩一区二区三区免费看 | 奇米精品一区二区三区在线观看 | 欧美日本在线观看| 在线观看一区二区视频| 日本丶国产丶欧美色综合| 一本色道久久综合精品竹菊 | 亚洲国产精品久久人人爱蜜臀 | 欧美综合亚洲图片综合区| 色婷婷av一区二区| 欧美少妇一区二区| 欧美日韩视频不卡| 4438x成人网最大色成网站| 欧美一区二区免费视频| 欧美一区二区三区公司| 欧美大片在线观看一区| 久久人人爽爽爽人久久久| 久久精品一区二区三区不卡| 久久久久久99久久久精品网站| 久久免费偷拍视频| 中文字幕免费一区| 中文字幕佐山爱一区二区免费| 一区二区三区四区视频精品免费 | av午夜一区麻豆| 日本久久一区二区三区| 欧美日韩高清在线播放| 日韩一区二区三区精品视频|