跳到主要内容

SDK 内核配置

menuconfig 是 Linux 内核提供的交互式配置工具,具有基于终端的图形化界面,可直观地浏览和修改内核配置选项。它能够自动处理配置项之间的依赖关系,避免手动修改配置文件时可能出现的冲突。 除了 menuconfig 外,内核还提供了 nconfig、xconfig 等其他配置界面。以下将介绍 menuconfig 的主要功能和基本使用方法。

1. 配置界面

执行如下指令,打开配置界面:

./build.sh lunch
./build.sh kernelconfig

2. 基本操作

  1. 执行命令后显示的配置界面如下:
    Luckfox

从界面上方我们可以看到 menuconfig 的基本操作和说明。

  1. 按键操作:

    • PgUpPgDn:浏览、选择内核功能
    • :选择Select、Exit等操作
    • Enter:进入子菜单吃的
    • Y:选中这项功能
    • N:排除这项功能
    • M:以模块的形式选择
    • Esc:双击Esc返回上一级菜单
    • ?:查看这项功能的帮助信息
    • /:搜索
  2. 图例说明:

    • [*] :已选中的项目
    • [ ] :未选中的项目
    • <M> :已选中的项目(以模块形式)
    • < > :未选中的项目(以模块形式)
  3. 中间区域是用户选择各项功能的地方,您可以使用上下方向键进行导航,同时也支持直接按下行首带颜色的字母,跳转到该行,如 Kernel Features 的首字母 K,当我们按下 K 键时就会直接跳转至该行。

  4. 底部区域包含了一些常用的操作选项,为用户提供了重要的交互功能。它们的作用如下:

    • <Select>:进入当前高亮配置项的子菜单
    • <Exit>:退出当前菜单,返回上一层
    • <Help>:提供当前高亮配置项的帮助信息
    • <Save>:保存当前的配置更改,但不退出配置工具
    • <Load>:加载指定的配置文件

3. 功能简述

内核配置界面的中间部分是一个多层级的菜单系统,您可以通过上下方向键进行导航,按 Enter 键进入子菜单,按 Esc 键返回上一级菜单,通过这个界面,用户可以根据系统需求灵活配置内核,选择需要的功能和驱动,以构建适合特定硬件和用途的定制内核,以下是 Linux 内核配置界面中的主要项目:

  • General setup(常规设置):运行时的基本配置
  • Kernel Features(内核特性):核心功能的配置,如模块化、块设备支持等
  • CPU Power Management(CPU 功耗管理):配置 CPU 的功耗管理选项
  • Enable loadable module support(启用可加载模块支持):是否支持内核模块
  • IO Schedulers(I/O 调度器):配置磁盘 I/O 调度器
  • Networking support(网络支持):配置网络支持,包括协议、设备等
  • Device Drivers(设备驱动):配置各种设备驱动,如输入设备、USB 设备等
  • File systems(文件系统):配置文件系统支持,选择支持的文件系统类型
  • Security options(安全选项):配置内核安全相关选项
  • Cryptographic API(加密 API):配置加密 API 支持

4. Kernel 添加驱动示例

以下示例演示如何在 Kernel 中添加 USB TO AUDIO 驱动:

  1. 打开配置界面。进入 SDK 根目录,启动 kernel 配置界面。对于尚未编译过的 SDK,请先根据所使用的开发板选择相应的分支:
  2. 按 / 键后输入 SND_USB_AUDIO 并回车开始搜索。
    Luckfox
  3. 若仅有一个匹配项,按 1 即可跳转至该配置位置。若存在多个匹配结果,请根据路径选择对应的组件。
    Luckfox
  4. 按下 Y 或 Space 勾选 USB Audio,然后选择 Save 保存配置。
    Luckfox
  5. 编译内核和编译 rootfs:
    ./build.sh kernel

5. 单独烧录内核

  1. 按住BOOT键的同时连接电脑,待瑞芯微刷机工具显示MaskRom设备(设备号可能不同)后即可松开BOOT键。
  2. 点击Search Path选择固件存放目录。
  3. 勾选 boot 分区和 download.bin。
  4. 点击 Download 按钮执行烧录。
    Luckfox
  5. 登录开发板验证:
    Luckfox

6. Linux下加载ko驱动模块

6.1 ko 文件简介

在Linux操作系统中,.ko文件是内核模块文件的扩展名。内核模块是一种可以在运行时加载和卸载的代码,用于扩展Linux内核的功能,无需重新编译整个内核。每个.ko文件包含模块的代码和元数据,允许用户在不重新启动系统的情况下添加或移除特定功能,如驱动程序或文件系统支持。

6.2 ko文件的优点

  1. 动态加载和卸载:内核模块可以在运行时动态加载到内核中,也可以随时卸载,无需重新启动系统。这使得系统管理员和开发人员能够在不中断系统运行的情况下添加、测试或修复功能。
  2. 节约资源:内核模块允许将不常用的功能作为模块加载,从而减少了系统内核的大小和内存占用。这有助于提高系统的资源利用率。
  3. 定制性: 内核模块允许用户根据需要添加或移除特定功能,从而实现定制化的系统。这对于嵌入式系统、特定硬件支持和特定应用场景非常有用。
  4. 减少编译时间: 重新编译整个内核可能会花费大量时间,而使用内核模块则可以避免这种情况。只需编译和加载所需的模块,节省了时间和资源。
  5. 快速调试和开发:内核模块可以在不重新启动系统的情况下加载和卸载,这使得驱动程序和其他内核代码的调试和开发变得更加高效。
  6. 易于维护: 内核模块的独立性使得它们可以独立于整个内核进行维护和升级。这有助于降低系统维护的复杂性。
  7. 增加兼容性:内核模块可以根据需要支持多个内核版本,从而增加了软件的兼容性和灵活性。

6.3 应用实例

下载工程文件戳我下载,整个工程只有两个文件,一个helloworld.c,一个用来控制编译的Makefile。

  1. 将工程文件复制到已经安装了编译通过的 Luckfox Pico SDK 的 Ubuntu 主机或虚拟机上。

  2. 打开、修改 Makefile 文件让 make 命令进入指定的内核源代码目录也就是 Luckfox Pico SDK目录/luckfox-pico/sysdrv/source/kernel 。(Makefile 文件建议直接下载使用,复制粘贴需自己修改Tab缩进问题)

    obj-m += helloworld.o
    KDIR:=/home/ubuntu/Luckfox/sdk-1015/luckfox-pico/sysdrv/source/kernel
    PWD?=$(shell pwd)
    MAKE := make
    ARCH := arm
    CROSS_COMPILE := /home/ubuntu/Luckfox/sdk-1015/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-
    KBUILD_OUTPUT := $(abspath $(dir $(lastword $(KDIR))))/objs_kernel
    all:
    $(MAKE) O=$(KBUILD_OUTPUT) -C $(KDIR) M=$(PWD) modules \
    ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)
    echo $(PWD)
    clean:
    rm -f *.ko *.o *.mod *.mod.o *.mod.c *.symvers *.order
  3. 代码部分:

    #include <linux/module.h>
    #include <linux/init.h>

    static int helloworld_init(void)
    {
    printk("helloworld!\n");
    return 0;
    }

    static void helloworld_exit(void)
    {
    printk("helloworld bye\n");
    }

    module_init(helloworld_init);
    module_exit(helloworld_exit);

    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Luckfox");
    MODULE_VERSION("V1.0");
    • 模块加载函数:当通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块的相关初始化工作。 Linux内核模块加载函数一般以__init标识声明,模块加载函数以“module_init(函数名)”的形式被指定。它返回整型值,若初始化成功,应返回0。而在初始化失败时,应该返回错误编码。在Linux内核里,错误编码是一个接近于0的负值。
    • 模块卸载函数:当通过rmmod命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块卸载函数相反的功能。 Linux内核模块加载函数一般以__exit标识声明,模块卸载函数在模块卸载的时候执行,而不返回任何值,且必须以“module_exit(函数名)”的形式来指定。
    • 模块许可证声明许可证(LICENSE):明描述内核模块的许可权限,如果不声明LICENSE,模块被加载时,将收到内核被污染(Kernel Tainted)的警告。在Linux内核模块领域,可接受的LICENSE包括“GPL”、“GPL v2”、“GPLand additional rights”、“Dual BSD/GPL”、“Dual MPL/GPL”和“Proprietary”(关于模块是否可以采用非GPL许可权,如“Proprietary”,这个在学术界和法律界都有争议)。大多数情况下,内核模块应遵循GPL兼容许可权。Linux内核模块最常见的是以MODULE_LICENSE(“GPL v2”)语句声明模块采用GPL v2。
    • 模块作者等信息声明:MODULE_AUTHOR、MODULE_DESCRIPTION、MODULE_VERSION、MODULE_DEVICE_TABLE、MODULE_ALIAS分别声明模块的作者、描述、版本、设备表和别名
  4. 进入工程文件中,执行以下命令(其中CROSS_COMPILE的地址需要按SDK的实际路径填写):

    export ARCH=arm

    export CROSS_COMPILE=/home/luckfox/Luckfox-Pico/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-

    make
    • 效果如下:
  1. 把helloworld.ko上传到开发板上,可以使用TFTP,ADB等方式。

    tftp 192.168.10.127 -g -r helloworld.ko
  2. 执行以上命令可以进行验证。

    # insmod helloworld.ko
    [ 200.330884] helloworld!
    # rmmod helloworld.ko
    [ 218.624421] helloworld bye
  3. 最后我们使用 dmesg 查看日志。

    # dmesg | grep hello
    [ 200.330884] helloworld!
    [ 218.624421] helloworld bye