一、树莓派开发环境搭建
二、Linux文件系统的目录结构
三、树莓派Linux源码目录树分析
四、树莓派Linux源码配置
五、如何配置树莓派的Linux内核
六、树莓派Linux内核编译
七、配置启动参数的cmdline.txt
树莓派官网
raspberrypi
raspberrypi/tools
raspberrypi/linux/tree/rpi-4.14.y
cp /mnt/hgfs/Share/tools-master.zip ./
unzip tools-master.zip 解压
cd /home/tan/raspberryPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
//gcc-linaro-arm-linux-gnueabihf-raspbian 32位
//gcc-linaro-arm-linux-gnueabihf-raspbian-x64 64位
arm-linux-gnueabihf-gcc ->arm-linux-gnueabihf-gcc-4.8.3
echo $PATH // 获得当前环境变量的值
pwd // 获得当前路径
export PATH=$PATH:pwd
PATH 环境变量
export PATH=/home/orangepi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/tan/raspberryPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
export PATH=$PATH:/home/tan/raspberryPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
修改工作目录下的 .bashrc
隐藏文件,配置命令终端的
vi /home/tan/.bashrc
在文件最后一行加入:
export PATH=/home/orangepi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/tan/raspberryPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
source /home/tan/.bashrc 加载配置文件,马上生效配置。
arm-liunx-gnueabihf-gcc -v
unzip linux-rpi-4.14.y.zip
Linux 文件系统的目录结构是由 Filesystem Hierarchy Standard(FHS,文件系统层次结构标准)定义的,这个标准规定了不同目录的用途和存储的内容。以下是 Linux 文件系统中一些常见的目录及其用途:
/bin:
/boot:
/dev:
/etc:
/home:
/lib 和 /lib64:
/media:
/mnt:
/opt:
/proc:
/root:
/run:
/sbin:
/srv:
/sys:
/tmp:
/usr:
/var:
/etc/opt:
/usr/local:
这只是 Linux 文件系统的一小部分,不同的 Linux 发行版可能会有一些变化,但大多数发行版都遵循 FHS 标准。了解这些目录结构有助于更好地管理和维护 Linux 系统。
Linux内核源代码目录树结构
Linux是开源,免费,LInux开源社区工作者共同维护
Linux是一个开源的,支持多架构多平台代码
sudo apt-get install tree
Linux 源码目录树非常庞大,包含了操作系统的各个组件和子系统。以下是 Linux 源码目录树的主要部分和其功能的简要分析:
arch/:
block/:
crypto/:
Documentation/:
drivers/:
fs/:
include/:
init/:
ipc/:
kernel/:
lib/:
mm/:
net/:
scripts/:
security/:
sound/:
tools/:
usr/:
virt/:
Makefile:
这只是 Linux 源码目录树的一小部分,整个目录树非常庞大。Linux 内核的模块化设计使得各个组件可以独立开发和维护,同时也为适应不同硬件和用途提供了灵活性。 Linux 内核的开源特性使得全球的开发者社区能够共同贡献和维护这个强大的操作系统内核。
在Linux系统中,源码配置通常指的是通过源码编译的方式配置和构建软件。下面是一个通用的Linux源码配置的基本流程:
获取源码: 首先,你需要获取你想要配置和编译的软件的源代码。这通常包括从开发者的官方网站、版本控制系统(如Git)或Linux发行版的软件仓库中获取。
解压源码: 如果源码是一个压缩文件(通常是.tar.gz或.zip格式),你需要解压它。你可以使用以下命令:
tar -xzvf source_code.tar.gz
或者
unzip source_code.zip
进入源码目录: 使用cd
命令进入解压后的源码目录:
cd source_code
配置: 执行configure
脚本或其他配置脚本,该脚本通常位于源码根目录中。这个脚本会检查系统环境并生成一个Makefile,它包含了编译和安装软件的指令。如果没有configure脚本,你可能需要查看软件的文档以了解正确的配置方法。
./configure
配置过程中可能需要安装一些依赖项。如果缺少某些依赖项,configure会报错,并提供相关提示。
编译: 执行make
命令进行编译:
make
这将根据Makefile文件编译源码,并生成可执行文件。
安装: 使用make install
命令将编译好的文件安装到系统中。请注意,通常需要使用sudo
权限来进行安装:
sudo make install
如果你不希望将文件安装到系统目录,而是想在当前目录下运行可执行文件,可以省略make install
步骤。
清理: 如果需要,你可以使用make clean
命令清理编译过程中生成的中间文件,或使用make distclean
清理更多文件。
make clean
或者
make distclean
请注意,以上步骤是通用的,实际的配置和编译步骤可能因软件的不同而有所不同。因此,请务必阅读软件的文档以获取详细的配置和编译说明。
驱动代码的编写
驱动代码的编译需要一个提前编译好的内核
编译内核就必须配置
配置的最终目标会生成 .config文件,该文件指导Makefile去把有用东西组织成内核
编写和编译驱动代码通常需要与特定内核版本兼容,并需要一些配置步骤。下面是一般的流程:
获取内核源码: 从官方Linux内核仓库、Linux发行版提供的内核源码包,或者其他可信来源获取所需的内核源码。
git clone https://github.com/torvalds/linux.git
配置内核: 进入内核源码目录,并运行make menuconfig
或其他配置命令,以配置内核。这将生成一个.config
文件,其中包含了配置选项。
cd linux
make menuconfig
在配置中,你需要确保启用了与你的驱动相关的选项,比如设备驱动支持、文件系统支持等。你可以在Device Drivers
下找到许多驱动相关的配置选项。
保存配置: 退出配置界面时,系统会询问是否保存配置,选择保存并退出。
编译内核: 运行make
命令编译内核,这将生成vmlinuz
和其他必要的文件。
make
编写驱动代码: 创建你的驱动代码文件(通常是一个.c
文件),实现必要的功能。你的驱动代码应该包含与内核模块相关的初始化和清理函数,以及适当的模块信息。
编写Makefile: 创建一个Makefile文件,用于编译你的驱动代码。该Makefile通常包括编译选项和链接选项,以确保代码可以正确地与内核一起编译。
obj-m += your_driver.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
在这个例子中,your_driver.o
是你的驱动代码的目标文件。
编译驱动: 运行make
命令来编译你的驱动代码。这将生成一个.ko
文件,即内核模块。
make
加载驱动: 使用insmod
命令加载你的驱动模块。
insmod your_driver.ko
查看加载信息: 使用dmesg
命令查看内核日志,以确认驱动是否成功加载。
dmesg
卸载驱动: 如果需要,使用rmmod
命令卸载你的驱动模块。
rmmod your_driver
这只是一个简单的示例,实际的驱动编写和编译可能会更为复杂,取决于你的具体需求和内核版本。确保阅读相关文档,并在需要时调整配置和代码。
以下是对三种方式的总结:
使用厂家提供的配置文件:
.config
)复制到内核源码目录,使用该配置进行编译。cp 厂家.config .config
使用make menuconfig进行交互式配置:
make menuconfig
命令,通过文本界面逐一选择配置选项。make menuconfig
完全自己进行配置:
.config
文件,通过文本编辑器逐一配置内核选项,包括添加、删除、修改。这三种方式提供了不同的灵活性和适用性,选择哪种方式取决于具体的需求和使用场景。初学者通常可以从厂家提供的配置文件开始,然后根据需要进行微调。在深入了解内核配置的同时,逐渐可以采用更灵活的方式进行配置。
【树莓派】内核开发 说明 下载代码 编译 替换内核
在树莓派上配置Linux内核通常包括以下步骤:
获取树莓派内核源码:
树莓派官方提供了Linux内核的源代码,你可以从官方的GitHub仓库中获取。
使用以下命令克隆官方的内核仓库:
git clone --depth=1 https://github.com/raspberrypi/linux
--depth=1
选项表示只克隆最新的一次提交,以减小下载体积。
进入内核源码目录:
cd linux
配置内核:
运行make menuconfig
以进入内核配置界面。
make ARCH=arm CROSS_COMPILE=[交叉编译器前缀] menuconfig
在配置界面中,选择所需的配置选项。你可以使用箭头键进行导航,使用空格键进行选择,然后按下回车键进入子菜单或确认选项。
保存配置:
编译内核:
运行make
命令进行内核编译。
make ARCH=arm CROSS_COMPILE=[交叉编译器前缀]
这一步可能需要一些时间,具体取决于你的计算机性能。
生成内核映像文件:
运行以下命令生成内核映像文件:
make ARCH=arm CROSS_COMPILE=[交叉编译器前缀] zImage
内核映像文件通常会生成在 arch/arm/boot/
目录下。
生成设备树文件:
运行以下命令生成设备树文件(*.dtb):
make ARCH=arm CROSS_COMPILE=[交叉编译器前缀] dtbs
设备树文件通常会生成在 arch/arm/boot/dts/
目录下。
安装内核映像和设备树文件到SD卡:
zImage
和相关的 .dtb
文件拷贝到SD卡的 /boot
目录。更新引导配置:
编辑 /boot/config.txt
文件,确保引导配置正确,指向新的内核映像和设备树文件。
kernel=zImage
device_tree=bcm2837-rpi-3-b.dtb
根据你的树莓派型号,.dtb
文件的名称可能会有所不同。
重启树莓派:
这是一个基本的内核配置和编译流程。根据你的需求,你可能需要更改其他配置选项或使用其他编译目标。确保参考树莓派官方文档和内核源码中的README文件,以获取更详细的信息。
加载 Linux 内核模块有两种主要方式:
编译进内核:
zImage
)将包含该驱动。以模块方式加载:
.ko
文件),并在运行时动态加载到内核中。insmod
)加载。下面是两种方式的简要描述:
在内核源码中配置该驱动,确保其被包含在编译中。
make menuconfig
重新编译内核。
make
将新的内核映像烧录到系统。
编译驱动成为模块。
make modules
加载模块到内核。
insmod xxx.ko
卸载模块(如果需要)。
rmmod xxx
在实际应用中,通常会选择以模块方式加载,因为这提供了更大的灵活性。只有那些必须随着内核一起启动的基本驱动才会选择编译进内核。
*
编译进内核 zImage包含了驱动
M
模块方式生成驱动文件xxx.ko 系统启动后,通过命令inmosd xxx.ko 加载
配置树莓派内核的指令。
下面是对指令的详细解释:
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
ARCH=arm: 指定目标体系结构为 ARM 架构。
CROSS_COMPILE=arm-linux-gnueabihf-: 指定交叉编译器的前缀,用于生成适用于 ARM 架构的二进制文件。在这里,arm-linux-gnueabihf-
是一个针对硬浮点(hard-float)的交叉编译器的前缀。硬浮点指的是使用硬件浮点运算单元进行浮点运算,这通常会提高性能。
KERNEL=kernel7: 指定要生成的内核类型。在树莓派中,kernel7
是用于 Raspberry Pi 2 和 Raspberry Pi 3 的内核。
make bcm2709_defconfig: 使用 bcm2709_defconfig
配置文件生成内核配置。bcm2709
是 Raspberry Pi 2 的代号。该配置文件包含了一组默认的配置选项,适用于 Raspberry Pi 2 和 3。
这个命令的目的是为指定的目标体系结构和硬件平台生成一个默认的内核配置。这个配置可以作为内核配置的起点,你可以在此基础上通过 make menuconfig
等命令进一步定制内核配置。
编译命令用于生成树莓派内核的不同部分。
下面是对指令的详细解释:
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs
ARCH=arm: 指定目标体系结构为 ARM 架构。
CROSS_COMPILE=arm-linux-gnueabihf-: 指定交叉编译器的前缀,用于生成适用于 ARM 架构的二进制文件。
KERNEL=kernel7: 指定要生成的内核类型。在树莓派中,kernel7
是用于 Raspberry Pi 2 和 Raspberry Pi 3 的内核。
make -j4: 使用 -j4
参数表示并行编译,同时利用 4 个核心进行编译。这样可以加速编译过程。
zImage: 生成内核镜像文件,这是 Linux 内核的主要可执行文件。
modules: 生成内核模块,这些模块可以在运行时加载到内核中。
dtbs: 生成设备树二进制文件,设备树文件包含了硬件信息和配置,用于在运行时配置硬件。
这个命令的目的是通过交叉编译器为指定的目标体系结构生成内核镜像、内核模块和设备树二进制文件。-j4
的参数用于充分利用多核心进行并行编译,提高编译速度。
编译成功后,看到源码树目录多了vmlinux,失败则无此文件
成功后,目标zImage镜像arch/arm/boot底下
vmlinux
是 Linux 内核的可执行文件,而 zImage
是压缩后的内核镜像。在成功编译后,你会在指定的输出目录中看到这些文件。
vmlinux: 这是未压缩的内核可执行文件,包含了完整的内核符号信息。通常,这个文件会生成在 Linux 内核源码树的根目录下。
zImage: 这是压缩后的内核镜像,用于启动树莓派。它通常位于 arch/arm/boot/
目录下。
如果编译成功,你可以在 arch/arm/boot/
目录下找到生成的 zImage
文件。这个文件是你需要烧录到树莓派SD卡的内核镜像。
请确保查看编译输出,以了解是否有任何错误消息。在编译过程中,如果有错误,它们通常会在编译输出中显示,并且可能会指导你解决问题。
命令是用于将 zImage
打包成树莓派可用的 xxx.img
文件。这个过程通常是通过使用 mkknlimg
工具完成的。
下面是对这个命令的解释:
./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img
./scripts/mkknlimg: 这是一个脚本工具,用于创建树莓派可用的内核镜像文件。
arch/arm/boot/zImage: 这是你之前编译生成的内核镜像文件。
./kernel_new.img: 这是生成的树莓派可用的内核镜像文件的输出路径和文件名。
使用这个命令会将 zImage
打包成一个树莓派可用的内核镜像文件,并命名为 kernel_new.img
。你可以将这个文件烧录到 SD 卡的相应位置,使树莓派在启动时使用这个内核。
请注意,确保你已经按照树莓派启动的相关步骤进行配置,包括在 SD 卡上的 config.txt
文件中正确指定了内核镜像的位置。
你提供的是关于将内核和相关文件拷贝到 U 盘上以更新树莓派系统的步骤。下面是对这个操作的逐步解释:
创建目录:
mkdir data1 data2
创建两个目录 data1
和 data2
,用于挂载 U 盘上的两个分区。
挂载 U 盘分区:
sudo mount /dev/sdb1 data1
sudo mount /dev/sdb2 data2
一个fat分区,是boot相关的内容,kernel的img
一个是ext4分区,也就是系统的根目录分区。
将 U 盘的第一个分区挂载到 data1
,第二个分区挂载到 data2
。这里假设 U 盘分区是 /dev/sdb1
和 /dev/sdb2
。
安装内核模块到 U 盘系统分区:
安装modules, 设备驱动文件:如 HDMI接口 USB WIFI I/O …
sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=/home/tan/data2 modules_install
将编译生成的内核模块安装到 U 盘系统分区中。这是确保 U 盘上的系统具有新的内核模块的步骤。
备份原内核镜像:
先备份
cd /home/tan/data1
cp kernel7.img kernel7OLD.img
在 data1
目录中备份原始的内核镜像文件,以便出现问题时可以回滚。
拷贝新生成的内核镜像到 U 盘:
再把编译新生成的拷贝到data1,起名kernel7.img
cp kernel_new.img /home/tan/data1/kernel7.img
将新生成的内核镜像拷贝到 U 盘上,并命名为 kernel7.img
,这是树莓派所期望的内核镜像文件名。
拷贝设备树文件:
拷贝配置文件
复制其他相关文件
cp arch/arm/boot/dts/.*dtb* /home/tan/data1
cp arch/arm/boot/dts/overlays/.*dtb* /home/tan/data1/overlays/
cp arch/arm/boot/dts/overlays/README /home/tan/data1/overlays/
将编译生成的设备树文件拷贝到 U 盘中。这些文件通常以 .dtb
结尾。
以上操作假设你的 U 盘已经正确挂载,并且文件路径和命令参数都是正确的。确保在执行这些操作之前,U 盘上的分区已经正确挂载。
Raspberry Pi(树莓派)中用于配置启动参数的 cmdline.txt
文件的示例。在这个文件中,你可以设置一些启动时的参数,以影响系统的行为。
dwc_otg.lpm_enable=0 console=tty1 console=serial0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
让我们解释一下这个例子中的参数:
dwc_otg.lpm_enable=0
:
dwc_otg
是 Raspberry Pi 中用于 USB 控制器的驱动程序。lpm_enable=0
表示将 USB 低功耗模式禁用。console=tty1
和 console=serial0,115200
:
console=tty1
表示将控制台输出(终端)重定向到第一个虚拟终端。console=serial0,115200
表示将控制台输出也重定向到串口 0(Raspberry Pi 上的 UART 接口),波特率为 115200。root=/dev/mmcblk0p2
:
root
参数指定了根文件系统所在的设备。/dev/mmcblk0p2
表示使用 SD 卡(mmcblk0)上的第二个分区(p2)作为根文件系统。rootfstype=ext4
:
elevator=deadline
:
elevator
参数指定了 I/O 调度器的类型,这里是使用 deadline 调度器。fsck.repair=yes
:
fsck.repair
参数表示在检查文件系统时自动修复任何错误。rootwait
:
rootwait
参数告诉内核等待根文件系统设备就绪。这些参数可以根据系统的需求进行调整,但在大多数情况下,使用默认值是合适的。在修改 cmdline.txt
文件时,请确保你知道自己在做什么,并备份文件以防止意外。