前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Linux内核笔记之中断映射

Linux内核笔记之中断映射

作者头像
刘盼
发布于 2021-07-05 13:08:07
发布于 2021-07-05 13:08:07
5.1K00
代码可运行
举报
文章被收录于专栏:人人都是极客人人都是极客
运行总次数:0
代码可运行

硬中断和虚拟中断号

Linux 内核笔记之高层中断处理一文中,介绍了ARM gic中断控制器对于硬中断的处理过程。gic的中断处理程序是从ack一个硬件中断开始的, 在gic的中断处理过程中,会根据中断的映射去寻找对应的虚拟中断号, 再去进行后续的中断处理。gic_handle_irq->handle_domain_irq

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
   bool lookup, struct pt_regs *regs)
{
...
#ifdef CONFIG_IRQ_DOMAIN
 if (lookup)
  irq = irq_find_mapping(domain, hwirq);   ---- 获得虚拟中断号
#endif
...
}

那么问题来了,为什么要有一个虚拟中断号的概念?当前的SOC,通常内部会有多个中断控制器(比如gic interrupt controller, gpio interrupt controller), 每一个中断控制器对应多个中断号, 而硬件中断号在不同的中断控制器上是会重复编码的, 这时仅仅用硬中断号已经不能唯一标识一个外设中断。对于软件工程师而言,我们不需要care是中断哪个中断控制器的第几个中断号, 因此linux kernel提供了一个虚拟中断号的概念。

irq_domain

接下来讨论硬件中断号是如何映射到虚拟中断号的linux kernel提供irq_domain的管理框架, 将hwirq映射到虚拟中断号上。每一个中断控制器都需要注册一个irq_domain。

irq_domain数据结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct irq_domain {
        struct list_head link;
        const char *name;
        const struct irq_domain_ops *ops;
        void *host_data;
        unsigned int flags;
        unsigned int mapcount;

        /* Optional data */
        struct fwnode_handle *fwnode;
        enum irq_domain_bus_token bus_token;
        struct irq_domain_chip_generic *gc;
#ifdef  CONFIG_IRQ_DOMAIN_HIERARCHY
        struct irq_domain *parent;
#endif
#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
        struct dentry           *debugfs_file;
#endif

        /* reverse map data. The linear map gets appended to the irq_domain */
        irq_hw_number_t hwirq_max;
        unsigned int revmap_direct_max_irq;
        unsigned int revmap_size;
        struct radix_tree_root revmap_tree;
        struct mutex revmap_tree_mutex;
        unsigned int linear_revmap[];
};
  • link: 用于将irq domain连接到全局链表irq_domain_list中;
  • name: irq domain的名称;
  • ops: irq domain映射操作使用方法的集合;
  • mapcount: 映射好的中断的数量;
  • fwnode: 对应中断控制器的device node;
  • parent: 指向父级irqdomain的指针,用于支持级联irq_domain;
  • hwirq_max: 该irq domain支持的中断最大数量;
  • revmap_tree:Radix Tree 映射的根节点;
  • linear_revmap:hwirq->virq 反向映射的线性表;

从该结构体中我们可以看出irq_domain支持多种类型的映射。

irq_domain映射类型

  • 线性映射

线性映射保留一张固定的表,通过hwirq number来索引.当hwirq被映射后, 会相应地分配 一个irq_desc, IRQ number就被存在表中。当hwirqs是固定的而且小于256, 用线性映射更好。它的优势是寻找时间固定,并且irq_descs只在in-use IRQs分配.缺点是表格和hwirq 最大numbers一样大。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
irq_domain_add_linear
  • 树映射

此种方法使用radix tree来维护映射, 通过key来查找此方法适合hwirq number非常大的时候, 因为它不需要分配和hwirq一样大的table。缺点是查表效率依赖与table里的entries数量。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
irq_domain_add_tree
  • 不映射

当有些硬件可以对hwirq number编程时,IRQ number被编进硬件寄存器里,那么就不需要映射了。这种情况下通过irq_create_direct_mapping()实现。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
irq_domain_add_nomap

中断映射的完整过程

以arm64 dtb启动为例分析完整的中断映射过程。

  • interrupt controller初始化的过程中,注册irq domain

以gic 注册irq_domain为例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+-> gic_of_init
 +-> gic_init_bases
  +-> irq_domain_add_linear
   +-> _irq_domain_add
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
        irq_hw_number_t hwirq_max, int direct_max,
        const struct irq_domain_ops *ops,
        void *host_data)
{
 struct device_node *of_node = to_of_node(fwnode);
 struct irqchip_fwid *fwid;
 struct irq_domain *domain;

 static atomic_t unknown_domains;

 domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size),
         GFP_KERNEL, of_node_to_nid(of_node));       
 if (WARN_ON(!domain))
  return NULL;
 ...
 of_node_get(of_node);
 /* Fill structure */
 INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
 mutex_init(&domain->revmap_tree_mutex);
 domain->ops = ops;
 domain->host_data = host_data;
 domain->hwirq_max = hwirq_max;
 domain->revmap_size = size;
 domain->revmap_direct_max_irq = direct_max;
 irq_domain_check_hierarchy(domain);

 mutex_lock(&irq_domain_mutex);
 debugfs_add_domain_dir(domain);
 list_add(&domain->link, &irq_domain_list);     
 mutex_unlock(&irq_domain_mutex);

 pr_debug("Added domain %s\n", domain->name);
 return domain;
}

irq_domain_add()用于初始化一个irq_domain数据结构。irq_domain分配的内存大小为sizeof(*domain) + (sizeof(unsigned int) * size), (sizeof(unsigned int) * size)大小的空间是用于linear_revmap[]成员。最后,irq_domain添加到全局的链表irq_domain_list中。

  • 外设的驱动初始化过程中,创建硬中断和虚拟中断号的映射关系设备的驱动在初始化的时候可以调用irq_of_parse_and_map这个接口函数进行该device node中和中断相关的内容的解析,并建立映射关系。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
{
 struct of_phandle_args oirq;

 if (of_irq_parse_one(dev, index, &oirq))
  return 0;

 return irq_create_of_mapping(&oirq);
}

of_irq_parse_one()函数用于解析DTS文件中设备定义的属性,如"reg", “interrupt”, 最后把DTS中的"interrupts"存放在*out_irq->args[1].

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+-> irq_create_of_mapping
 +->irq_create_fwspec_mapping
  +-> irq_find_matching_fwspec // 找到device node对应的irq_domain, 每一个irq_domain都定义了一系列的映射相关的方法
  +-> irq_domain_translate //解析中断信息,如硬件中断号, 中断出发类型
   +-> domain->ops->translate (gic_irq_domain_translate)
  +-> irq_create_mapping // 映射硬件中断号到虚拟中断号
   +-> irq_domain_alloc_descs // 分配一个虚拟中断号 从allocated_irq位图中取第一个空闲的bit位作为虚拟中断号
    +-> irq_domain_alloc_irqs_hierarchy
     +-> domain->ops->alloc (gic_irq_domain_alloc)
      +-> gic_irq_domain_map // gic创建硬中断和虚拟中断号的映射,并且根据中断类型设置struct irq_desc->handle_irq处理函数
   +-> irq_domain_associate
     +-> domain->ops->map 
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+->gic_irq_domain_map 
 +-> irq_domain_set_info
  +-> irq_domain_set_hwirq_and_chip
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int irq_domain_set_hwirq_and_chip(struct irq_domain *domain, unsigned int virq,
      irq_hw_number_t hwirq, struct irq_chip *chip,
      void *chip_data)
{
 struct irq_data *irq_data = irq_domain_get_irq_data(domain, virq);

 if (!irq_data)
  return -ENOENT;

 irq_data->hwirq = hwirq;
 irq_data->chip = chip ? chip : &no_irq_chip;
 irq_data->chip_data = chip_data;

 return 0;
}

通过虚拟中断号获取irq_data结构体,并将hwirq设置到irq_data->hwirq中, 完成了硬中断到虚拟中断号的映射。

转自:https://blog.csdn.net/yhb1047818384/article/details/63687126

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 人人都是极客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
IDEA使用ideaVim, 配置自定义vim快捷键
.ideavimrc 配置文件 其实很简单,修改 ideavim 的配置文件 .ideavimrc 即可。默认情况下该文件并不存在,需要自行创建。macOS 或 Linux 下直接在当前用户目录下新建即可。(Windows 下应该也是在用户目录下新建配置文件,不过文件名应该是 _ideavimrc。)
全栈程序员站长
2022/11/10
3.2K0
IDEA使用ideaVim, 配置自定义vim快捷键
定制 vim 插件:ideavim
Jetbrains 的很多产品还是非常好用的,IntelliJ IDEA, PyCharm, Clion 等等都非常受欢迎。 因为我比较喜欢 vim, 因此在使用这些 IDE 时都会装上 vim 的插件:ideavim. 不过因为我对 vim 的默认配置更改了很多,定制了很多快捷键等等,在使用默认配置下的 ideavim 时还是有些不太顺手,因此针对 ideavim 定制一些 vim 的配置便十分有必要了。
用户1558438
2018/08/23
3K0
ideavim怎么用_idea基本使用教程
ideavim是JetBrains官方开发的模拟vim插件,熟练ideavim的人可以更快的进行操作,大部分操作都可以用键盘来代替。 纯vim也能进行更高效的开发,但是一款适合自己深定义的配置,能够让人更加高效。配合ide的智能补全,就一个字爽
全栈程序员站长
2022/11/10
1.8K0
ideavim怎么用_idea基本使用教程
VIM配置文件vimrc
Ubuntu 默认情况下只安装tiny-vim , 只要运行 sudo apt-get install vim 安装完整的vim就好了
阳光岛主
2019/02/19
2.8K0
idea vim 配置[通俗易懂]
” 设置 jk 映射为 esc键 inoremap jk <ESC> inoremap kj <ESC>
全栈程序员站长
2022/11/11
1.2K0
ideavim有什么用_intellij idea社区版
使用vim,最大的好处,是减少打代码的时候进行键鼠切换的频率。有一种相当不错流畅感,当然需要有一定的vim基础才行。
全栈程序员站长
2022/11/10
1.7K0
ideavim怎么用_idea常用快捷键图文
学了这么久的VIM,当然还是要用在开发上。下面来介绍一下ideavim这个插件。 IdeaVim是用于基于IntelliJ平台的IDE的Vim仿真插件。IdeaVim支持许多Vim功能,包括普通/插入/可视模式,动作键,删除/更改,标记,寄存器,一些Ex命令,Vim regexp,通过〜/ .ideavimrc配置,宏,窗口命令等。另外还可以自定义ideavim的快捷键,定制专属的快捷键。
全栈程序员站长
2022/11/10
8810
ideavim怎么用_idea常用快捷键图文
vim01-环境配置
现在开发、写文章基本上已经离不开 vim了,写代码idea + vim 配合,写文章就是直接上 vim。vim 有一定的学习曲线,但是习惯了就好。 习惯以后,再使用这些插件就会更好用。
潇洒
2020/12/18
1.4K0
vim01-环境配置
Vim 3 vimrc[通俗易懂]
vimrc 是 Vim 的配置文件, Vim 在启动时会加载 vimrc 文件, 你能想到的几乎所有的配置(包括主题, 快捷键, 插件设置等等), 都可以配置在 vimrc 中, 所以, vimrc 在 Vim 使用过程中有着至关重要的地位. Vim 是极其依赖 vimrc 配置的, 没有经过配置的 Vim 又丑又难用, 但是你如果懂得怎么配置, 就可以把 Vim 变成你想要的样子.
全栈程序员站长
2022/08/30
3.1K0
我的vim配置文件,再度升级
原来的repo放在 spf13-vim-leoatchina,因为原来一时脑抽,把中文字体放进去后导致体积较大,影响速度,所以重开一个repo并把windows下的工具分开,以增加clone速度。
py3study
2020/01/03
1K0
请品鉴我的vim配置
背景 本人是生信工程师,主要使用的语言是 python, R, perl, shell,经常要ssh到远程服务器上写代码,因此学习了vim,后来发现了spf13-vim:steve francia's vim distribution,大大提高了写代码的效率。但是,原配置仍然有很多插件和配置不符合我的需要,因此,fork后进行了大量的修改.请访问leoatchina的vim配置文件.由于本人水平所限,一定有很多错误和bug,望各位指正. 注意使本配置文件后可能会影响vim运行流畅度. 对使用者的要求 掌握v
生信技能树
2018/03/09
2K0
请品鉴我的vim配置
jetbrains vim插件配置
首先, vi ~/.ideavimrc windows 编辑(创建) c://User//你的用户//_ideavimrc 内容: " 剪贴板设为系统" set clipboard=unnamedplus set backspace=2 set ts=4 set sw=4 set autoindent let mapleader="\" " 双击jj退出编辑模式,好用" inoremap jj <Esc> " ctrl+l,h,左右切换tab" noremap <C-l> gt noremap <
超级大猪
2019/11/27
8560
vim配置总结[通俗易懂]
我的vim版本是8.1,这个版本可以在vim中直接调用terminal,并且自带的插件管理器。如果你不是8.1的vim版本,可能无法使用我下面的插件安装方法,需要自行百度下载一个插件管理器了。
全栈程序员站长
2022/08/31
1.7K0
Vim的配置说明
在网上参考了某大牛个vim配置,然后更改添加了一部分,形成了自己的配置,让Vim变的更强大。
xindoo
2021/01/21
1K0
Docker - Nginx定制
直接采用Nginx镜像进行定制修改 Docker容器换源 常用软件 apt-get install vim apt-get install lrzsz apt-get install zip unzip apt-get install git 安装 上传 vimplus.zip 解压文件 进入文件夹 可以先编辑配置文件 vim .vimrc """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " 通用设置 """""
断痕
2021/01/21
2.1K0
VIM个性化配置(一)
只需在Home目录创建一个 ~/.vimrc 文件即可以配置 vim 了,如需安装插件,在 ~/.vim 目录下创建一个bundle文件夹,插件装在里面。(需安装 Vundle 插件管理器),将以下内容拷入~/.vimrc 文件中即可。
宋天伦
2020/07/27
1.4K0
千姿百态,瞬息万变,Win11系统NeoVim打造全能/全栈编辑器(前端/Css/Js/Vue/Golang/Ruby/ChatGpt)
    我曾经多次向人推荐Vim,其热情程度有些类似现在卖保险的,有的时候,人们会因为一些弥足珍贵的美好暗暗渴望一个巨大的负面,比如因为想重温手动挡的快乐而渴望买下一辆二十万公里的老爷车,比如因为所谓完美的音质而舍不得一个老旧的有线耳机,比如因为一个铜炉火锅而期待北京那漫长而寒冷的冬天。
用户9127725
2023/03/01
8500
千姿百态,瞬息万变,Win11系统NeoVim打造全能/全栈编辑器(前端/Css/Js/Vue/Golang/Ruby/ChatGpt)
vim的配置_vim全局配置
因为写了一段时间前端,一直在考虑vim是否能够替代前端无敌编辑器vscode,最后发现只能高仿,自己配置的性能跟vscode下的vim模式差不多,灵活性更高点,喜欢折腾的朋友可以试试,否则用vscode vim模式吧,已经神一般的完美了(不是高级黑-。-)。 这套插件目前包含了代码自动补全,目录树,js/jsx eslint自动格式化,小黑屋模式, 文件搜索ctrlp,快速检索ack,emmet,函数工具条还有各种奇奇插插的主题配置而成, 别想歪。这里我做了一堆的配置,大家可以根据个人喜好,配置任意的快捷键。我是一边做一边写的文章,有些东西可能没考虑到,有问题可以给我留言。
全栈程序员站长
2022/11/14
2.9K0
vim的配置_vim全局配置
vim配置IDE,下载压缩包即拥有轻巧且强大的文本编辑器
用 vim 也有一段时间了, 真心是越用越好用, 现已作为敲代码主力以及默认文本编辑器。
杨永贞
2022/04/13
7720
vim配置IDE,下载压缩包即拥有轻巧且强大的文本编辑器
Vim 插件: vim-which-key
emacs 用户相信应该对于 emacs-which-key 很熟悉,如果你在一定时间没有输入下一个按键,它会自动显示接下来可能的所有快捷键映射,这对于常常需要多组合键的 emacs 来说很是方便。我在一开始使用 spacemacs 的时候,就被这个功能所吸引。不过一直以来 vim 中都缺少像 emacs-which-key 这样“形神兼备”的插件,这一点我在 space-vim 的 README 中也一早有提及。
用户1558438
2018/10/15
2.9K0
相关推荐
IDEA使用ideaVim, 配置自定义vim快捷键
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文