RK3568开发板Android 11系统移植实战:从内核驱动到HAL适配

news2026/5/16 10:17:40
1. 项目概述与学习路径规划拿到一块像迅为iTOP-RK3568这样的开发板想把最新的Android 11系统跑起来这个想法听起来挺酷但很多朋友一看到“系统移植”四个字就有点发怵感觉这是大神才能玩转的领域。其实只要你熟悉Linux这件事的难度就降了一大半。Android的底层就是Linux内核我们常说的“移植”核心工作就是让这个Linux内核完美适配你的硬件。剩下的比如Android的框架层、应用层谷歌和芯片原厂比如瑞芯微已经为我们搭好了绝大部分的舞台。所以我们的任务更像是“定制”而非“从零创造”核心是打通硬件与系统之间的桥梁。这篇文章我就以手头的迅为iTOP-RK3568开发板为例带你走一遍Android 11系统移植的完整流程。我不会只给你一堆命令和配置文件那样你只能照猫画虎。我会重点拆解每个步骤背后的“为什么”比如为什么要配置这个电源域设备树里某个节点修改了到底影响了什么从分析原理图开始到编写或修改底层驱动再到配置Android的硬件抽象层HAL最后写个简单的APP验证功能。整个过程会涉及硬件原理分析、设备树DTS配置、内核驱动、Android框架修改甚至一点点JNI编程。我的目标是你跟着走完一遍后不仅能在这块板子上跑通Android 11更能建立起一套应对其他平台或芯片的系统级调试与适配的思维方法。2. Android 11系统架构与RK3568平台解析在动手之前我们必须对要操作的对象有一个清晰的认知。这包括两个层面一是Android系统本身的分层结构二是RK3568这块芯片及其开发板的硬件特性。理解前者你才知道动哪里是改内核动哪里是改框架理解后者你才知道具体要改什么。2.1 Android 11系统分层架构精讲很多人对Android的理解停留在应用层但做移植我们必须深入其骨骼。Android是一个庞大的软件栈从上到下可以清晰地分为五层应用程序层Applications这就是我们日常接触的各种APP包括系统自带的拨号、短信以及我们从应用商店下载的所有软件。在移植阶段我们基本不关心这一层除非要预装或定制系统应用。应用程序框架层Application Framework这是Android系统的“大脑”和“调度中心”。它提供了大量API供应用开发者调用比如管理活动Activity的生命周期、处理触摸事件、访问传感器数据等。我们熟知的ActivityManager、WindowManager、ContentProvider等都位于这一层。在做系统定制时我们可能会修改这里的某些服务或资源。系统运行库与Android运行时Libraries Android Runtime系统运行库主要是C/C库例如SurfaceFlinger负责图形显示合成、OpenGL ES3D图形库、SQLite数据库引擎等。这些是支撑框架层运行的基础。Android运行时ART从Android 5.0开始ART取代了Dalvik虚拟机。它的作用是在应用安装时将应用的字节码预编译成本地机器码从而大幅提升应用执行效率。对于移植工作我们需要确保芯片架构如RK3568的ARM v8-A被ART完美支持。硬件抽象层HAL这是连接Android框架与Linux内核驱动的关键桥梁也是我们移植工作的核心战场之一。框架层想要读取传感器数据不会直接去调用内核的驱动接口而是通过一个统一的HAL接口。HAL层之下才是具体的、与硬件强相关的驱动。这种设计使得Android框架与底层硬件解耦更换不同型号的摄像头模组可能只需要提供新的HAL实现和驱动而上层的相机APP无需修改。RK3568的BSP板级支持包里会提供大量芯片专属的HAL实现。Linux内核层Linux Kernel这是系统的基石负责最底层的硬件管理如CPU调度、内存管理、进程间通信IPC、设备驱动如显示、触摸、USB、Wi-Fi/蓝牙芯片驱动等。我们移植的绝大部分工作都集中在这一层。目标就是打造一个能为RK3568这块板子上的所有硬件提供完美驱动的定制内核。注意不要把“移植”想象成重写整个Android。我们的工作主要聚焦在最底部的两层HAL和Kernel确保它们能正确识别和控制RK3568开发板上的硬件。上面的三层谷歌和瑞芯微已经做了绝大部分工作我们更多的是进行配置和微调。2.2 RK3568硬件平台与迅为开发板特性RK3568是瑞芯微推出的一款面向AIoT和工业应用的中高端ARM处理器。它的几个关键特性决定了我们移植时的关注点CPU与GPU四核Cortex-A55搭配Mali-G52 GPU。这意味着内核需要正确的CPU调度策略和GPU驱动支持。多媒体强大的VPU视频处理单元和ISP图像信号处理器。移植时必须确保相关的编解码驱动和相机HAL正常工作。外设接口丰富的接口如PCIe 3.0、SATA 3.0、双千兆以太网、多个USB、多个SDIO等。我们需要在设备树中正确启用和配置这些接口对应的控制器和引脚复用。电源管理集成复杂的电源管理单元PMU搭配外部电源管理芯片如RK809。这是系统稳定运行的保障配置错误可能导致无法开机或功耗异常。迅为的iTOP-RK3568开发板基于这颗芯片设计了具体的电路包括内存DDR、存储eMMC、电源电路、各种接口的物理连接如通过电平转换芯片连接串口、USB Hub芯片扩展USB口等。我们的移植工作就是让Android内核和系统“认识”并“驱动”这块板上所有的硬件电路。源码从哪里来最权威的来源当然是谷歌的AOSPAndroid Open Source Project。但对于特定芯片直接使用芯片原厂提供的“BSP”Board Support Package或“SDK”是最高效的方式。瑞芯微会提供一个基于特定Android版本如Android 11的、为RK3568优化过的内核源码和Android框架源码仓库。迅为这样的开发板厂商通常会在瑞芯微SDK的基础上再加入自己板级的设备树和驱动修改。因此获取迅为提供的专属SDK是开始我们工作的第一步。3. 开发环境搭建与源码获取工欲善其事必先利其器。一个稳定、高效的编译环境是后续所有工作的基础。Android源码编译对主机环境有比较严格的要求我们需要一步步搭建好。3.1 编译主机环境配置详解我强烈建议使用Ubuntu 20.04 LTS 64位系统作为编译主机这是经过广泛验证最稳定的选择。在虚拟机或物理机上安装均可但务必保证有至少200GB的可用磁盘空间源码下载和编译中间文件会占用巨大空间以及16GB以上的物理内存内存不足会导致编译极其缓慢甚至失败。首先安装必要的依赖包。这些工具链和库是解压、编译、构建Android镜像所必需的。sudo apt-get update sudo apt-get install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig python3 openjdk-11-jdk这里特别要注意Java版本。Android 11要求使用OpenJDK 11使用其他版本如8或17可能会导致编译错误。接下来配置repo工具。repo是谷歌为了管理庞大的Android源码而开发的Python脚本它底层调用git但可以同步数百个独立的git仓库。mkdir ~/bin curl https://storage.googleapis.com/git-repo-downloads/repo ~/bin/repo chmod ax ~/bin/repo将~/bin路径加入系统的环境变量这样在任何目录下都可以直接执行repo命令。echo ‘export PATH“$HOME/bin:$PATH”’ ~/.bashrc source ~/.bashrc3.2 获取Android 11源码与RK3568 BSP现在我们需要获取两份关键的代码一是纯净的Android 11AOSP基础代码二是瑞芯微针对RK3568的硬件相关代码通常以“kernel”、“device”、“vendor”等仓库形式提供。最规范的做法是先初始化AOSP仓库再通过repo的本地清单local_manifests机制将瑞芯微的仓库“注入”到同步流程中。首先创建一个工作目录并初始化AOSP的repo。这里我们同步android-11.0.0_r48这个特定的标签版本以保证稳定性。mkdir ~/aosp_rk3568 cd ~/aosp_rk3568 repo init -u https://android.googlesource.com/platform/manifest -b android-11.0.0_r48初始化完成后目录下会生成一个.repo文件夹。我们需要在.repo/manifests/目录下创建local_manifests目录并在其中创建一个XML文件例如rk3568.xml用来描述需要额外同步的瑞芯微仓库。这个XML文件的具体内容需要从瑞芯微官方或迅为提供的SDK文档中获取。一个简化示例如下?xml version“1.0” encoding“UTF-8”? manifest remote name“rockchip” fetch“https://github.com/rockchip-linux” / project path“kernel” name“kernel” remote“rockchip” revision“rk356x/android-11” / project path“device/rockchip/rk3568” name“device/rockchip/rk3568” remote“rockchip” revision“rk356x/android-11” / project path“vendor/rockchip” name“vendor/rockchip” remote“rockchip” revision“rk356x/android-11” / /manifest这个文件告诉repo除了AOSP的主线代码还要从rockchip这个远程地址拉取kernel、device/rockchip/rk3568等几个仓库并切换到rk356x/android-11这个分支。最后执行同步命令开始下载所有源码。这是一个非常耗时的过程取决于你的网络速度可能需要数小时。repo sync -c -j$(nproc) --no-tags --no-clone-bundle参数解释-c表示只同步当前分支-j$(nproc)表示使用与CPU核心数相同的线程数来加速--no-tags和--no-clone-bundle是为了节省时间和空间。实操心得同步过程很可能因为网络问题中断。如果中断直接重新执行repo sync命令即可它会自动断点续传。建议在夜间或网络稳定的时段进行。同步完成后整个aosp_rk3568目录的大小会在100GB左右。4. 深入源码目录从结构理解移植切入点源码同步完成后面对浩如烟海的目录新手很容易迷失。我们不需要精通每一个目录但必须知道关键模块的位置这样当需要修改某个功能时才能快速定位。4.1 核心目录功能解析进入~/aosp_rk3568目录我们来看几个最关键的kernel/这就是Linux内核源码。所有与硬件直接相关的驱动、设备树DTS文件都在这里。例如RK3568的串口驱动在kernel/drivers/tty/serial/里而针对迅为开发板的设备树源文件.dts或.dtsi很可能在kernel/arch/arm64/boot/dts/rockchip/目录下名字可能包含itop或rk3568-itop。这是我们未来修改最频繁的目录之一。device/rockchip/rk3568/这是RK3568平台的设备配置目录。它定义了针对这块芯片的编译配置、分区表、系统属性等。例如device.mk文件决定了哪些系统模块会被编译进镜像BoardConfig.mk定义了内核编译配置、引导程序bootloader类型等。vendor/rockchip/这是厂商定制目录。里面存放了瑞芯微提供的闭源或开源库、硬件抽象层HAL实现、预编译的固件如GPU、VPU的固件等。例如vendor/rockchip/common/下可能有通用的HAL实现而vendor/rockchip/rk3568/下则是RK3568特有的。hardware/这是Android标准的硬件抽象层HAL接口定义和开源实现目录。一些标准的HAL如hardware/libhardware在这里。瑞芯微的HAL实现可能会放在vendor下也可能部分放在这里。frameworks/Android框架层的核心代码。除非你要深度定制系统服务如修改电源管理策略、添加新的系统API否则很少直接改动这里。packages/系统自带的应用如设置、相机、通讯录等。如果你想定制系统应用的外观或功能可以在这里找到对应代码。system/包含Android系统的一些核心守护进程和工具如init第一个用户空间进程、adb、logcat等。bootable/包含引导相关的代码如recovery恢复模式的代码。build/Android庞大的构建系统Soong/Bazel的核心代码。我们通常不直接修改它但会通过它定义的变量和规则在mk文件中来控制编译过程。4.2 编译系统初探如何开始编译理解了目录结构我们来看看如何启动第一次编译。编译的入口通常是源码根目录下的一个脚本或source一个环境设置文件。对于瑞芯微的平台常见的做法是source build/envsetup.sh lunch执行lunch后会弹出一个菜单让你选择编译目标。这个目标由“产品名”和“构建类型”组成例如rk3568_itop-userdebug。rk3568_itop是产品名对应device/rockchip/rk3568下的某个产品配置userdebug是构建类型介于user正式版和eng工程版之间带调试功能。选择好目标后就可以开始编译了。最彻底的编译命令是make -j$(nproc)-j$(nproc)表示使用所有CPU核心并行编译以最大化利用硬件资源。这个过程同样非常漫长首次编译在性能强大的机器上也可能需要数小时。编译成功后生成的系统镜像文件如boot.img,system.img,vendor.img,super.img等会输出在out/target/product/rk3568_itop/目录下。这些镜像文件就是我们最终要烧写到开发板上的东西。注意事项编译过程可能因环境问题如依赖缺失、权限问题、Java版本不对而失败。控制台会输出详细的错误信息。解决问题的关键是仔细阅读错误日志通常错误信息会直接指出缺少哪个库或文件或者哪行代码有语法错误。搜索引擎是解决编译错误的最佳伙伴大部分常见错误都有解决方案。5. 内核与设备树移植让系统认识你的硬件这是移植工作中最硬核、也最体现工程师功力的部分。Linux内核通过“设备树”Device Tree这种数据结构来描述硬件配置它取代了旧时代内核中大量的硬编码硬件信息。对于RK3568我们需要确保内核包含了所有必要的驱动并且设备树文件准确地描述了迅为这块开发板上的硬件连接。5.1 内核配置与驱动裁剪RK3568的BSP内核通常已经配置好了绝大多数驱动。我们的任务是根据迅为开发板的实际硬件进行微调。进入kernel目录使用菜单界面进行配置cd ~/aosp_rk3568/kernel make ARCHarm64 rockchip_defconfig # 加载瑞芯微的基础配置 make ARCHarm64 menuconfigmenuconfig会打开一个图形化界面。在这里你可以启用缺少的驱动例如如果你的板子用了某个特殊的以太网PHY芯片就需要在Device Drivers - Network device support - Ethernet driver support下找到并启用对应的驱动。禁用无用驱动为了减小内核体积和启动时间可以关闭板上没有的硬件驱动。例如如果板子没有PCIE接口可以安全地禁用相关驱动。配置内核参数比如设置默认的控制台串口、内存大小等。配置完成后保存退出。生成的配置会保存在.config文件中。5.2 设备树DTS深度解析与修改设备树才是描述“这块具体板子”的关键。它位于kernel/arch/arm64/boot/dts/rockchip/。瑞芯微通常会提供一个芯片级的通用文件如rk3568.dtsi里面定义了CPU、内存控制器、各种内置外设如UART、I2C、SPI控制器的通用信息。然后会有一个或多个板级文件如rk3568-itop.dts或rk3568-itop.dtsi它们#include芯片级文件并在此基础上进行覆盖和扩展描述具体的硬件连接。一个关键的实操案例配置调试串口UART2假设迅为开发板将RK3568的UART2控制器通过电平转换芯片连接到了板载的USB转串口芯片上作为系统调试串口。我们需要在设备树中启用并正确配置它。找到对应节点在板级设备树文件如rk3568-itop.dts中找到uart2这个节点引用。它可能已经被定义但状态是disabled。修改节点属性uart2 { status “okay”; // 将状态改为“okay”以启用该控制器 pinctrl-names “default”; pinctrl-0 uart2m0_xfer; // 指定引脚复用组这需要对照RK3568的PinCtrl手册和迅为的原理图 };status “okay”这是启用一个设备节点的标准写法。pinctrl-0 uart2m0_xfer这是最关键的一步。它告诉内核UART2的TXD和RXD信号线具体复用到哪两个物理引脚上。uart2m0_xfer是一个在芯片级DTSI文件中定义好的“引脚控制状态”。你必须根据迅为原理图上UART2连接的实际芯片引脚选择正确的pinctrl配置可能是m0,m1,m2等不同功能复用组。选错了串口就无法收发数据。配置串口为控制台为了让内核启动信息从这个串口输出我们还需要在chosen节点中指定它。/ { chosen { stdout-path “serial2:115200n8”; // 指定标准输出路径为串口2波特率115200 }; };另一个案例配置I2C总线上的RK809电源管理芯片RK809是RK3568常用的配套电源管理芯片通过I2C总线与主控通信。我们需要在设备树中声明这个I2C设备。找到I2C控制器节点假设RK809接在I2C1总线上。找到i2c1节点。添加子节点在i2c1节点内添加RK809的设备节点。i2c1 { status “okay”; rk809: pmic20 { compatible “rockchip,rk809”; // 用于匹配内核中的驱动 reg 0x20; // I2C设备地址根据原理图确定 interrupt-parent gpio0; // 中断引脚所在的GPIO组 interrupts RK_PA3 IRQ_TYPE_LEVEL_LOW; // 具体的中断引脚和触发方式 // ... 其他配置如时钟、稳压器输出等 }; };compatible属性是设备树的“灵魂”内核驱动程序通过这个字符串来识别并绑定这个设备。“rockchip,rk809”必须与驱动代码中定义的完全一致。reg是I2C从设备地址必须与硬件原理图上的地址一致。interrupts属性定义了中断引脚这同样需要查阅原理图。避坑指南设备树修改中最常见的错误就是引脚复用冲突。一个物理引脚在同一时刻只能有一种功能。如果你在设备树中既将某个引脚配置为UART的TXD又在其他地方可能是另一个节点或者被默认状态配置成了GPIO或其他功能内核启动时就会报错。务必仔细核对原理图并利用kernel/Documentation/devicetree/bindings/下的文档和瑞芯微提供的引脚复用表格。6. 硬件抽象层HAL与系统服务配置当内核正确驱动硬件后Android上层还需要通过HAL来访问硬件。此外一些系统级的配置也需要调整以适配我们的开发板。6.1 硬件抽象层HAL适配原理HAL定义了一套标准的接口。以背光调节为例Android的DisplayService不会直接去写/sys/class/backlight下的文件而是调用hardware/libhardware/include/hardware/lights.h中定义的lights_module_t接口。这个接口的实现则由厂商如瑞芯微提供。在vendor/rockchip/或hardware/rockchip/目录下你会找到backlight、sensor、camera、audio等HAL的实现。通常这些实现已经为RK3568芯片做好了我们需要检查的是板级配置。例如背光HAL可能需要知道控制背光的PWM通道编号这个信息通常通过系统属性ro.vendor.backlight.pwm来传递而这个属性是在device/rockchip/rk3568/下的某个prop文件或init.rc脚本中设置的。我们的工作往往是确认HAL实现存在 - 确认对应的系统属性被正确设置 - 测试功能是否正常。6.2 系统属性与Init脚本配置Android的init进程在启动时会解析init.rc脚本以及/vendor/etc/init/等目录下的脚本。这些脚本负责在特定的启动阶段如on boot、on post-fs-data创建目录、设置权限、启动守护进程、设置系统属性等。例如为了在Android系统中访问我们前面配置的普通串口比如/dev/ttyS3我们需要修改权限。可以在device/rockchip/rk3568/目录下找到一个名为ueventd.rc或类似的文件在其中添加一行/dev/ttyS3 0666 system system这表示在设备节点创建时将其权限设置为0666所有用户可读可写所属用户和组为system。这样普通的Android应用如果有权限才能打开这个串口设备。另一个重要的配置是sepolicy安全策略。在Android中访问硬件资源受到SELinux的严格限制。即使设备节点权限是0666如果SELinux策略不允许应用也无法访问。你可能会在logcat日志中看到“Permission denied”或“avc: denied”的SELinux报错。这时就需要在device/rockchip/rk3568/sepolicy/目录下为你的设备添加或修改对应的策略规则文件。这是一个比较深入的话题初期可以通过将SELinux模式设置为permissive在BoardConfig.mk中添加BOARD_KERNEL_CMDLINE androidboot.selinuxpermissive来暂时绕过但产品化时必须妥善处理。7. 编译、烧写与基础调试当所有代码修改完成后我们进入最终的构建和验证阶段。7.1 完整系统镜像编译回到AOSP根目录确保环境已配置并lunch了正确的目标然后执行make -j$(nproc)如果只修改了内核或设备树可以使用增量编译命令来节省时间make bootimage -j$(nproc) # 仅编译boot.img包含内核和设备树 # 或者 make vendorimage -j$(nproc) # 仅编译vendor.img编译成功后在out/target/product/rk3568_itop/目录下我们会得到一系列镜像文件boot.img包含内核Image.gz和设备树二进制 blobdtb。vendor.img包含厂商的HAL库、固件等。system.img包含Android系统框架和核心应用。super.img在Android动态分区系统中可能将system、vendor等分区合并为一个super分区。rockdev/目录下可能还有用于瑞芯微专用烧写工具如upgrade_tool的打包文件。7.2 镜像烧写与启动验证RK3568开发板通常支持多种烧写方式MaskROM模式烧写最彻底的方式。短接开发板上的“MaskROM”引脚或按住特定按键再上电电脑通过USB识别到设备进入“Loader”模式。使用瑞芯微的AndroidToolWindows或upgrade_toolLinux工具加载统一的固件包如update.img或分别加载各个镜像进行烧写。这种方式会擦除整个存储设备。Fastboot模式烧写如果系统已经能启动到bootloader通常显示Fastboot界面可以通过fastboot命令线刷。这种方式更灵活可以单独更新某个分区。fastboot flash boot boot.img fastboot flash vendor vendor.img fastboot flash super super.img fastboot reboot烧写完成后重启开发板。此时你应该通过调试串口我们之前配置的UART2连接电脑使用串口终端工具如minicom,picocom或Windows下的MobaXterm、SecureCRT查看内核启动日志。波特率设置为115200。成功的标志在串口终端中看到内核解压、设备树解析、驱动初始化特别是显示驱动dw_hdmi或panel相关驱动的日志最后看到Android的init进程启动并最终进入系统。如果屏幕有显示你应该能看到Android的启动动画Bootanimation和桌面。8. 典型问题排查与实战技巧第一次启动很少能一帆风顺。下面是一些常见问题及其排查思路这些都是我在实际调试中积累下来的经验。8.1 内核启动阶段问题问题串口无任何输出。排查硬件连接确认串口线连接正确TX接RXRX接TXGND接GNDUSB转串口模块驱动已安装终端软件端口和波特率115200, 8N1设置正确。设备树配置检查调试串口如UART2的status是否为“okay”pinctrl配置的引脚复用组是否正确。这是最常见的原因。内核配置确认内核menuconfig中对应串口驱动CONFIG_SERIAL_8250等已启用。时钟配置检查设备树中该串口对应的时钟clocks属性是否被正确引用和启用。问题内核启动卡在“Starting kernel ...”或某条驱动初始化信息处。排查设备树语法错误使用dtc工具编译设备树源文件检查是否有语法错误dtc -I dts -O dtb -o test.dtb your_board.dts。内存配置错误检查设备树中memory节点的地址和大小是否正确必须与开发板板载的DDR芯片规格严格一致。驱动崩溃观察卡住前最后一条打印信息定位到对应的驱动。可能是该驱动依赖的硬件如电源、时钟、复位信号未正确配置或者驱动代码有BUG。尝试在menuconfig中暂时禁用该驱动看是否能继续启动。8.2 Android系统启动阶段问题问题内核启动成功但卡在Android启动动画Bootanimation无法进入桌面。排查查看后续日志Android启动后串口输出可能会停止或切换到其他日志级别。尝试在uboot或内核命令行中添加androidboot.serialconsole1或earlycon参数确保所有日志都从串口输出。分析logcat通过adb logcat命令获取Android层面的日志。如果系统还没完全启动adb可能无法连接。此时可以尝试在init.rc中设置ro.debuggable1和ro.secure0并确保adbd服务在早期启动。更直接的方法是修改内核配置将printk的日志级别调到最低CONFIG_CONSOLE_LOGLEVEL_DEFAULT8让所有内核和init日志都从串口吐出。常见原因关键服务崩溃如surfaceflinger显示服务、zygote应用孵化器崩溃。查看logcat中是否有它们的崩溃栈信息。SELinux策略问题日志中大量出现“avc: denied”。将SELinux设置为permissive模式临时验证。存储挂载失败检查/data、/vendor等分区是否成功挂载。查看内核日志中关于ext4或f2fs的错误信息。问题触摸屏、Wi-Fi、音频等特定硬件功能失效。排查确认驱动加载在串口日志或通过adb shell执行ls -l /dev/input/event*触摸屏、dmesg | grep wifi、lsmod等命令查看对应设备的驱动模块是否成功加载设备节点是否创建。检查HAL服务通过adb shell执行getprop | grep hal或ps -A | grep .hal查看对应的HAL服务进程是否在运行。检查系统属性很多HAL会读取特定的系统属性来获取配置。检查这些属性是否被正确设置getprop property_name。逐层调试从底层到上层。先确保/sys或/dev下的底层接口能正常工作如直接读写文件测试再测试HAL层的hwtest如果有最后通过Android标准API如写一个测试APP来验证。8.3 调试工具与技巧速查表工具/命令作用使用场景示例串口终端查看内核及早期init日志系统无法启动时定位内核崩溃、驱动初始化失败。adb logcat查看Android系统及应用日志分析应用崩溃、系统服务异常、权限问题。可使用-b参数查看不同缓冲区main,system,crash。adb shell dmesg查看内核环状缓冲区日志获取内核启动后的驱动消息、错误信息。adb shell getprop查看所有系统属性确认HAL或服务依赖的配置属性是否正确设置。adb shell ls -l /dev/查看设备节点确认驱动是否成功创建了设备节点如/dev/ttyS3,/dev/input/event0。adb shell ps -A查看所有进程确认关键系统服务如surfaceflinger,audioserver是否在运行。adb shell top实时查看进程资源占用排查系统卡顿、发热问题定位高CPU/内存占用进程。adb shell dumpsys转储系统服务信息深入分析特定服务状态如dumpsys power查看电源管理dumpsys display查看显示信息。瑞芯微开发工具upgrade_tool(Linux) /AndroidTool(Win)烧写固件、进入MaskROM模式救砖。一个实用的调试习惯在修改了任何代码后不要急于编译整个系统。先评估影响范围。如果只改了设备树就只编译boot.img如果只改了某个HAL库就只编译对应的模块mmm vendor/rockchip/...并推送到设备。这能极大节省调试时间。另外善用版本控制如git每次做一个清晰的提交这样当修改引入问题时可以快速回退。移植工作就像解一个多维度的拼图需要你在硬件原理、内核驱动、系统框架之间不断切换视角。遇到问题是常态而解决问题的过程正是能力提升最快的时候。从串口点亮第一行日志到屏幕亮起Android logo再到所有外设正常工作每一步的成功都会带来巨大的成就感。希望这份基于RK3568和Android 11的移植指南能为你点亮这条路上的一盏灯。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2617896.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…