日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
探秘linux ioremap:物理地址映射的奧秘 (linux ioremap)

探秘linux ioremap:物理地址映射的奧秘

站在用戶的角度思考問題,與客戶深入溝通,找到廊坊網(wǎng)站設(shè)計(jì)與廊坊網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請(qǐng)域名、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋廊坊地區(qū)。

Linux操作系統(tǒng)已經(jīng)成為世界上最廣泛使用的操作系統(tǒng)之一,它具有高度的可定制性和多線程優(yōu)化,是開發(fā)人員和運(yùn)維人員的首選之一。盡管Linux在應(yīng)用程序開發(fā)、安全性以及系統(tǒng)性能等方面達(dá)到了驚人的高度,但是針對(duì)硬件的處理卻仍然是非常復(fù)雜的。雖然Linux可以通過文件系統(tǒng)或映射文件的方式訪問外部硬件,但是這種方式并不是最為高效的。因此,Linux內(nèi)核特別提供了一個(gè)叫做 ioremap() 的功能來處理這個(gè)問題。

性質(zhì)和用途

ioremap()是Linux內(nèi)核提供給系統(tǒng)開發(fā)人員的一種機(jī)制,用來映射物理地址空間到虛擬地址空間。具體的來說,ioremap()可以將從內(nèi)核訪問的物理地址轉(zhuǎn)換為在用戶空間下可用的虛擬地址。這個(gè)轉(zhuǎn)換的過程實(shí)際上涉及到對(duì)某些特殊內(nèi)存區(qū)域進(jìn)行訪問,因此必須謹(jǐn)慎地處理這個(gè)過程。

在Linux中,訪問一些系統(tǒng)資源,如帶有Memory-Mapped I/O、Direct Memory Access、系統(tǒng)緩存等的硬件設(shè)備,需要直接訪問物理內(nèi)存地址,而不能使用標(biāo)準(zhǔn)的Linux系統(tǒng)調(diào)用。這是因?yàn)樵谶@些場(chǎng)景下,訪問效率非常的關(guān)鍵。因此,Linux內(nèi)核提供了ioremap()這個(gè)接口,它可以直接訪問物理內(nèi)存地址。正是因?yàn)樗哂羞@種特殊性質(zhì),所以ioremap()是Linux內(nèi)核開發(fā)人員不可或缺的工具之一。

內(nèi)部機(jī)制

ioremap()函數(shù)的具體實(shí)現(xiàn)和具體的架構(gòu)息息相關(guān)。 Linux 內(nèi)核體系結(jié)構(gòu)非常復(fù)雜,所以涉及到不同架構(gòu)的計(jì)算機(jī)時(shí),可能會(huì)出現(xiàn)平臺(tái)相關(guān)性問題。但是,不管是哪一種架構(gòu),ioremap() 都是通過直接地址映射的方式將物理地址映射到虛擬地址空間的。

當(dāng)系統(tǒng)開發(fā)人員需要使用ioremap()函數(shù)時(shí),首先需要向系統(tǒng)內(nèi)核請(qǐng)求一個(gè)虛擬地址。內(nèi)核會(huì)為調(diào)用者分配并返回一個(gè)適當(dāng)?shù)奶摂M地址。系統(tǒng)內(nèi)核在返回的虛擬地址中記錄了映射位置以及相關(guān)信息,以便在需要的時(shí)候該函數(shù)可以返回正確的地址。

此時(shí)ioremap()函數(shù)已經(jīng)在虛擬地址空間中設(shè)置了要關(guān)聯(lián)的范圍和屬性,當(dāng)需要讀取一個(gè)特定硬件設(shè)備的值時(shí),開發(fā)人員在確定了正確的物理地址之后,使用ioremap()函數(shù)將其映射到虛擬地址。一個(gè)已經(jīng)映射的物理地址所對(duì)應(yīng)的虛擬地址是通過讀取對(duì)應(yīng)的寄存器來響應(yīng)的。這個(gè)過程很快,而且可以在通過虛擬地址指針讀取或?qū)懭霝橛布A舻募拇嫫鞯耐瑫r(shí),實(shí)際上是在讀取或?qū)懭雰?nèi)存中對(duì)應(yīng)的值。

iolist()函數(shù)是Linux內(nèi)核提供給系統(tǒng)開發(fā)人員的一種高效的機(jī)制,用于將物理地址轉(zhuǎn)換為用戶可訪問的虛擬地址。在Linux內(nèi)核中,訪問某些系統(tǒng)資源需要直接訪問物理內(nèi)存地址,這時(shí)必須使用特殊的方法來實(shí)現(xiàn),而iolist()正是為此而生。雖然iolist()在不同架構(gòu)的機(jī)器上需要進(jìn)行平臺(tái)相關(guān)性的處理,但是它在提高系統(tǒng)性能和優(yōu)化系統(tǒng)開發(fā)方面的作用是不可小覷的。

相關(guān)問題拓展閱讀:

  • 在Linux內(nèi)核中,注冊(cè)字符設(shè)備驅(qū)動(dòng)程序的函數(shù)是?

在Linux內(nèi)核中,注冊(cè)字符設(shè)備驅(qū)動(dòng)程序的函數(shù)是?

字符設(shè)備驅(qū)動(dòng)程序框架 1、寫出open、write函數(shù) 2、告訴內(nèi)核 1)、定義一個(gè)struct file_operations結(jié)構(gòu)并填充好 static struct file_operations first_drv_fops = { .owner = THIS_MODULE, /* 這是一個(gè)宏,推向編譯模塊時(shí)自動(dòng)創(chuàng)建的__this_module變量 */ .open = first_drv_open, .write = first_drv_write, }; 2)、把struct file_operations結(jié)構(gòu)體告訴內(nèi)核 major = register_chrdev(0, “first_drv”, &first_drv_fops); // 注冊(cè), 告訴內(nèi)核相關(guān)參數(shù):之一個(gè),設(shè)備號(hào),0自動(dòng)分配主設(shè)備號(hào),否則為主設(shè)備號(hào)0-255 第二個(gè):設(shè)備名第灶銷二個(gè):struct file_operations結(jié)構(gòu)體 4)、register_chrdev由誰調(diào)用(入口函數(shù)調(diào)用) static int first_drv_init(void) 5)、入口函數(shù)須使用內(nèi)核宏來修飾 module_init(first_drv_init); module_init會(huì)定義一個(gè)結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體里面有一個(gè)函數(shù)指針指向first_drv_init這個(gè)函數(shù),當(dāng)我們加載或安裝一個(gè)驅(qū)動(dòng)時(shí),內(nèi)核會(huì)自動(dòng)找到這個(gè)結(jié)構(gòu)體,然后調(diào)用里面的函數(shù)指針,這個(gè)函數(shù)指針指向first_drv_init這個(gè)函數(shù),first_drv_init這個(gè)函數(shù)就是把struct file_operations結(jié)構(gòu)體告訴內(nèi)核 6)、有入口函數(shù)就有出口函數(shù) module_exit(first_drv_exit); 最后加上協(xié)議 MODULE_LICENSE(“GPL”); 3、mdev根據(jù)系統(tǒng)信息自動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn): 每次寫驅(qū)動(dòng)都要手動(dòng)創(chuàng)建設(shè)備文件過于麻煩,使用設(shè)備管理文件系統(tǒng)則方便很多。在2.6的內(nèi)核以前一直使用的是devfs,但是它存在許多缺陷。它創(chuàng)建了大量的設(shè)備文件,其實(shí)這些設(shè)備更本不存在。而且設(shè)備與設(shè)備文件的映射具有不確定性,比如U盤即可能對(duì)應(yīng)sda,又可能對(duì)應(yīng)sdb。沒有足夠的主/輔設(shè)備號(hào)。2.6之后的內(nèi)核引入了sysfs文件系統(tǒng),它掛載在/sys上,配合udev使用,可以很好的完成devfs的功能,并彌補(bǔ)了那些缺點(diǎn)。(這里說一下,當(dāng)今內(nèi)核已經(jīng)使用隱物游netlink了)。 udev是用戶空間的一個(gè)應(yīng)用程序,在嵌入式中用的是mdev,mdev在busybox中。mdev是udev的精簡(jiǎn)版。首先在busybox中添加支持mdev的選項(xiàng): Linux System Utilities —> mdev Support /etc/mdev.conf Support subdirs/symlinks Support regular expressions substitutions when renaming device Support command execution at device addition/removal 然后修改/etc/init.d/rcS: echo /螞乎in/mdev > /proc/sys/kernel/hotplug /in/mdev -s 執(zhí)行mdev -s :以‘-s’為參數(shù)調(diào)用位于 /in目錄寫的mdev(其實(shí)是個(gè)鏈接,作用是傳遞參數(shù)給/bin目錄下的busybox程序并調(diào)用它),mdev掃描 /sys/class 和 /sys/block 中所有的類設(shè)備目錄,如果在目錄中含有名為“dev”的文件,且文件中包含的是設(shè)備號(hào),則mdev就利用這些信息為這個(gè)設(shè)備在/dev 下創(chuàng)建設(shè)備節(jié)點(diǎn)文件。一般只在啟動(dòng)時(shí)才執(zhí)行一次 “mdev -s”。熱插拔事件:由于啟動(dòng)時(shí)運(yùn)行了命 令:echo /in/mdev > /proc/sys/kernel/hotplug ,那么當(dāng)有熱插拔事件產(chǎn)生時(shí),內(nèi)核就會(huì)調(diào)用位于 /in目錄的mdev。這時(shí)mdev通過環(huán)境變量中的 ACTION 和 DEVPATH,來確定此次熱插拔事件的動(dòng)作以及影響了/sys中的那個(gè)目錄。接著會(huì)看看這個(gè)目錄中是否“dev”的屬性文件,如果有就利用這些信息為 這個(gè)設(shè)備在/dev 下創(chuàng)建設(shè)備節(jié)點(diǎn)文件重新打包文件系統(tǒng),這樣/sys目錄,/dev目錄就有東西了下面是create_class的原型: #define class_create(owner, name) / ({ / static struct lock_class_key __key; / __class_create(owner, name, &__key); / }) extern struct class * __must_check __class_create(struct module *owner, const char *name, struct lock_class_key *key); class_destroy的原型如下: extern void class_destroy(struct class *cls); device_create的原型如下: extern struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, …) __attribute__((format(printf, 5, 6))); device_destroy的原型如下: extern void device_destroy(struct class *cls, dev_t devt); 具體使用如下,可參考后面的實(shí)例: static struct class *firstdrv_class; static struct class_device *firstdrv_class_dev; firstdrv_class = class_create(THIS_MODULE, “firstdrv”); firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, “xyz”); /* /dev/xyz */ class_device_unregister(firstdrv_class_dev); class_destroy(firstdrv_class); 下面再來看一下應(yīng)用程序如何找到這個(gè)結(jié)構(gòu)體的在應(yīng)用程序中我們使用open打開一個(gè)設(shè)備:如:open(/dev/xxx, O_RDWR); xxx有一個(gè)屬性,如字符設(shè)備為c,后面為讀寫權(quán)限,還有主設(shè)備名、次設(shè)備名,我們注冊(cè)時(shí) 通過register_chrdev(0, “first_drv”, &first_drv_fops)(有主設(shè)備號(hào),設(shè)備名,struct file_operations結(jié)構(gòu)體)將first_drv_fops結(jié)構(gòu)體注冊(cè)到內(nèi)核數(shù)組chrdev中去的,結(jié)構(gòu)體中有open,write函數(shù),那么應(yīng)用程序如何找到它的,事實(shí)上是根據(jù)打開的這個(gè)文件的屬性中的設(shè)備類型及主設(shè)備號(hào)在內(nèi)核數(shù)組chrdev里面找到我們注冊(cè)的first_drv_fops,實(shí)例代碼: #include #include #include #include #include #include #include #include #include #include static struct class *firstdrv_class; static struct class_device *firstdrv_class_dev; volatile unsigned long *gpfcon = NULL; volatile unsigned long *gpfdat = NULL; static int first_drv_open(struct inode *inode, struct file *file) { //printk(“first_drv_open\n”); /* 配置GPF4,5,6為輸出 */ *gpfcon &= ~((0x3); return 0; } if (strcmp(argv, “on”) == 0) { val = 1; } else { val = 0; } write(fd, &val, 4); return 0; }linux ioremap的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux ioremap,探秘linux ioremap:物理地址映射的奧秘,在Linux內(nèi)核中,注冊(cè)字符設(shè)備驅(qū)動(dòng)程序的函數(shù)是?的信息別忘了在本站進(jìn)行查找喔。

成都網(wǎng)站設(shè)計(jì)制作選創(chuàng)新互聯(lián),專業(yè)網(wǎng)站建設(shè)公司。
成都創(chuàng)新互聯(lián)10余年專注成都高端網(wǎng)站建設(shè)定制開發(fā)服務(wù),為客戶提供專業(yè)的成都網(wǎng)站制作,成都網(wǎng)頁(yè)設(shè)計(jì),成都網(wǎng)站設(shè)計(jì)服務(wù);成都創(chuàng)新互聯(lián)服務(wù)內(nèi)容包含成都網(wǎng)站建設(shè),小程序開發(fā),營(yíng)銷網(wǎng)站建設(shè),網(wǎng)站改版,服務(wù)器托管租用等互聯(lián)網(wǎng)服務(wù)。


分享題目:探秘linux ioremap:物理地址映射的奧秘 (linux ioremap)
路徑分享:http://www.dlmjj.cn/article/djceoog.html