成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

這樣理解mmap,挺有意思!

系統 Linux
mmap有很多用途,有人用它來實現進程間通信,有人用它搬運數據,對于我們嵌入式工程師來說,我們可以用它來點燈。嘿嘿,想不到吧!

大概雍正皇帝怎么也不會想到,自己在西歷2022年的男生和女生眼里,會是截然不同的兩種形象。

1

以我對身邊同學朋友的觀察,男生們大多愛看《雍正王朝》,他們眼中的雍正,大約是個推行了“火耗歸公”、“攤丁入畝”等遏制貪腐,減輕稅收之類政策的改革家,是個經歷了九子奪嫡的驚心動魄、腹黑深沉的政治家,是個登基后也兢兢業業,熬夜加班996的工作狂。

而女生們大多愛看《甄嬛傳》,她們眼里的雍正,是“大胖橘”,是“大豬蹄子”,是被后宮一眾妃嬪玩弄于股掌之中,戴了N頂綠帽,最后還被鈕鈷祿甄嬛氣死的渣男。

我沒完整的看過甄嬛傳,但是有幸在吃飯的時候陪我家那位看過幾集。

正所謂后宮佳麗三千人,鐵杵磨成繡花針... (不是妃嬪太多了,皇帝就一個,難免會互相爭風吃醋。位份高的貴妃的仗勢欺人,一些小妃嬪無法正面回擊,自然會用點別的奇淫技巧,扎小人就是其中一個出現頻率較高的方法。

據我總結,扎小人這個技術的核心思想是:用戶這邊由于無法扎到正主,只能拿個自己身邊的布片等物品模擬一個小人出來,在上面畫上正主的經筋脈絡,寫上名字,施以某種魔法,然后用針扎自己手邊的小人的某個穴道,遠程那位正主的對應部位就會受到同樣的折磨。

雖然有點神乎其技,令人羨慕而不可得。但是在linux內核開發里面,卻可以用mmap的機制實現類似的效果。

2

mmap的核心思想是:用戶這邊由于在用戶態無法直接操作寄存器的物理地址,于是通過mmap方法進行內存映射,將物理地址映射到用戶態的虛擬地址上,然后用戶通過讀寫自己手邊的虛擬地址,就可以實現對物理地址的讀取/寫入。

兩者的共同點是,由于無法直接操作目標,所以通過某種方法,將自己能操作的事物和目標建立一種映射關系,從而達到如臂使指,指哪打哪,打哪哪疼的效果。

只要能建立起對目標的映射,我們借此映射能做什么文章,自然有很多想象空間。所以mmap有很多用途,有人用它來實現進程間通信,有人用它搬運數據,對于我們嵌入式工程師來說,我們可以用它來點燈。嘿嘿,想不到吧!

且聽我慢慢道來。

3

作為一個嵌入式工程師,花式點燈是必備技能。無論是寫裸機代碼操作GPIO口,還是通過物聯網云端遠程控制LED,從硬件的角度講,核心原理都是找到連接LED的GPIO口,讓它輸出一個電信號。而從軟件的角度講,最終目的就是找到這個GPIO口對應寄存器的地址,根據實際的電路要求,讓CPU給它寫入一個1或者0。

裸機開發的時候,我們可以直接找到物理地址進行操作。而在Linux系統里卻略有不同。因為在操作系統里有內核空間的存在,我們寫的程序都是運行在用戶態的,需要經過內核來對硬件進行驅動,無法直接操作物理地址。

你當然可以選擇為這個LED寫一個驅動,從而在用戶空間通過read,write來操作它的狀態。不過有些同學一聽要寫驅動,就想吟一首蜀道難來表達自己的望而卻步。所以沒了解過驅動的同學你也可以選擇用一種更直接的方式:mmap。

就好像你可以選擇給貴妃下藥來控制她,不過下藥這種方式需要精通藥理、掌控時機,成本較高,難度較大。只要能達到目的,有時候扎個小人或許更加經濟適用。

我在上家公司的時候用ARM Cortex-A9芯片做過一個項目,開發過程大概是先和硬件同事約定好一個協議,然后我通過GPIO口的輸入輸出模擬出這個協議,通過它對寄存器進行讀寫配置,驅動硬件ADC采樣,然后將采回來的數據通過DMA傳輸,最終到應用層進行分析處理。其中驅動GPIO口的部分就用了mmap。

項目很大,做了半年多,想完全講明白也不現實,不過我們可以從驅動GPIO口這個點切入,體會一下軟件驅動硬件中間這玄妙的過程。聰明的你一定可以舉一反三。

4

作為一個軟件工程師,拿到板子的時候,硬件工程師一般會給你一份文檔,類似這樣:

這個文檔會指明,如果想操作這個GPIO口的話,你需要用GPIO外設的基地址加上偏移地址找到對應的寄存器地址,再用位操作給指定的bit寫入命令。

不過我由于FPGA也會一些,所以我們公司里FPGA的Block Diagram都是我來建的。建好FPGA的硬件工程后做一下綜合,從Address Map里就能看到我想用的GPIO口地址了。如圖:

無論怎樣,你現在拿到這個所謂的硬件寄存器地址了,接下來我們就可以拿小人扎它了。

以上圖我拿到的0x43C00000為例,這是寄存器的地址,那我能否直接在應用程序里把0x43C00000賦值給一個指針,然后對它進行讀寫呢?

在玩裸機的時候確實是這樣的。但是上面說了,Linux系統有虛擬內存的存在,就不能這么做了。因為理論上我可以在系統里開100個進程,這100個進程里都有0x43C00000這個地址,那這100個地址哪個是真正的寄存器地址呢?可能都不是。因為進程里的0x43C00000是虛擬的,它真正對應的物理地址在哪里,沒人知道。要想把虛擬地址和物理地址對應起來,就得用mmap進行內存映射。

5

mmap的函數接口定義如下:

void mmap(void addr,size_t length,
int prot,int flags,
int fd,off_t offset);

這里面參數比較多。其中addr一般指定為NULL,prot則用于設置映射區域的權限,比如是否可讀可寫;flags則用于指定是共享映射還是私有映射;而fd,offset,length這三個參數表示將fd對應的文件,從offset位置起,將長度為length的內容映射到進程的地址空間。

需要注意mmap的操作單元是頁,即最后映射的offset參數必須是內存頁大小的整數倍,而Linux系統內存頁大小一般為4096字節。

一個我在程序中的調用示例:

#define AXI_GPIO_BASEADDR 0x43C00000  
int memfd = open("/dev/mem", O_RDWR
| O_SYNC);
if (-1 == memfd) {
printf("Can't open /dev/mem\n");
return -1;
}
unsigned int* led_gpio =
(unsigned int*)(mmap(
NULL, MMAP_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED, memfd,
AXI_GPIO_BASEADDR));

調用mmap后,我們拿到一個指針,通過這個指針對指向的地址做任何操作,對應的寄存器物理地址也會有相同的效果。于是我們將它循環賦值0101,相應的寄存器控制的GPIO口輸出電信號,于是板卡上的燈成功的閃爍起來,類似奧特曼體力不支時的能量燈。

6

多說兩句,除了用來操作GPIO/字符設備外,mmap還有個常用的場景是操作塊設備。它和傳統的用read,write的區別,最關鍵的是省一次拷貝。

比如要讀取磁盤上某個文件的數據,用read write的話,由于會涉及到系統調用,進程是無法直接訪問內核的,所以在read系統調用返回前,內核需要將數據從內核復制到進程指定的buffer里。

但如果用mmap的話,那么這段數據會首先拷貝到內存中作為頁緩存(即page cache)。用mmap將這段內存映射到用戶空間,則進程可以通過指針直接讀寫page cache,不再需要多余的系統調用和內存拷貝。

不過雖然少了一次拷貝,但mmap會觸發缺頁中斷(page fault),相比于內存拷貝而言,缺頁中斷的開銷更大。所以性能而言mmap大部分情況下并不會比read/write要好。

說到頁緩存,我在上家公司開發項目的時候,還被臟頁延遲這玩意坑過。篇幅所限,頁緩存涉及到的缺頁中斷,臟頁,延遲寫回,sync強制寫回等內容,我們下次再詳細聊聊。

7

好了,于是我們學會用mmap點亮一個燈了。想象一下接下來的場景:

你跟公司研發部最漂亮的女同事說,

“hi,領導那邊給了我們組一個新任務,你寫個驅動控制一下LED吧?”

“???驅動這么難,我不會啦”

“哦沒事,那你用mmap吧”

“誒你怎么罵人呢!”

責任編輯:龐桂玉 來源: 良許Linux
相關推薦

2021-04-09 08:23:30

Css前端加載動畫

2021-03-25 06:12:55

SVG 濾鏡CSS

2022-08-15 22:34:47

Overflow方向裁切

2022-06-15 07:21:47

鼠標指針交互效果CSS

2015-09-17 17:49:13

華三/UIS

2020-12-12 13:50:16

云開發

2017-08-01 00:52:07

kafka大數據消息總線

2021-01-27 13:54:05

開發云原生工具

2018-06-24 16:39:28

Tomcat異常線程

2013-08-28 09:46:09

Debian LinuLinux發行版

2010-04-09 11:24:59

Oracle 排序

2012-05-22 10:12:59

jQuery

2012-06-19 16:49:19

Web開發

2021-11-17 10:45:58

Chrome 95新特性前端

2015-10-28 13:57:29

融合架構華三UIS

2023-05-15 09:16:18

CSSCSS Mask

2012-04-12 15:14:31

idf2012英特爾

2013-11-29 13:05:07

程序員工作

2021-06-10 08:15:49

CSS 文字動畫技巧

2022-08-23 08:01:09

CSS前端
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩电影免费观看中文字幕 | 久久精品国产免费一区二区三区 | 日韩有码在线播放 | 国产高清在线 | 国产精品久久国产精品久久 | 国产精品成人一区二区三区夜夜夜 | 久久久久久综合 | 欧美日韩精品免费观看 | 久久久久久国产精品久久 | 亚洲日本免费 | 国产馆 | 国产999精品久久久久久 | 欧美一区免费 | 超碰8| 99精品免费久久久久久日本 | www.久久 | 美女视频一区 | 干狠狠 | 一区二区三区视频播放 | 成人国产免费观看 | 久久精选 | 在线a视频网站 | 午夜丰满少妇一级毛片 | 97成人精品| 亚洲精品在线看 | 日韩一级不卡 | 国产精品一区二区电影 | 久国产 | 精品视频在线观看 | 99久久99热这里只有精品 | 人人玩人人添人人澡欧美 | 亚洲电影在线播放 | 国产精品久久久久久久久久三级 | 欧美一级片久久 | 91视频进入| 综合久| 国产精品地址 | 久久精品久久久 | 狠狠夜夜| 二区亚洲 | 天堂中文字幕av |