記憶體管理單元MMU實驗

2021-07-24 18:08:49 字數 4543 閱讀 2438

mmu介紹

許可權管理:

當我們使用windows時,有時候會彈出位址訪問錯誤,但這不影響整個作業系統的執行。

假設a、b程式的時序圖如下:

因為a、b程式的位址空間各不相同。許可權管理就使得a程式無法訪問b程式的位址。如果a程式寫的非常糟糕,a程式並不能破壞核心。

假如有兩個hello.c檔案,如圖:

這兩個程式同時在記憶體中執行。

多工的系統也是乙個分時的系統。

在真正的記憶體裡面,顯然兩個程式存在不同的位址裡面,那麼為什麼cpu列印出來兩個程式的變數的位址又是一樣的呢?

在程式列印的時候,其實列印的是虛擬位址,當要利用虛擬位址訪問實體地址。這中間就有個轉換,這個轉換工作就是mmc來做的。

cpu發出虛擬位址給mmu,mmu將其轉換為實體地址。

總結一下:

對於2440來說,也會有cpu、mmu、儲存管理器(管理與硬體相關的東西,如行列位址)。

如果沒有啟用mmu,cpu直接發實體地址給儲存管理器。

如果啟用mmu,cpu發虛擬位址給mmu,mmu將其轉換為實體地址。

同樣的道理,我們寫程式的時候,鏈結位址也是沒有虛擬位址和實體地址的概念。鏈結位址只是從cpu的角度看到的。

虛擬位址怎麼轉換為實體地址?最簡單的方法就是使用乙個**。

對於arm架構來說,用什麼將虛擬位址轉換為實體地址?**。對於32位(4gb)的位址來說,如果把每乙個4gb都放入乙個**,那麼每個虛擬位址就可以將其轉換為實體地址。

**:從術語來說叫頁表(一級頁表、二級頁表)。對於arm來說,有段對映、大頁對映、小頁對映 、極小頁對映。

這裡我們只針對段對映:

**裡面的每乙個表項對應乙個段(1mb),4gb的大小想完全對映的話,那麼需要多大的**? 4gb/1mb = 4096個**項。

第0個**項表示0到1mb的實體地址,放實體地址0,…..;

以前我們操作led的時候,是直接使用的是從原理圖中來的實體地址。

我們能不能建立乙個這麼乙個虛擬位址到實體地址的對映?

建立對映後,我們就通過虛擬位址操作暫存器。

段位址對映的單位是1mb。這裡我們想把0xa0000050對映到**裡面, 1mb = 2的20次方(0x100000),0xa0000050/(2的20次方) = 0xa00 = 2560(10進製);我們想建立對映的時候,就需要把實體地址存到2560這個表項裡面。實體地址(0xa0000050)對應0x5600,0050; 1mb對齊的話,0xa000,0000 《=》0x5600,0000

makefile檔案:

objs := head.o init.o leds.o

mmu.bin : $(objs)

arm-linux

-ld-tmmu

.lds -o mmu_elf $^

arm-linux

-objcopy

-o binary -s mmu_elf $@

arm-linux

-objdump

-d-m arm mmu_elf > mmu.dis

%.o:%

.c arm-linux

-gcc

-wall

-o2-c

-o $@ $<

%.o:%

.s arm-linux

-gcc

-wall

-o2-c

-o $@ $<

clean:

rm -f mmu.bin mmu_elf mmu.dis *

.o

sections 

second 0xb0004000 : at(2048)

}

在mmu.lds指令碼檔案中,將程式分為firtst、second兩個段,其中第乙個段的內容是head.o和 init.o,也就是說從head.o和 init.o編譯出來的內容都放到第乙個段,第乙個段的鏈結位址應該位於0x00000000。

第二個段同理。

看一下head.s檔案的**實現:

@*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

***@ file:head.s

@ 功能:設定sdram,將第二部分**複製到sdram,設定頁表,啟動mmu,

@ 然後跳到sdram繼續執行

@*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

***

.text

.global _start

_start:

ldr sp, =4096 @ 設定棧指標,以下都是c函式,呼叫前需要設好棧 指向片內的最頂部

bl disable_watch_dog @ 關閉watchdog,否則cpu會不斷重啟

bl memsetup @ 設定儲存控制器以使用sdram

bl copy_2th_to_sdram @ 將第二部分**複製到sdram

bl create_page_table @ 設定頁表

bl mmu_init @ 啟動mmu

ldr sp, =0xb4000000 @ 重設棧指標,指向sdram頂端(使用虛擬位址)

ldr pc, =0xb0004000 @ 跳到sdram中繼續執行第二部分**

@ ldr pc, =main

halt_loop:

b halt_loop

init.c檔案內容如下:

/*

* init.c: 進行一些初始化,在steppingstone中執行

* 它和head.s同屬第一部分程式,此時mmu未開啟,使用實體地址

*//* watchdog暫存器 */

#define wtcon (*(volatile unsigned long *)0x53000000)

/* 儲存控制器的暫存器起始位址 */

#define mem_ctl_base 0x48000000

/* * 關閉watchdog,否則cpu會不斷重啟

*/void disable_watch_dog(void)

/* * 設定儲存控制器以使用sdram

*/void memsetup(void)

; int i = 0;

volatile

unsigned

long *p = (volatile

unsigned

long *)mem_ctl_base;

for(; i < 13; i++)

p[i] = mem_cfg_val[i];}/*

* 將第二部分**複製到sdram

*/void copy_2th_to_sdram(void)}/*

* 設定頁表

*/void create_page_table(void)}/*

* 啟動mmu

mmu有資料cache,指令cache,這些可以加快程式的執行。

MMU記憶體管理單元

mmu記憶體管理單元主要負責虛擬位址到實體地址的對映。在沒有使用虛擬儲存器的機器上,虛擬位址被直接送到記憶體匯流排上,使具有相同位址的物理儲存器被讀寫。而在使用了虛擬儲存器的情況下,虛擬位址不是被直接送到記憶體位址匯流排上,而是送到記憶體管理單元 mmu,再由mmu對映到物理記憶體中。如上圖所示,使...

MMU記憶體管理單元介紹

本篇文章簡要闡述mmu的概念,以及以段位址的轉換過程為例,簡單說明mmu將虛擬位址轉換成實體地址的過程。更多詳細內容請檢視 arm mmu 中文手冊 pdf mmu的實現過程,實際上就是乙個查表對映的過程。建立頁表 translate table 是實現mmu功能不可缺少的一步。頁表是位於系統的記憶...

MMU記憶體管理單元簡介

mmu 全稱叫做 memory manage unit,也就是記憶體管理單元。在老版本的 linux 中要求處理器必須有 mmu,但是現在 linux 核心已經支援無 mmu 的處理器了。mmu 主要完成的功能如下 虛擬位址 va,virtual address 實體地址 pa,physcicala...