BSP 定制开发
BSP 概述
BSP(Board Support Package,板级支持包)是针对特定硬件平台的底层软件包,包含引导程序、内核驱动、设备树等。
BSP 组成
移远 Android BSP 组成:
├── Bootloader(引导程序)
│ ├── XBL(eXtensible Bootloader):高通一级引导
│ └── ABL(Android Bootloader):Android 引导
├── Linux Kernel(内核)
│ ├── 设备树(Device Tree)
│ └── 驱动程序
├── Android 系统
│ ├── AOSP(Android Open Source Project)
│ └── 移远定制层(HAL、系统 App)
└── 文件系统
├── system.img
├── vendor.img
└── userdata.img开发环境搭建
编译环境要求
bash
# Ubuntu 20.04 LTS(推荐)
# 安装依赖
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 python3-pip
# 安装 repo 工具
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH获取 BSP 源码
bash
# 从移远开发者中心下载 BSP 包
# 或通过 repo 同步(需要移远账号)
# 解压 BSP 包
tar -xzf SC200E_Android11_BSP_v1.0.tar.gz
cd SC200E_Android11_BSP
# 初始化编译环境
source build/envsetup.sh
lunch sc200e-userdebug # 选择编译目标编译
bash
# 完整编译(首次,耗时 2-4 小时)
make -j$(nproc)
# 编译特定模块
make kernel -j$(nproc) # 只编译内核
make bootimage -j$(nproc) # 编译 boot.img
make systemimage -j$(nproc) # 编译 system.img
# 编译输出目录
ls out/target/product/sc200e/
# boot.img, system.img, vendor.img, userdata.img设备树定制
设备树(Device Tree)描述硬件配置,是 BSP 定制的核心。
设备树文件位置
kernel/arch/arm64/boot/dts/
└── qcom/
├── sc200e.dts # 主设备树
├── sc200e-pinctrl.dtsi # 引脚配置
└── sc200e-regulator.dtsi # 电源配置添加 I2C 设备
c
// 在设备树中添加 I2C 传感器(如温湿度传感器 SHT30)
&i2c_2 {
status = "okay";
clock-frequency = <400000>; // 400kHz Fast Mode
sht30@44 {
compatible = "sensirion,sht3x";
reg = <0x44>; // I2C 地址
status = "okay";
};
};添加 UART 设备
c
// 配置 UART2 为用户串口
&uart_2 {
status = "okay";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&uart2_active>;
pinctrl-1 = <&uart2_sleep>;
};
// 引脚配置
&tlmm {
uart2_active: uart2_active {
mux {
pins = "gpio4", "gpio5"; // TX, RX
function = "blsp_uart2";
};
config {
pins = "gpio4", "gpio5";
drive-strength = <2>;
bias-disable;
};
};
};配置 GPIO
c
// 在设备树中定义 GPIO
/ {
custom_gpio {
compatible = "quectel,custom-gpio";
// 定义 GPIO 引脚
gpio-led = <&tlmm 10 GPIO_ACTIVE_HIGH>;
gpio-button = <&tlmm 11 GPIO_ACTIVE_LOW>;
// 中断配置
interrupt-parent = <&tlmm>;
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
};
};驱动开发
字符设备驱动示例
c
// 简单字符设备驱动(用于控制 GPIO)
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/uaccess.h>
#define DEVICE_NAME "custom_gpio"
#define GPIO_LED 10
static int major_number;
static struct class *device_class;
static struct device *device;
static ssize_t device_write(struct file *file,
const char __user *buf,
size_t len, loff_t *offset)
{
char value;
if (copy_from_user(&value, buf, 1))
return -EFAULT;
gpio_set_value(GPIO_LED, value - '0');
return len;
}
static struct file_operations fops = {
.write = device_write,
};
static int __init gpio_driver_init(void)
{
// 申请 GPIO
gpio_request(GPIO_LED, "led");
gpio_direction_output(GPIO_LED, 0);
// 注册字符设备
major_number = register_chrdev(0, DEVICE_NAME, &fops);
device_class = class_create(THIS_MODULE, DEVICE_NAME);
device = device_create(device_class, NULL,
MKDEV(major_number, 0), NULL, DEVICE_NAME);
pr_info("GPIO driver loaded\n");
return 0;
}
static void __exit gpio_driver_exit(void)
{
device_destroy(device_class, MKDEV(major_number, 0));
class_destroy(device_class);
unregister_chrdev(major_number, DEVICE_NAME);
gpio_free(GPIO_LED);
}
module_init(gpio_driver_init);
module_exit(gpio_driver_exit);
MODULE_LICENSE("GPL");固件烧录
使用 QFIL 烧录(Windows)
1. 安装高通 USB 驱动和 QFIL 工具
2. 模组进入 EDL(Emergency Download)模式:
- 按住 BOOT_CONFIG 引脚,同时上电
- 或通过 ADB:adb reboot edl
3. 打开 QFIL,选择 Flat Build
4. 加载 rawprogram0.xml 和 patch0.xml
5. 点击 Download 开始烧录使用 fastboot 烧录(Linux)
bash
# 进入 fastboot 模式
adb reboot bootloader
# 查看设备
fastboot devices
# 烧录各分区
fastboot flash boot boot.img
fastboot flash system system.img
fastboot flash vendor vendor.img
fastboot flash userdata userdata.img
# 重启
fastboot reboot