NVDLA用户态驱动代码整理一


前言

本系列内容力求将nvdla的用户态驱动整理清楚,如果有分析不对的请指出。

前面已经花了不少章节详细解释NVDLA内核态驱动代码,链接分别如下:
系列文章1:NVDLA内核态驱动代码整理一
系列文章2:NVDLA内核态驱动代码整理二
系列文章3:NVDLA内核态驱动代码整理三
系列文章4:NVDLA内核态驱动代码整理四
系列文章5:NVDLA内核态驱动代码整理五
系列文章6:NVDLA内核态驱动代码整理六
系列文章7:NVDLA内核态驱动代码整理七
系列文章8:NVDLA内核态驱动代码整理八
系列文章8:NVDLA内核态驱动代码整理汇总篇

欢迎阅读硬件信号和架构分析系列文章1:
架构开篇介绍文章:NVDLA内核态驱动代码整理三
系列文章1:NVDLA硬件信号和架构设计整理一
系列文章2:NVDLA硬件信号和架构设计整理二
系列文章3:NVDLA硬件信号和架构设计整理三


一、整理和规划

先从Makefile开始看,确定哪些文件更为关键!

COMPILER_SUBDIRS = core/src/compiler \
	apps/compiler

RUNTIME_SUBDIRS = core/src/runtime \
	apps/runtime
	

# $(MAKE) -C $$dir; 这行执行了make命令,-C选项指定了要切换到的子目录。
compiler:
	for dir in $(COMPILER_SUBDIRS); do \
		$(MAKE) -C $$dir; \
	done

runtime:
	for dir in $(RUNTIME_SUBDIRS); do \
		$(MAKE) -C $$dir; \
	done

clean:
	rm -rf out/

首先Makefile清楚显示使用规则分为三条:compilerruntimeclean。与compiler密切相关的文件是core/src/compilerapps/compiler,与runtime密切相关的文件是core/src/runtimeapps/runtime。因为用户态已经靠近上层,因此不再像内核态一样深入解读,而是会抓住几个核心问题进行思考。
另外,刚解读完内核态驱动,我们都知道驱动向上暴露供更上一层使用的API,那么这堆API如何被定义?可以发现umd文件夹中包含了port/linux文件夹,文件夹内容有nvdla_os.cnvdla.c,我们可以先看nvdla.c文件夹的开头,会发现这里出现了一位内核态驱动加载时出现的老朋友:

#include <drm.h>
#include <drm_mode.h>

#include "nvdla.h"
#include "nvdla_inf.h"
#include "nvdla_ioctl.h"
#include "nvdla_os_inf.h"

#define NVDLA_DEVICE_NODE "/dev/dri/renderD128" // 定义了 NVDLA 设备节点的路径。

#define NVDLA_MEM_READ (PROT_READ)
#define NVDLA_MEM_WRITE (PROT_WRITE)

这里的/dev/dri/renderD128最早出现modprobe驱动之后查看驱动路径的时候出现,如下:
在这里插入图片描述
然后看一下官网对于运行时的博文介绍,链接在这里。根据运行时的若干函数去检索,大致可以确定core/src/runtime/Runtime.cpp是运行时功能的核心文件,而编译模块的核心文件落在core/src/compiler/Compiler.cpp

二、需要回答的几个问题

那接下来就有几个问题:
1、用户态驱动做了什么?如何与AI编译器协作?
2、用户态驱动程序如何调用封装好的内核态驱动API?
3、根据流程,内核态驱动编译为.ko之后使用mdprobe加载到Ubuntu上,用户态驱动程序如同应用程序一样编译运行到Ubuntu上,那怎么理解一段已经运行好的二进制(内核态驱动)会帮到待运行的二进制(用户态驱动)?

1、第一个问题的回答比较容易,其实就是借助POSIX的线程库和两个驱动节点card0renderD128file operation实现下陷后的调用,用户态驱动向上暴露接口提供给AI编译器。由于大佬在这篇文章中提到NVDLA的软件栈分为两个部分,一个是Compiler,Compiler在自己的主机上编译是与硬件无关的,而Runtime则需要调用KMD程序调度加速器,只能在板卡上运行。在这小节我们的目标是在ARM处理器上编译出Runtime,打通软件栈,所以我并不打算针对编译器部分进行解释。
2、第二个问题值得深究,可以在nvdla.c文件中找到两个很关键的fdNvDlaDeviceHandleNvDlaMemHandle结构体中各自定义了一个fd,这两个不同的fd可以追溯到renderD128card0。那怎么调用?举个open的例子,用户态open=>内核态do_sys_open=>内核态文件操作中的open,用户态的close可以向下追溯到内核态的release
3、第三个问题本质上就是第二个问题。但是注意内核版本需要保持一致。


总结

本文开篇用户态驱动,并对将要分析的.c文件进行了过滤。

扫描二维码关注公众号,回复: 17284253 查看本文章

猜你喜欢

转载自blog.csdn.net/weixin_41029027/article/details/134503168