linux內核地址
⑴ 什麼是linux內核
Linux是由Linus Torvalds開發的類UNIX的操作系統,Linux主要特點是開源的,因此我們可以免費使用來當做伺服器。
Linux嚴格分為兩個含義。
1.廣泛的Linux是指Linux發行版
2.狹義的Linux是指Linux內核
Linux內核是操作系統的基礎,介於硬體和軟體之間,並且內核位於操作系統中,操作系統將在硬體和軟體之間進行調解,Linux內核是操作系統核心部分的功能。
二:內核的基本性能
1.流程管理
在Linux內核中,程序的執行狀態以進程為單位進行管理。此外,內核為每個進程准備一個名為task_stract結構的數據結構。
2.進程調度程序
可執行狀態等待哪個進程以哪個順序執行,由於基本上不可能運行比CPU數量更多的進程,因此運行過程的效率非常重要。
3.內存管理
在Linux內核中,使用物理內存和虛擬內存管理數據。通過分配對應於物理存儲器的虛擬地址,而不是實際為每個進程分配物理存儲器地址,可以使用容量遠大於實際物理存儲器容量的存儲器。它使它成為可能。此外,由於每個進程都分配了自己的虛擬地址,因此每個進程的內存空間是獨立的,並且不會違反其他進程的內存。
3.文件系統
它以文件的形式提供存儲數據的訪問方法。所有數據都以文件的形式進行管理。/ Directory(根目錄)作為頂點,內核本身作為文件和目錄的集合存在。
⑵ 為什麼linux操作系統內核在虛擬地址空間的3GB處
1: 並不是所有平台都在3G
2:i386沒有PAE,並且編譯時沒有特別指定的時候才在3G
3:在這種情況下,由於地址匯流排最大隻能訪問4G的空間,並且為了在切換入內核空間時不需要重新載入內核的頁表,使用了一個技巧:讓內核與用戶空間影射到同一內存段。根據實際需要,給內核保留了1G的內存空間,並且為了讓應用程序看起來是從0地址開始的,那麼內核的1G內存段就佔用了3G~4G的空間。這就回答了你的問題。
4:其實這種方法不是唯一的,比如,可以讓內核少佔用一些空間,那麼就不是3G了。或者,讓內核與應用程序不映射到同一個內存空間,那麼用戶程序可以使用幾乎全部的4G空間(有些patch可以做到,但這樣的話內核<->用戶態切換時代價很大。說幾乎4G的原因是:調用syscall時還是需要一段內存傳遞參數的)。
⑶ ARM linux內核啟動時幾個關鍵地址
1. 內核啟動地址
ZTEXTADDR
解壓代碼運行的開始地址。沒有物理地址和虛擬地址之分,因為此時MMU處於關閉狀態。這個地址不一定時RAM的地址,可以是支持讀寫定址的flash等存儲中介。
Start address of decompressor. here's no point in talking about virtual or physical addresses here, since the MMU will be off at the time when you call the decompressor code. You normally call the kernel at this address to start it booting. This doesn't have to be located in RAM, it can be in flash or other read-only or read-write addressable medium.
在arch/arm/boot/compressed/Makefile中說的很明確
#
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
ifeq ($(CONFIG_ZBOOT_ROM),y)
ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR := 0
ZBSSADDR := ALIGN(8)
endif
ZRELADDR
內核啟動在RAM中的地址。壓縮的內核映像被解壓到這個地址,然後執行。
This is the address where the decompressed kernel will be written, and eventually executed. The following constraint must be valid:
__virt_to_phys(TEXTADDR) == ZRELADDR
The initial part of the kernel is carefully coded to be position independent.
一般定義在項目目錄下,比如:
arch/arm/mach-at91/Makefile.boot: zreladdr-y += 0x70008000
arch/arm/mach-at91/Makefile.boot: zreladdr-y += 0x20008000
arch/arm/mach-cns3xxx/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-davinci/Makefile.boot: zreladdr-y += 0xc0008000
arch/arm/mach-davinci/Makefile.boot: zreladdr-y += 0x80008000
arch/arm/mach-dove/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-ebsa110/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-exynos/Makefile.boot: zreladdr-y += 0x40008000
arch/arm/mach-footbridge/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-gemini/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-gemini/Makefile.boot: zreladdr-y += 0x10008000
arch/arm/mach-integrator/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/mach-iop13xx/Makefile.boot: zreladdr-y += 0x00008000
在arch/arm/boot/Makefile中被賦值:
ZRELADDR := $(zreladdr-y)
PARAMS_PHYS := $(params_phys-y)
INITRD_PHYS := $(initrd_phys-y)
... ...
ifneq ($(LOADADDR),)
UIMAGE_LOADADDR=$(LOADADDR)
else
ifeq ($(CONFIG_ZBOOT_ROM),y)
UIMAGE_LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)
⑷ 如何找到具體版本的linux 內核
方法一:
命令: uname -a
作用: 查看系統內核版本號及系統名稱
方法二:
命令: cat /proc/version
作用: 查看目錄"/proc"下version的信息,也可以得到當前系統的內核版本號及系統名稱
執行效果如下圖所示:
補充說明:
/proc文件系統,它不是普通的文件系統,而是系統內核的映像,也就是說,該目錄中的文件是存放在系統內存之中的,它以文件系統的方式為訪問系統內核數據的操作提供介面。而我們使用命令「uname -a"的信息就是從該文件獲取的,當然用方法二的命令直接查看它的內容也可以達到同等效果.另外,加上參數"a"是獲得詳細信息,如果不加參數為查看系統名稱。
⑸ Linux,本人自學,剛剛接觸,想問一下高手,Linux內核,存儲在哪裡例如安卓手機Linux
Android內核一般放在一個ROM的小分區里(不帶文件系統,看不到這個文件,而是在分區頭部記錄了內核的偏移地址),這是大部分手機的做法,不是絕對的(有放到fat文件系統里的)。
PC機上一般把內核放在根分區的boot文件夾下,或放到單獨的boot分區里(仍然可以通過/boot訪問)。
非常規情形下,Linux內核位置可以很隨意,有放網路上的,甚至有塞主板里的,只要能被引導程序讀進內存就好。
⑹ linux內核內存定址在哪個文件
linux內核地址映射模型 x86 CPU採用了段頁式地址映射模型。進程代碼中的地址為邏輯地址,經過段頁式地址映射後,才真正訪問物理內存。 段頁式機制如下圖。 linux內核地址空間劃分 通常32位linux內核地址空間劃分0~3G為用戶空間,3~4G為內核空間。注意這里是32位內核地址空間劃分,64位內核地址空間劃分是不同的。 linux內核高端內存的由來 當內核模塊代碼或線程訪問內存時,代碼中的內存地址都為邏輯地址,而對應到真正的物理內存地址,需要地址一對一的映射,如邏輯地址0xc0000003對應的物理地址為0×3,0xc0000004對應的物理地址為0×4,… …,邏輯地址與物理地址對應的關系為 物理地址 = 邏輯地址 0xC0000000 邏輯地址物理內存地址0xc00000000×00xc00000010×10xc00000020×20xc00000030×3… … 0xe00000000×20000000……0xffffffff0×40000000 ?? 顯然不能將內核地址空間0xc0000000 ~ 0xfffffff全部用來簡單的地址映射。因此x86架構中將內核地址空間劃分三部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_HIGHMEM即為高端內存,這就是內存高端內存概念的由來。 在x86結構中,三種類型的區域如下: ZONE_DMA 內存開始的16MB ZONE_NORMAL 16MB~896MB ZONE_HIGHMEM 896MB ~ 結束 linux內核高端內存的理解 前面我們解釋了高端內存的由來。 linux將內核地址空間劃分為三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端內存HIGH_MEM地址空間范圍為0xF8000000 ~ 0xFFFFFFFF(896MB~1024MB)。那麼如內核是如何藉助128MB高端內存地址空間是如何實現訪問可以所有物理內存? 當內核想訪問高於896MB物理地址內存時,從0xF8000000 ~ 0xFFFFFFFF地址空間范圍內找一段相應大小空閑的邏輯地址空間,借用一會。借用這段邏輯地址空間,建立映射到想訪問的那段物理內存(即填充內核PTE頁面表),臨時用一會,用完後歸還。這樣別人也可以借用這段地址空間訪問其他物理內存,實現了使用有限的地址空間,訪問所有所有物理內存。如下圖。 例如內核想訪問2G開始的一段大小為1MB的物理內存,即物理地址范圍為0×80000000 ~ 0x800FFFFF。訪問之前先找到一段1MB大小的空閑地址空間,假設找到的空閑地址空間為0xF8700000 ~ 0xF87FFFFF,用這1MB的邏輯地址空間映射到物理地址空間0×80000000 ~ 0x800FFFFF的內存。映射關系如下: 邏輯地址物理內存地址0xF87000000×800000000xF87000010×800000010xF87000020×80000002… …0xF87FFFFF0x800FFFFF當內核訪問完0×80000000 ~ 0x800FFFFF物理內存後,就將0xF8700000 ~ 0xF87FFFFF內核線性空間釋放。這樣其他進程或代碼也可以使用0xF8700000 ~ 0xF87FFFFF這段地址訪問其他物理內存。 從上面的描述,我們可以知道高端內存的最基本思想:借一段地址空間,建立臨時地址映射,用完後釋放,達到這段地址空間可以循環使用,訪問所有物理內存。 看到這里,不禁有人會問:萬一有內核進程或模塊一直佔用某段邏輯地址空間不釋放,怎麼辦?若真的出現的這種情況,則內核的高端內存地址空間越來越緊張,若都被佔用不釋放,則沒有建立映射到物理內存都無法訪問了。
⑺ Linux 內核從哪個階段開始使用虛擬地址的
一般是在kernel/head_32.S文件,early_init之後,會調用relocate_kernel,重定向,KERNELBASE為內核的虛擬起始地址,接著trun_on_mmu中,跳轉到start_here,然後就是虛擬地址了。
⑻ 為什麼Linux內核要把內核地址放在高地址空間內
我們知道現在操作系統都是採用虛擬存儲器,那麼對32位操作系統而言,它的定址空間(虛擬存儲空間)為4G(2的32次方)。操心系統的核心是內核,獨立於普通的應用程序,可以訪問受保護的內存空間,也有訪問底層硬體設備的所有許可權。為了保證用戶進程不能直接操作內核,保證內核的安全,操心系統將虛擬空間劃分為兩部分,一部分為內核空間,一部分為用戶空間。針對linux操作系統而言,將最高的1G位元組(從虛擬地址0xC0000000到0xFFFFFFFF),供內核使用,稱為內核空間,而將較低的3G位元組(從虛擬地址0x00000000到0xBFFFFFFF),供各個進程使用,稱為用戶空間。每個進程可以通過系統調用進入內核,因此,Linux內核由系統內的所有進程共享。於是,從具體進程的角度來看,每個進程可以擁有4G位元組的虛擬空間
需要注意的細節問題:
(1) 內核空間中存放的是內核代碼和數據,而進程的用戶空間中存放的是用戶程序的代碼和數據。不管是內核空間還是用戶空間,它們都處於虛擬空間中。
(2) Linux使用兩級保護機制:0級供內核使用,3級供用戶程序使用。
內核態與用戶態:
(1)當一個任務(進程)執行系統調用而陷入內核代碼中執行時,稱進程處於內核運行態(內核態)。此時處理器處於特權級最高的(0級)內核代碼中執行。當進程處於內核態時,執行的內核代碼會使用當前進程的內核棧。每個進程都有自己的內核棧。
(2)當進程在執行用戶自己的代碼時,則稱其處於用戶運行態(用戶態)。此時處理器在特權級最低的(3級)用戶代碼中運行。當正在執行用戶程序而突然被中斷程序中斷時,此時用戶程序也可以象徵性地稱為處於進程的內核態。因為中斷處理程序將使用當前進程的內核棧。
⑼ linux內核調用哪些介面分配內核地址空間的內存
kmalloc/kfree
類似於標准C中的malloc/free,kmalloc/kfree是內核中的用於常規內存分配的介面。
例如,申請1024位元組的內核地址空間:
char*buff;
buff=kmalloc(1024,GFP_KERNEL);
if(!buff)
return-ENOMEM;
還有什麼問題的話,可以私信我哦
⑽ linux內核地址映射
其實阿,你忽略了一點,不管進程如何切換,內核的載入位置一致保持不便,而且映射內核的幾個頁面在啟動頁式管理之前,就已經映射到幾個固定的頁面中。這樣保持了內核位於任何進程地址空間的固定位置。進程切換時,只是將這些頁表的頁目錄項添加到進程的頁目錄中。這個是安排一條中斷返回指令(iret),從當前的PC開始執行。其實你後面已經對前面做答了! 2中,那句話的意思是,內核在進程的地址空間中頁面映射是相同的! 理解了嗎?好好加油,我搜了好長時間的svr4,一致找不到,你有嗎?