mmu頁(yè)表映射-> 物理地址 的形式正確地訪問(wèn)到物理地址了。 ARM Linux 引入設(shè)備樹特性后,一些支持設(shè)備樹的設(shè)備" />

色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

為什么Linux操作寄存器要ioremap

麥辣雞腿堡 ? 來(lái)源:老吳嵌入式 ? 作者:吳偉東Jack ? 2023-07-20 10:23 ? 次閱讀

1. 原因

  • 這里只考慮有 MMU 的芯片Linux 為了實(shí)現(xiàn)進(jìn)程虛擬地址空間,在啟用 MMU 后,在內(nèi)核中操作的都是虛擬地址,內(nèi)核訪問(wèn)不到物理地址。
  • 如果在驅(qū)動(dòng)里直接訪問(wèn)物理地址,等于訪問(wèn)了一個(gè)非法地址,會(huì)導(dǎo)致內(nèi)核崩潰,下面會(huì)有一個(gè)相關(guān)的小實(shí)驗(yàn)。
  • 通過(guò) ioremap 將物理地址映射為虛擬地址后,內(nèi)核就能通過(guò) ioremap() 返回的虛擬地址,以 虛擬地址->mmu頁(yè)表映射-> 物理地址 的形式正確地訪問(wèn)到物理地址了。
  • ARM Linux 引入設(shè)備樹特性后,一些支持設(shè)備樹的設(shè)備驅(qū)動(dòng)不再使用直接 ioremap(),改用 drivers/of/address.c/of_iomap(),of_iomap() 的內(nèi)部仍然會(huì)調(diào)用 ioremap(),例如:
clk-rk3288.c (driversclkrockchip)
static void rk3288_clk_init(struct device_node *np) {
    rk3288_cru_base = of_iomap(np, 0);
    [...]
}

2. ioremap() 實(shí)驗(yàn)

實(shí)驗(yàn)環(huán)境:

  • Linux-4.14 + Allwinner/H3。

實(shí)驗(yàn)代碼:

#include < linux/init.h >
#include < linux/module.h >
#include < linux/sched.h >
#include < asm/io.h >

#define USE_IOREMAP

#define H3_GPIO_BASE (0x01C20800)

static volatile unsigned long *gpio_regs = NULL;

static int __init ioremap_mod_init(void)
{

    int i = 0;
    printk(KERN_INFO "ioremap_mod initn");

#ifdef USE_IOREMAP
    gpio_regs = (volatile unsigned long *)ioremap(H3_GPIO_BASE, 1024);
#else
    gpio_regs = (volatile unsigned long *)H3_GPIO_BASE;
#endif

    for (i=0; i< 3; i++)
        printk(KERN_INFO "reg[%d] = %lxn", i, gpio_regs[i]);

    return 0;
}
module_init(ioremap_mod_init);

static void __exit ioremap_mod_exit(void)
{
    printk(KERN_INFO "ioremap_mod exitn ");

#ifdef USE_IOREMAP
    iounmap(gpio_regs);
#endif 
}

module_exit(ioremap_mod_exit);

MODULE_AUTHOR("es-hacker");
MODULE_LICENSE("GPL v2");

實(shí)驗(yàn)結(jié)果:

使用了 ioremap()

$ insmod ioremap
ioremap_mod init
reg[0] = 71227722
reg[1] = 33322177
reg[2] = 773373

未使用 ioremap():

$ insmod ioremap_mod.ko

Unable to handle kernel paging request at virtual address 01c20800
pgd = c9ece7c0
[01c20800] *pgd=6ddd7003, *pmd=00000000
Internal error: Oops: 206 [#1] SMP ARM
CPU: 1 PID: 1253 Comm: insmod Tainted: G           O    4.14.111 #116
Hardware name: sun8i
task: ef15d140 task.stack: edc50000
PC is at ioremap_mod_init+0x3c/0x1000 [ioremap_mod]
LR is at ioremap_mod_init+0x14/0x1000 [ioremap_mod]
pc : [< bf5d903c >]    lr : [< bf5d9014 >]    psr: 600e0013
sp : edc51df8  ip : 00000007  fp : 118fa95c
r10: 00000001  r9 : ee7056c0  r8 : bf5d6048
r7 : bf5d6000  r6 : 00000000  r5 : bf5d6200  r4 : 00000000
r3 : 01c20800  r2 : 01c20800  r1 : 00000000  r0 : bf5d5048
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 30c5387d  Table: 49ece7c0  DAC: b106c794
Process insmod (pid: 1253, stack limit = 0xedc50210)

[

3. ioremap() 的實(shí)現(xiàn)內(nèi)幕

ioremap() 的實(shí)現(xiàn)內(nèi)幕會(huì)涉及到比較多的內(nèi)存管理的知識(shí),這里我們拋開(kāi)代碼細(xì)節(jié)簡(jiǎn)單了解一下原理就好。

  • ioremap() 將 vmalloc 區(qū)的某段虛擬內(nèi)存塊映射到 io memory,其實(shí)現(xiàn)原理與vmalloc() 類似,都是通過(guò)在 vmalloc 區(qū)分配虛擬地址塊,然后修改內(nèi)核頁(yè)表的方式將其映射到設(shè)備的 I/O 地址空間。
  • 與 vmalloc() 不同的是,ioremap 并不需要通過(guò)伙伴系統(tǒng)去分配物理頁(yè),因?yàn)閕oremap 要映射的目標(biāo)地址是 io memory,不是物理內(nèi)存 (RAM)。

函數(shù)調(diào)用流程:

圖片

總結(jié)一下:

  • 相關(guān)檢查;
  • 分配一個(gè) vm_struct 結(jié)構(gòu)體,內(nèi)核在管理虛擬內(nèi)存中的 vmalloc 區(qū)時(shí),內(nèi)核必須跟蹤哪些子區(qū)域被使用、哪些是空閑的,對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)就是 vm_strcut。
  • 初始化 vm_struct;
  • 建立頁(yè)表;
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 芯片
    +關(guān)注

    關(guān)注

    455

    文章

    50851

    瀏覽量

    423916
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5343

    瀏覽量

    120427
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11310

    瀏覽量

    209597
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    linux系統(tǒng)中內(nèi)存分配基本原理分析

    訪問(wèn)外設(shè)的寄存器(一般包括數(shù)據(jù)寄存器、控制寄存器與狀態(tài)寄存器),需要在驅(qū)動(dòng)初始化中將外設(shè)所處的物理地址映射為虛擬地址,linux為應(yīng)對(duì)該問(wèn)題
    發(fā)表于 03-28 09:16 ?796次閱讀

    寄存器是什么?怎么操作寄存器點(diǎn)亮LED燈?

    寄存器,是集成電路中非常重要的一種存儲(chǔ)單元,通常由觸發(fā)組成。在集成電路設(shè)計(jì)中,寄存器可分為電路內(nèi)部使用的寄存器和充當(dāng)內(nèi)外部接口的寄存器這兩
    的頭像 發(fā)表于 07-21 16:59 ?4049次閱讀
    <b class='flag-5'>寄存器</b>是什么?怎么<b class='flag-5'>操作</b><b class='flag-5'>寄存器</b>點(diǎn)亮LED燈?

    iTOP-4412開(kāi)發(fā)板ioremap控制GPIO寄存器

    GPIO的讀和寫以及其它任意功能。 需要的基礎(chǔ)知識(shí)虛擬地址和物理地址內(nèi)存管理單元概念linux 驅(qū)動(dòng)模塊的加載 主要內(nèi)容GPIO 的寄存器文檔詳細(xì)介紹和說(shuō)明函數(shù) ioremap的用法
    發(fā)表于 05-16 15:13

    對(duì)寄存器操作方法的經(jīng)驗(yàn)和其總結(jié)

    接觸了一陣子的STM32函數(shù)庫(kù),使用起來(lái)挺方便的,但是很少有處理會(huì)有函數(shù)庫(kù),大部分情況下還是自己來(lái)對(duì)寄存器進(jìn)行操作,所以還是不要生疏了對(duì)寄存器
    的頭像 發(fā)表于 12-19 09:30 ?8761次閱讀
    對(duì)<b class='flag-5'>寄存器</b><b class='flag-5'>操作</b>方法的經(jīng)驗(yàn)和其總結(jié)

    寄存器操作方法_對(duì)寄存器操作的通用方法總結(jié)

    本文主要詳解寄存器操作方法以及對(duì)寄存器操作的通用方法總結(jié),具體的跟隨小編來(lái)了解一下。
    的頭像 發(fā)表于 05-22 15:53 ?2.3w次閱讀

    寄存器變量

    C語(yǔ)言中使用關(guān)鍵字register來(lái)聲明局部變量為寄存器變量。寄存器變量的值會(huì)被存放在CPU的寄存器中,每當(dāng)需要使用它們時(shí),CPU就可以直接使用,而無(wú)須再通過(guò)控制從內(nèi)存中獲取。由于
    發(fā)表于 06-03 10:13 ?2385次閱讀

    C語(yǔ)言:寄存器操作

    C語(yǔ)言:寄存器操作
    發(fā)表于 01-13 12:56 ?6次下載
    C語(yǔ)言:<b class='flag-5'>寄存器</b><b class='flag-5'>操作</b>

    STM32的寄存器操作

    STM32的寄存器操作在使用STM32單片機(jī)編程時(shí)一般都用ST給的庫(kù)函數(shù)編程,庫(kù)函數(shù)編程的底層就是對(duì)單片機(jī)寄存器操作,庫(kù)函數(shù)就是一系列寄存器
    發(fā)表于 01-13 15:43 ?19次下載
    STM32的<b class='flag-5'>寄存器</b><b class='flag-5'>操作</b>

    簡(jiǎn)述RAL寄存器模型基礎(chǔ)

    RAL(Register Abstract Layer,寄存器抽象層),通常也叫寄存器模型,顧名思義就是對(duì)寄存器這個(gè)部件的建模。本文介紹的內(nèi)容,包括對(duì)UVM
    的頭像 發(fā)表于 02-14 16:55 ?2739次閱讀
    簡(jiǎn)述RAL<b class='flag-5'>寄存器</b>模型基礎(chǔ)

    RAL寄存器模型操作圖鑒

    寄存器模型操作,指的是通過(guò)寄存器模型對(duì)RTL中寄存器進(jìn)行讀寫訪問(wèn),或者同步寄存器模型與RTL中寄存器
    的頭像 發(fā)表于 05-17 09:01 ?950次閱讀
    RAL<b class='flag-5'>寄存器</b>模型<b class='flag-5'>操作</b>圖鑒

    RAL寄存器模型操作指南

    寄存器模型操作,指的是通過(guò)寄存器模型對(duì)RTL中寄存器進(jìn)行讀寫訪問(wèn),或者同步寄存器模型與RTL中寄存器
    的頭像 發(fā)表于 07-12 09:37 ?1097次閱讀
    RAL<b class='flag-5'>寄存器</b>模型<b class='flag-5'>操作</b>指南

    Linux驅(qū)動(dòng)操作寄存器

    ,第四個(gè)參數(shù)是映射的大小。 驅(qū)動(dòng)中操作: #define?OFFSET??0x60?//某個(gè)寄存器的偏移地址 static?int?my_probe(struct?platform_device
    的頭像 發(fā)表于 09-26 16:34 ?834次閱讀

    Linux應(yīng)用層操作寄存器

    應(yīng)用層操作寄存器 驅(qū)動(dòng)中操作寄存器,需要先進(jìn)行映射將物理地址轉(zhuǎn)為虛擬地址。 但如果想在應(yīng)用層中操作寄存器
    的頭像 發(fā)表于 09-26 16:37 ?969次閱讀

    如何在shell中操作寄存器

    shell 中操作寄存器可以使用 devmem 命令. devmem 命令其實(shí)就是上述應(yīng)用層操作寄存器生成的可執(zhí)行文件,只不過(guò)busybox已經(jīng)幫我們實(shí)現(xiàn)了。 devmem 命令格式:
    的頭像 發(fā)表于 09-26 16:39 ?1068次閱讀

    Linux應(yīng)用層操作寄存器

    --- > [*] /dev/mem virtual device support Linux應(yīng)用層操作寄存器 除了直接使用devmem,我們也可以在Linux應(yīng)用層自己實(shí)現(xiàn)一個(gè)de
    的頭像 發(fā)表于 10-08 15:16 ?1242次閱讀
    <b class='flag-5'>Linux</b>應(yīng)用層<b class='flag-5'>操作</b><b class='flag-5'>寄存器</b>
    主站蜘蛛池模板: 午夜dj免费中文字幕| 日本高清不卡一区久久精品| 超碰97av 在线人人操| 综合激情区视频一区视频二区| 亚洲免费网站观看视频| 亚州中文字幕| 亚洲 欧美 国产 综合不卡| 特级毛片内射WWW无码| 色狠狠一区二区| 日韩亚射吧| 日日夜夜操操操| 日韩午夜欧美精品一二三四区| 全肉高H短篇合集| 日本性xxx| 四虎精品久久久久影院| 无敌在线视频观看免费| 小寡妇水真多好紧| 亚洲AV 中文字幕 国产 欧美| 性色无码AV久久蜜臀| 亚洲精品理论电影在线观看| 亚洲乱亚洲乱妇13p| 亚洲人成无码久久久AAA片| 亚洲免费一区| 在线国内自拍精品视频| 4480YY无码午夜私人影院| 99re10久久热| 成人国产精品玖玖热色欲| 国产高清精品自在久久| 国产学生在线播放精品视频| 好男人好资源在线观看| 久久机热视频 这里只有精品首页| 久久热在线视频精品1| 男人天堂黄色| 三男强一女90分钟在线观看| 午夜办公室在线观看高清电影| 亚洲AV永久无码精品老司机蜜桃| 亚洲免费中文| 337p欧洲亚大胆精品| 阿娇和冠希13分钟在线观看| 国产成人亚洲精品老王| 国产永久免费观看视频软件|