io资源记录

本文详细介绍了在x86平台上,如何使用in/out等指令访问IO端口,并通过resource数据结构管理端口资源。request_resource和allocate_resource函数用于资源分配,而release_resource用于释放。此外,对于非统一编址,通过ioremap函数实现IO地址到内存的映射,确保设备访问。
摘要由CSDN通过智能技术生成

针对io端口单独编址的情况(x86),可以使用专用道指令in\out\ins\outs指令访问,针对这样的情况内核会用一些数据结构如resource 管理这些端口。

使用

struct resource {
        const char *name; //资源拥有者名称
        unsigned long start, end; //资源范围的起止地址
        unsigned long flags;//各种标志
        struct resource *parent, *sibling, *child; //指向资源树的父、兄、子的指针
};
此节点的孩子都被链在一个链表内,首元素被child指向

1、request_resource函数检查资源范围是否冲突,不冲突则将指定的资源挂入资源树

      a、加锁resource_lock

       b、调用__request_resource申请资源,如果发现了范围冲突则返回冲突的节点

        c、释放锁,检查冲突节点,如果没有冲突节点则__request_resource会将指定的资源挂入资源树,如果有直接返回-EBUSY错误

2、int allocate_resource(struct resource *root, struct resource *new,
                      unsigned long size,
                      unsigned long min, unsigned long max,
                      unsigned long align,
                      void (*alignf)(void *, struct resource *,
                                     unsigned long, unsigned long),
                      void *alignf_data)

          a、加锁resource_lock

          b、调用find_resource函数查找

          c、调用__request_resource申请资源

          d、释放锁

          e、成功返回0或者失败返回-EBUSY

3、int release_resource(struct resource *old) 释放io资源

          a、加锁resource_lock

          b、调用__release_resource函数去从资源树上取下需要释放的资源节点

           c、释放resource_lock,成功返回0,失败返回-EBUSY

针对非统一编址则需要将io地址空间映射为内存地址里的一部分

主要通过ioremap函数来进行映射

void __iomem *
__ioremap(unsigned long phys_addr, size_t size, unsigned long flags,
          unsigned long align)

    a、计算出映射的最后地址范围,进行页面对齐

    b、调用get_vm_area函数获取vmalloc一块符合大小的虚拟内存

    c、调用remap_area_pages将虚拟地址与物理端口地址进行映射绑定

    d、出错了则释放c步骤申请的虚拟地址

    e、返回申请的虚拟地址与页面对齐返回的offset

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值