wiki挂载在GitHub上,国内访问较慢,目前仅作为个人wiki使用;

Linux-Kernel驱动调试

--- echo 0 > /proc/sys/kernel/sysrq 关闭 1开启 内核日志

DMESG

---dmesg指令打印的内容只与kernel相关,它的log源于内核缓冲区

//实时监控dmesg日志输出信息
[root@RedHat_test ~]# watch "dmesg | tail -20"

//输出dmesg至文档
dmesg > xx.log
==> exit后adb pull xx.log C:\Users\xxxxx

GPIO

//查看gpio信息
cd sys/kernel/debug
cat gpio

# 使能引脚GPIO1_C4
echo 52 > /sys/class/gpio/export

# 设置引脚为输入模式
echo in > /sys/class/gpio/gpio52/direction
# 读取引脚的值
cat /sys/class/gpio/gpio52/value

# 设置引脚为输出模式
echo out > /sys/class/gpio/gpio52/direction
# 设置引脚为低电平
echo 0 > /sys/class/gpio/gpio52/value
# 设置引脚为高电平
echo 1 > /sys/class/gpio/gpio52/value

# 复位引脚
echo 52 > /sys/class/gpio/unexport

GPIO被占用会报错,可能这个个引脚已被使用,需在设备树中自行查找

input事件

--- 查看linux下事件

# 查看总共有几个事件
 ls /dev/input/
 
# 查看event对应的设备信息
cat /proc/bus/iio/devices

# 直接读取事件的输入
cat /dev/input/event4

# evtest

ADC

--- 一般ADC接口有两种:温度传感器,逐次逼近ADC

# TS-ADC(Temperature Sensor):支持两通道,时钟频率必须低于800KHZ
# SAR-ADC(Successive Approximation Register):支持六通道单端10位的SAR-ADC,时钟频率必须小于13MHZ。

# 获取所有的ADC值
cat /sys/bus/iio/devices/iio\:device0/in_voltage*_raw
==> 逐次逼近ADC:1.8v上拉,10位采样率,因此读出来的值为1024,实际电压计算公式:Vresult = (1800mv * 读出来的值) / 1023;

UART-串口

串口功能
TXD发送信号线
RXD接受信号线
# 检查串口设备是否成功使能
ls /dev/tty*

FAN

# 查看风扇状态
cat /sys/class/thermal/cooling_device0/cur_state

I2C

# 查看i2c总线是否开启
ls /dev/i2c-*

I2C-TOOLS

--- 适用于挂载在I2C上的设备(例如某些挂载在i2c上的codec)

参数y:关闭交互模式,使用该参数时,不会提示警告信息。

参数a:扫描总线上的所有设备。

参数q:使用SMBus的“quick write”命令进行检测,不建议使用该参数。

参数r:使用SMBus的“receive byte”命令进行检测,不建议使用该参数。
  • i2cdetect
# 检测当前系统有几组I2C总线
i2cdetect -l

# 查看指定I2C3总线的挂载情况
i2cdetect -a 3
i2cdetect -r 3
i2cdetect -y 3 //如显示i2c3的挂载情况
  • i2cdump
# i2cdump 读取指定设备上的全部寄存器的值
i2cdump -y(自动执行yes) -f 0 0x30 //读取I2c0总线上0x30地址里面的数据
  • i2cget
# 查询单个寄存器值
# 读取指定IIC设备的某个寄存器的值,如下读取I2C0地址为0x30器件中的0x01寄存器值。
i2cget -f -y 0 0x30 0x01
  • i2cset
# 修改单个寄存器值
# 写入指定IIC设备的某个寄存器的值,如下设置I2C0地址为0x30器件中的0x01寄存器值为0x02;
i2cset -f -y 0 0x30 0x01 0x02

IO命令

--- 适合SOC寄存器查询

# 例如查询SOC上的I2S
cat proc/iomem | grep i2s
# 查询fe41000的寄存器值
io -4 -l 0x40 0xfe4100000
// -1|2|4     Sets memory access size in bytes (default byte)

image-20240118151440877

image-20240118151730657


regmap

ls /sys/kernel/debug/regmap/
cat /sys/kernel/debug/regmap/0-0020-rk817-codec/registers

image-20240118152042629


SPI

SPI功能
MOSI主设备输出/从设备输入
MISO主设备输入/从设备输出
CLOCK时钟信号线
CS0片选信号线0
CS1片选信号线1
# 检查SPI设备
ls /dev/spi*

PWM设备

# 查看pwm是否开启
ls /sys/class/pwm/

示例:
pwm1->pwmchip1
pwm5->pwmchip2
pwm7->pwmchip3

==> 操作PWM
# 将指定pwm导出到用户空间
echo 0 > /sys/class/pwm/pwmchip1/export

# 设置pwm周期 单位为ns
echo 1000000 > /sys/class/pwm/pwmchip1/pwm0/period

# 设置占空比
echo 500000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle

# 设置pwm极性
echo "normal" > /sys/class/pwm/pwmchip1/pwm0/polarity

# 使能pwm
echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable

# 取消将pwm3导出到用户空间
echo 0 > /sys/class/pwm/pwmchip1/unexport

Interrupts 中断信息

//查看Linux内核的中断信息
cat /proc/interrupts   //这个主要是硬件中断信息
==>hp-det-gpio = <&gpio4 RK_PA4 GPIO_ACTIVE_LOW>; 耳机设置后会看到headset中断
中断号 CPU0  CPU1  CPU2  CPU3使用次数                                   中断名字
119:    0     0     0     0        rockchip_gpio_irq   4 Edge      headset_detect


cat /proc/softirqs     //软中断


cat /sys/kernel/irq/xxx //可以看到具体的中断信息

音频功能调试-Linux

--- Linux 使用alsa;Android使用tinyalsa

  • Lingx 音频调试方法
# 查看当前已注册的声卡
cat /proc/asound/cards

# 查询音频时钟,确认时钟设置是否正确
cat /sys/kernel/debug/clk/clk_summary | egrep "i2s1|pll"

# 获取录音设备
aplay -l

# 获取录音设备
arecord -l

# 查看声卡驱动目录
ls /dev/snd/

# 列出可以控制card 1的控制器
amixer controls -c 1

# 列出所有card 1控制器能配置的值
amixer contents -c 1

# 查看声卡0控制器2的可配置的值
amixer -Dhw:0 cget numid=2
amixer -c 0 cget numid=2

# 设置声卡0控制2的值为3
amixer -Dhw:0 cset numid=2 3
amixer -c 0 cset numid=2 3

# 图形化查看当前信息
alsamixer

# 指定声卡0播放音频文件
aplay -D hw:0 test.wav
aplay -c 0 test.wav

# 使用声卡0,cd音质,录制10s
arecord -f cd -Dhw:1 -d 10 test.wav

# 使用card 1录制并使用card 1进行播放
sudo arecord -f cd -Dhw:1 | aplay -Dhw:1
  • 后续补充alsaloop、play、pacmd、pluseaudio指令

  • -Dhw:0,0详解

    • 第一位0是指定0声卡,第二位0是指定设备0;实际完整命令如:aplay -Dhw:0,0 test.wav;
  • -Dhw:0,0 和 -Dplughw:0,0的区别

  • hw:是直接访问硬件

  • plughw:是经过采样率和格式转换的插件

= =>如RK平台,录播都是仅支持2ch,如果直接使用hw:0,0播放mono文件则会报错:Channels count non available;只能使用stereo;

但是可以使用plughw:0,0的方式播放mono文件

  • 录音也可以使用plughw:0的方式录制mono格式的音频

= => plughw:0 很好用


音频功能调试-Andorid



自定义log打印

/* Debug */
#if 1
#define DBG(x...) printk(x)
#else
#define DBG(x...) do { } while (0)
#endif

#ifdef CONFIG_SND_DEBUG
#define DBG(args...) pr_info(args)
#else
#define DBG(args...)
#endif


dtb反编译

# fdtdump工具
sudo apt-get install device-tree-complier

# 反编译
fdtdump xxx.dtc >  xxx.dts

常用ADB命令整理

--- Android Debug Bridge(安卓调试桥)

  • 连接/重启/安装/应用管理

    adb devices
    
    # 多设备连接
    adb devices
    adb -s 192.168.xxx.xxx shell
    
    # adb wifi
    adb tcpip 5555 //让设备端的 adbd 重启,并在 TCP 端口 5555 处监听
    adb connect 192.168.xxx:5555 //远程连接设备,设备的 IP 地址是 192.168.xxx
    adb disconnect 192.168.xxx:5555 // 断开连接
    
    # adb重新挂载
    adb root
    adb remount
    
    # adb重启
    adb reboot				//普通重启 
    adb reboot recovery		//重启到Recovery界面 
    adb reboot fastboot		//重启到fastboot 
    adb reboot bootloader	//重启到bootloader 
    adb reboot ed 重启到紧急下载(高通only)
    
    # 安装apk
    adb install xxx.apk 路径
    adb install -r xxx.apk 路径 (强制安装)
    
    # 文件导出/上传
    adb push xxx.txt 本地路径 
    adb pull xxx.txt 本地路径
    
    # 截图导出
    adb shell screencap /xxx.jpg //截图
    adb pull xxx //导出
    
    # 录制视频
    adb shell screencord /xxx.mp4
    
    # 查看CPU架构
    adb shell getprop ro.product.cpu.abi
    
    # 屏幕常亮
    adb shell settings put system screen_off_timeout 600000
    
  • Android-调试/Debug

    --- adb logcat 安卓系统专用指令,打印内容只与应用程序相关,即只打印用户态log信息

    # 常用
    adb logcat > log.txt 
    adb logcat -b(特定类型)  kernel > k.txt 
    adb logcat -b all -d(一次性输出后退出) >log.txt  //这个好用,有一次性退出 
    adb shell logcat -b all > log.txt     //kernel log
    
    # 实时查看音量级别
    logcat  | grep storeVolume
    
    # 实时输出
    logcat -b all | grep input_report_key
    
    # 清空日志信息,适用于复现前清除无用log
    logcat -c
    
    radio:查看包含无线装置/电话相关信息的缓冲区 
    events:查看已经过解释的二进制系统事件缓冲区消息
    main:查看系统日志缓冲区(默认) 
    crash:查看崩溃日志缓冲区(默认) 
    all:查看所有缓冲区 
    default:报告main、system、crash缓冲区
    

getprop/setprop/watchprops

--- 在Android系统中,使用getprop命令可以从系统中读取一些设备信息,属性的文件

  • getprop

    # 从系统的配置中读取信息
    
    adb shell getprop > p.txt (导出所有属性)
    
    getprop ro.build.type(看版本 Userdebug版本/UserD版本/熔断版本)
    
    getprop | grep efuse 熔断判断
    
    getprop ro.build.fingerprint(特定事件)
    
    getprop persist.vendor.framebuffer.main(看分辨率)
    
  • setprop

    # setprop <prop-name> <value>
    //例如,修改进程默认分配的可以使用堆内存大小:
    adb shell setprop dalvik.vm.heapgrowthlimit 128m
    
  • 一些常用参数说明

    dalvik.vm.heapgrowthlimit:默认给进程分配的可使用堆内存
    dalvik.vm.heapsize:设置了android:largeHeap以后可使用的内存大小
    ro.product.brand:手机品牌
    ro.product.device:设备名称
    ro.product.model:设备内部代号
    ro.product.name:设备名称
    ro.product.manufacturer:设备制造商
    ro.serialno:设备序列号
    ro.sf.lcd_density:设备屏幕密度
    ro.config.ringtone:默认来电铃声
    ro.config.notification_sound:默认通知铃声
    ro.config.alarm_alert:默认闹钟铃声
    dalvik.vm.stack-trace-file:trace文件放置目录
    

User版本开启ADB

  • Android

    Z:\work\xxx\build\make\core\main.mk
    修改:ro.debuggable=1   ro.adb.secure=0
    
    diff --git a/core/main.mk b/core/main.mk
    index c5a0baeef..ab5b9e22a 100644
    --- a/core/main.mk
    +++ b/core/main.mk
    @@ -393,7 +393,7 @@ ifneq (,$(user_variant))
       ADDITIONAL_SYSTEM_PROPERTIES += security.perf_harden=1
     
       ifeq ($(user_variant),user)
    -    ADDITIONAL_SYSTEM_PROPERTIES += ro.adb.secure=1
    +    ADDITIONAL_SYSTEM_PROPERTIES += ro.adb.secure=0
       endif
     
       ifeq ($(user_variant),userdebug)
    @@ -423,7 +423,7 @@ ifeq (true,$(strip $(enable_target_debugging)))
       ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.lockprof.threshold=500
     else # !enable_target_debugging
       # Target is less debuggable and adbd is off by default
    -  ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=0
    +  ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=1
     endif # !enable_target_debugging
     
     ## eng ##
    

Git/Gerrit平台

--- Git比svn好用

--- Gerrit一款开源免费的代码评审平台,基于GIT的版本控制系统,目前国内大多数公式均采用Gerrit平台进行代码评审/review管控。 ==> 项目主要使用该平台进行Merge审核。

Gerrit添加账号和密钥

image-20231120145012193

  • Gerrit的版本有时候不支持常用的RSA加密方式 --- 如在使用WSL2时,github可以正常拉取代码,gerrit会显示不识别,此时换一种更先进的加密方式,如ed25519格式的密钥,可以使得gerrit正常

Gerrit添加仓库和分支

1:联系管理员添加分支

2:添加仓库到manifest

  • 拉manifest image-20231120145347570

3:修改相应分支仓库

  • manifest\rk_manifests\include\rk_modules_repository_maiyun.xml image-20231120145927797

4:提交merge后,需重新init该仓库所在项目,而后再提交相关代码


Gerrit拉取代码

--- Gerrit拉取代码和github差不多

  • 拉取代码

    image-20231120150539929

git clone "ssh链接"即可

  • repo init

    repo init --repo-url=ssh://替换成自己@10.110.1.100:29418/repo --no-repo-verify --repo-branch=reponew -u ssh://替换成自己@10.110.1.100:29418/manifest.git -m rk_3568_manifests/rk3568_linux_bu16.xml
    

    出现and try again是正常的;

  • repo sync 即可


Gerrit 基线-同步/编译/提交/撤销/回退

  • 同步代码

    repo sync -c --no-tags     -j32  
    //**--no-tags** don't fetch tags.该选项指定不获取服务器上的tag信息
    
  • 清除、重置(丢弃分支)、同步

    repo forall -c git clean -fd && repo forall -c git reset --hard && repo sync -c --no-tags
    
    # 解决repo问题
    .repo/repo/repo forall -c git clean -fd && .repo/repo/repo forall -c git reset --hard && .repo/repo/repo sync -c --no-tags
    
  • 编译

    //编译
    source build/envsetup.sh
    lunch 40
    ./build.sh -AUCKu
    
  • 提交

    //代码提交
    # 添加这两个文件
    git add 文件名1 文件名2
    
    # 添加所有文件
    git add . 
    
    # 添加已跟踪文件
    git add -u .
    
    # 添加已跟踪和未跟踪的文件
    git add -A .
    
    # 取消添加该文件
    git reset HEAD+文件名         
    
    //example
    # 添加所有changes文件
    git add .
    git commit -m "[Project][Module]Add for xxx by xxx"
    
    # 查看分支
    git branch -a
    * (HEAD detached from 984f637aa77e)
      remotes/m/master -> origin/a1
      remotes/origin/a1
      remotes/origin/master
    
    # 推送至a1分支上
    git push origin HEAD:refs/for/a1
    
  • 撤销

    git reset --hard HEAD (撤销最新的提交) 
    git reset --hard HEAD^ (撤销上一次提交) 
    git reset --hard HEAD^^ (撤销上上一次提交) 
    git reset --hard commit ID (commit ID指的是通过git log看到的commit后面的一长串ID的前7位)
    
  • 回退/恢复

    git log
    git checkout -f 487de35b82fd72b78058b7c5efa34e9a59e0bb87 
    
    git reset --hard "xxxxxxxx"
    

Gerrit-本地分支-查看/创建/切换/重命名/删除

  • 查看

    # 查看本地分支
    git branch
    
    # 查看远程分支
    git branch -r
    
    # 查看所有分支
    git branch -a
    
  • 创建

    # 仅创建
    git branch name(分支名)
    
    # 创建并直接切换至该分支
    git checkout -b name(分支名)
    
  • 切换

    git checkout name(分支名)
    
  • 重命名

    # 重命名本地分支
    git branch -m old_name new_name
    
  • 删除

    # 删除本地分支
    git branch -d name
    
    # 删除远程分支(小卡拉米用不到的)
    git push origin -delete :name 
    

Gerrit-本地远程仓库对比

  • 更新本地远程分支后与本地分支进行对比

    # 更新本地远程分支
    git fetch origin
    
    # 对比
    git diff 本地分支 origin/xxx //只能看到diff内容
    
    # 通过log查看区别
    git log
    git log origin/xxxx 
    

Git-切换分支同步修改

  • 将当前分支修改放入一个新的Git分支

    # 暂存
    git stash
        
    # 创建新的分支
    git checkout -b new-feature
        
    # 将暂存拉到新的分支
    git stash apply
    

Git-解除本地分支冲突

  • 保存修改文件和记录修改内容

  • 通过git stash 解决冲突

    # 暂存
    git stash
        
    # pull 更新
    git pull <remote> <branch>
    //这里可以检查下是否是最新的,可能要拉取下远程分支
    
    # 还原暂存
    git stash pop
    

Git stash的用法

  • git stash 暂存本地修改至缓存区

  • Git-stash pop 和 Git-stash apply的区别

    # 查看保存的信息和标记
    git stash list
    
    # 拉取方式
    git stash pop 	//拉取最新的暂存区同时删除对应的stash list
    git stash apply	//不删除对应的stash list
    
    # 删除多的list
    git stash drop	//删除最新的list
    git stash claer	//清除全部的stash
    
  • 指定stash list

    # git stash list
    
    # git stash xxxx stash@{x}
    

Git-patch 打包/应用

  • 打包

    # 打包最近的一个log
    git format-patch -1
    # 打包最近的两个log
    git format-patch -2
    # 同理打包最近的n个log
    git format-patch -n
    
    # 打包n1、n2版本间的patch
    git format-patch -n1 -n2
    
    # 打包从根到指定log的所有patch
    git format-patch --root 6a99bdd14b66de695519cca7a72d9b652e9bfdc7
    
    # 将patch输出到指定文件
    git format-patch xxx --stdout > xxx.patch ==> git format-patch -4 --stdout > 1.patch
    
  • 应用

    # 合并指定log
    git am xxx.patch
    

Git-Fork/上传

  • Fork

    git clone xxxx(ssh)
    
  • 上传自己本地仓库

    rm -r .git //删除原有git信息
    git init
    git add .
    git commit -m "xxxx"
    //提前在git官网新建repository
    git remote add origin 远程库地址(如:git push --set-upstream origin master)  
    git push --set-upstream origin master
    

gitignore

  • 忽视如out等文件 --- 在.git同目录下

    touch .gitignore //生成gitignore文件
    vim .gitignore   //改下需要忽略的文件
    
    .gitignore 文件本身可以忽略
    
  • 权限引起的git status未显示变化,但是vscode等ide显示changes --- 忽略权限即可

    项目修改:git config core.filemode false
    全局修改:git config --global core.filemode false
    

Git/Gerrit/Repo-error

  • error: failed to push some refs to

    # 本质是第一次提交缺失Readme文件,第一次初始提交问题,按照出错提示即可
    example:
    gitdir=$(git rev-parse --git-dir); scp -p -P 29418 xxxx@10.110.1.100:hooks/commit-msg ${gitdir}/hooks/
    git commit --amend --no-edit
    
  • invalid syntax 使用项目自带的repo即可:.repo/repo/repo syncu

    # 普通用户repo失效
    mkdir -p ~/.bin
    PATH="${HOME}/.bin:${PATH}"
    curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
    chmod a+rx ~/.bin/repo
    
  • python版本错误

    //2.0/3.0 pyhton版本的老问题了
    # 查看当前默认python版本
    python --version
    
    # 查看python3位置
    whereis python3
    
    # 删除原有python2软链接
    rm /usr/bin/python
    
    # 链接3.x版本的软链接
    ln -s /usr/bin/python3.x /usr/bin/python
    
    # 重新检查当前python版本
    
  • git status未显示改动,但是VSCODE显示changes --- 文件权限导致changes提升 = =》忽视文件权限即可

    项目修改:git config core.filemode false
    全局修改:git config --global core.filemode false
    

Linux

DTS - Device Tree Source

--- 纷繁芜杂,如星星点点;点清且明,如月映波光

概述

--- DTS是一种描述==硬件的数据结构==,起源于OF(OpenFirmware);将驱动代码和设备硬件信息相互隔离;设备树对硬件信息进行抽象,驱动代码则负责逻辑处理 == 》 大量减少了内核当中的冗余代码;

  • DTS:设备树的源文件,硬件的相应信息都在其中;
    • 每一款硬件一般一个主控,==一个主控SOC对应一个DTS文件==
  • DTSI:设备树头文件扩展名,相当于C语言的头文件;
    • 一个SOC会对应多个设备,这些设备对于不同的SOC来说都是相同的,因此将这些==相同的DTS配置==抽象为一个.dtsi文件,SOC使用设备时,在DTS文件中包含该DTSI即可;
    • DTSI一般用于描述SOC的内部外设信息,如CPU架构、主频、IIC、SPI、外设(Motor、Fan等);
    • ==相同节点的配置,dts中的配置会覆盖dtsi的配置,后编译的dtsi也会覆盖之前同节点的dtsi配置==,注意检查节点配置是否重复配置或默认配置先后顺序;
  • DTC:DTS的编译工具,相当于众所周知的GCC;在内核源码scripts/dtc路径下已包含DTC相关工具
  • DTB:DTS被DTC编译后的二进制格式设备树文件,才可被linux内核解析;
    • DTB通过Bootloader引导加载到内核当中;

DTS框架

  • Linux kernel设备树路径:

手动编译

 ./scripts/dtc/dtc -I dts -O dtb -o xxx.dtb arch/arm/boot/dts/xxx.dts // 编译 dts 为 dtb
 ./scripts/dtc/dtc -I dtb -O dts -o xxx.dts arch/arm/boot/dts/xxx.dtb // 反编译 dtb 为 dts


dts注意事项

1. 自行添加dts节点和代码的优势

--- 对于某些开发中常见的功能,可以改代码,使用dts的参数的方法;有利于后续调试仅修改dts参数,尽量解耦合;


2. 确定项目DTS所在的位置

--- 基于RK平台

方法一
  • ./build.sh lunch image-20231010134901614
  • 查看对应的deconfig image-20231010135041497
  • 查看细节 image-20231010135115312
  • 在对应的dts文件里面找包含的DTS和DTSI即可
法二
  • 进入output路径,打开.config image-20231102144014071

  • 即可看到相应的dts

    image-20231102144156362


交叉编译

Android NDK交叉编译

--- 适用于Android平台,参考AS005文档

项目源码环境

--- 适用于Android平台,参考AS005文档

源码编译后的输出目录下进行环境编译

--- 适用于 Linux;应该也适用于android(未验证)

  • Linux 一般会在buildroot/output/rockchip_rkxx/host下
    • buildroot/output/rockchip_rkxx/host/bin 看编译版本
    • 在buildroot/output/rockchip_rkxx/host/ 写源码 hello.c
    • ./host/bin/arm-buildroot-linux-gnueabihf-gcc hello.c -o hello
  • android 待后续验证补充

Android Sepolicy

简介

--- Android安全模型的一部分,一种权限管理策略,即使是进程具有root权限,SELinux也能通过创建⾃动化的安全策略(sepolicy)来限制特权进程来增强 Android的安全性 ;主要就是限制Android的权限,避免滥用造成的安全风险问题。


查看selinux的详情

  • ps -z --- 显示selinux的角色、类型、安全级别;格式:user:role:type:rank

    ps -Z
    
    LABEL USER PID PPID NAME
    u:r:init:s0 root 1 0 /init
    u:r:kernel:s0 root 2 0 kthreadd
    ...
    
    • user;SEAndroid中定义了⼀个SELinux⽤户,值为u;
    • role;role是⾓⾊之意,它是SELinux中⼀种⽐较⾼层次,⼀个u可以属于多个role,不 同的role具有不同的权限;
    • init;代表该进程所属的Domain为init,是这个进程type,在andorid⾥⾯,定义了100多
    • type;进程所属的类型;
    • S0;是⼀个安全的等级MLS将系统的进程和⽂件进⾏了分级,不同级别的资源需要对应级别的进程 才能访问;

selinux 关键文件

  • 政策文件

    --- 文件格式:以*.te 文件结尾

    --- 路径:/device/manufacturer/device-name/sepolicy

    ==> 一般尽可能的更新现有文件, 也可创建新的政策文件

  • 上下文描述文件

    • file_contexts:文件分配标签
    • genfs_contexts:为不支持扩展属性的文件系统(proc、vfat)分配标签
    • property_contexts:为Android系统属性分配标签,便于控制哪些进程可以设置这些属性
    • service_contexts:Android Binder 服务分配标签,以便控制哪些进程可以为相应服务添加 (注册)和查找(查询)Binder 引⽤
    • seapp_contexts:为应⽤进程和 /data/data ⽬录分配标签
    • mac_permissions.xml:根据应⽤签名和应⽤软件包名称(后者可选)为应⽤分配 seinfo 标 记
  • BoardConfig.mk makefile

    修改或添加政策⽂件和上下⽂的描述⽂件后,请更新您的 /device/rockchip/devicename/BoardConfig.mk
    BOARD_SEPOLICY_DIRS += \
    		<root>/device/rockchip/device-name/sepolicy
    (8.0+版本不需要修改以下⽂件)
    BOARD_SEPOLICY_UNION += \
                genfs_contexts \
                file_contexts \
                sepolicy.te。
    

selinux 问题确认

  1. user版本相关功能不正常,userdebug版本功能正常,可能为selinux权限问题;
  2. kernel log、logcat中出现avc:denied字样log,需进一步复现确认是否为selinux权限问题;
  • selinux 权限开启/关闭

    adb shell setenforce 0
    setenforce 0 设置SELinux 成为permissive模式 临时关闭selinux
    setenforce 1 临时打开selinux
    
  • selinux 相关log抓取

    adb shell logcat | grep avc
    或 ad
    b shell dmesg | grep avc
    

sepolicy rule 读法/添加/验证

  • selinux log读法/添加 --- 一般缺少search、write、read权限都如下:

    01-01 00:07:51.030  4006  4006 W android.hardwar: type=1400 audit(0.0:763): avc: denied { search } for name="leds" dev="sysfs" ino=20167 scontext=u:r:hal_vibrator_default:s0 tcontext=u:object_r:sysfs_leds:s0 tclass=dir permissive=0
    
    1. 缺少 search 权限
    2. hal_vibrator_default 缺少权限
    3. sysfs_leds 这个节点缺少权限
    4. dir 类型文件
    如上;需添加:allow hal_vibrator_default sysfs_leds:dir search
    

    ----:

    • 权限问题一般不能一次性解决,可能会在一次权限问题解决后再提示下一个权限问题,需一次次给予新的权限;

    • 当需要加入很多权限时,推荐采用宏的方式添加

      allow hal_vibrator_default sysfs_leds:dir {search write add_name create };

  • selinux 添加

    • 法一

      如上:allow hal_vibrator_default sysfs_leds:dir search
      

      ==>:

      将对应的policy添加到te文件中;⼀般添加在 /device//common/sepolicy 或者 /device//$DEVICE/sepolicy ⽬录下,具体哪个⽬录,请执⾏get_build_var 查看

    • 法二 --- 使用audit2allow ⼯具⽣成对应的 policy 规则;暂未使用过

  • 修改生效:重新编译烧录抓log检查


案例:Motor驱动

1:userdebug:会上报avc问题,但permission=1仅上报不阻止

​ user:上报avc问题,permission=0,阻止;需给相关avc权限

image-20230214160311249

  • avc问题读法
01-01 00:07:51.030  4006  4006 W android.hardwar: type=1400 audit(0.0:763): avc: denied { search } for name="leds" dev="sysfs" ino=20167 scontext=u:r:hal_vibrator_default:s0 tcontext=u:object_r:sysfs_leds:s0 tclass=dir permissive=0
如上:需添加allow hal_vibrator_default sysfs_leds:dir search

2:解决方案

MaiYun\device\rockchip\common\sepolicy\vendor目录下无hal_vibrator_default.te相关文件

但MaiYun\device\rockchip\common\sepolicy\vendor\file_contexts下有vibrator_aidl描述;

image-20230214160644936

  • 直接添加hal_vibrator_hal.te文件并添加所需allow

image-20230214160808164

经修改后解决user版本无vibrator相关avc错误;userdebug仍有部分vibrator相关avc错误,如需解决,增加相关权限即可。 如还有selinux相关问题则参考:RK-Android Sepolicy配置指导。

==> 补充: AIDL、HIDL都是用于跨进程通信;将上层与底层分隔开

AIDL:Android Interface Definition Language(Android接口定义语言)

HIDL:Hardware Abstract Layer --- HIDL 则是改变之前上层直接调用 HAL 层的模式,而是将 HAL 层作为一个服务启动,当上层需要调用时是作为 client 来请求服务的

u-boot

参考自:[U-Boot 之八 详解 Driver Model 架构、配置、命令、初始化流程_u_boot_driver_ZC·Shou的博客-CSDN博客](https://blog.csdn.net/ZCShouCSDN/article/details/128600865#:~:text=U-Boot 的 DM 使用 uclass 和,udevice 这两个抽象的类来管理所有的设备驱动,这两个抽象类分别各自对应 uclass_driver 和 driver 。)

  • u-boot 的设备树和kernel共用一套;目前均采用设备树的方式配置

  • u-boot的config不共用,一般在:u-boot\configs\xxxx_defconfig下

  • 目前u-boot引用自己的Driver Mode(官方简称 DM)驱动架构

    ---需开启CONFIG_DM_GPIO=y 宏和相关器件的宏

  • u-boot 最主要的两个宏:

    UCLASS_DRIVER(__name) ==> uclass
    U_BOOT_DRIVER(__name) ==> udevice
    
    --- 初始化中,u-boot会遍历这些节区,然后进行内容匹配,依次创建各种设备和对应的UCLASS
    

    image-20231123164232439

    ==》 只有driver存在时,才会创建uclass

    uclass是根据uclass_driver动态创建的。

u-boot参数--cmdline

--- cmdline 由多个数据拼接而成,将重复数据过滤后再传给kernel; --- cmdline 是uboot引导内核启动时传给内核的,作用是指导内核启动;内核启动阶段会去解析cmdline,按照cmdline去指导内核启动

DMA Direct Memory Access

--- DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输

详见搞嵌入式,不懂DMA?笑死人。。。 (qq.com)

简单来讲:

主要是选择普通模式还是循环模式

111s

ss