imx6ull rootfs移植
busybox 根文件系统构建
通过 busybox 手动构建的根文件系统,缺失部分目录和相关脚本以及第三方的库和头文件,需要我们手动创建,操作复杂且繁琐。
有了 buildroot 谁还手动构建呢。。。。。。
buildroot 根文件系统构建
直接使用 buildroot 会方便很多,但是 buildroot 也是需要使用 busybox 来构建基础的 rootfs,区别在于 buildroot 支持了很多第三方 package,可以很方便的进行集成,make menuconfig 配置后就可以支持很多第三方组件,不需要去研究第三方组件复杂的编译流程,及其复杂的依赖项。
buildroot获取
从 buildroot 官网地址 通过浏览器直接下载最新版本,下载完成后放到 Linux 环境下解压即可;
下载到linux 开发环境使用解压命令进行解压
tar -xvf buildroot-2023.02.3.tar.xz
buildroot配置
直接在根目录下配置进行相关配置:
make menuconfig
Target options
主要是目标芯片和编译目标的相关设置
Target options
-> Target Architecture = ARM (little endian) # 架构为 ARM 小端架构
-> Target Architecture Variant = cortex-A7 # 内核为 cortex-A7
-> Target ABI = EABIhf # 编译后的二进制是支持浮点运算的
-> Floating point strategy = NEON/VFPv4 # 浮点指令集
-> ARM instruction set = ARM # 指令集选择
-> Target Binary Format = ELF # 编译后的二进制目标格式
Toolchain
编译工具链相关配置:
Toolchain
-> Toolchain type = External toolchain # 选择外部工具链
-> Toolchain = Custom toolchain # 编译链来源选择用户交叉编译器
-> Toolchain origin = Pre-installed toolchain # 编译链安装方式选择预装的编译器,不选择下载
-> Toolchain path =/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf #编译链路径
-> Toolchain prefix = $(ARCH)-linux-gnueabihf # 编译链前缀
-> External toolchain gcc version = 4.9.x # 使用的编译链版本为
-> External toolchain kernel headers series = 4.1.x # 编译链支持的内核版本(填写Linux kernel 版本)
-> External toolchain C library = glibc/eglibc # 工具链C库选择
-> [*] Toolchain has SSP support? (NEW) # 不选会报错
-> [*] Toolchain has RPC support? (NEW) # 不选会报错
-> [*] Toolchain has C++ support? # 支持 C++
-> Target linker options = xxxx # 根据需要添加编译选项(一般不需要)
System configuration
设置系统初始化相关配置
System configuration
-> System hostname = root # 系统主机名称设置
-> System banner = Welcome to i.mx6ull # 登录系统后的打印
-> Init system = BusyBox # 使用 busybox 构建根文件系统
-> /dev management = Dynamic using devtmpfs + mdev # 使用 mdev 设备节点管理
-> [*] Enable root login with password (NEW) # 使能登录密码
-> Root password = 123qwe # 设置登录密码
-> [*] Install timezone info # 安装时区库,用于date进行本地时间转换
-> timezone list = asia # 时区列表为亚洲
-> default local time = Asia/Shanghai # 默认时区设置为上海
Kernel
配置 kernel 相关选项,此处使用我们自己的 Kernel,不使用buildroot 下载的
Kernel
->[ ] Linux Kernel
Target packages
配置主要是选择第三方库或软件(你想要的都在这里),例如:ethtool(以太网工具)、tcpdump(抓包工具)、iperf3(网络测速工具)、lrzsz(Zmodem传输工具)、iw(无线配置工具)、wiress-tools(无线配置工具)
Target packages
-> Networking applications # 添加网络工具
-> [*] iperf3
-> [*] tcpdump
-> [*] ethtool
-> [*] lrzsz
-> [*] iw
-> [*] wireless tools
-> [*] Install shared library
Filesystem images
主要是选择 rootfs 文件系统使用的文件系统类型,不同的文件系统针对不同的存储介质有不同的表现,例如 yaffs2 针对 大容量的nand flash 设计的,jffs2 是针对 nor flash 设计的
-> Filesystem images
-> [*] ext2/3/4 root filesystem # EMMC或 SD卡的话就用 ext3/ext4
-> ext2/3/4 variant = ext4 # 选择 ext4格式
-> [*] tar the root filesystem # 选择rootfs 压缩类型,mfgtools在烧录时会解压
-> Compression method = bzip2
Bootloaders
选择boot类型,选择后会自动下载源码,然后进行编译,此处不需要选择任何选项,我们使用自己编译的 uboot。
Bootloaders
->[ ] U-boot
Host utilities
在编译 Buildroot 过程中,X86主机上所依赖的一些工具,全部取消不需要。
Legacy config options
是一些过期作废的软件包,一般都不需要。
busybox源码修改
busybox 是构建根文件系统的基础,会在编译前拉取最新的版本,但是 busybox 对中文显示支持有问题,需要手动修改源码。
package 目录下是 buildroot 下所有安装包的下载方式,在 make menconfig 选择后,make 编译之前,会自动下载配置的软件包到 dl 目录,dl 目录下的包是以压缩包的形式存在,在编译前还需要把对应的包解压到 output/build 目录,所以需要在此修改 busybox-1.36.1 的源码;
查看安装包
make show-targets
查看的安装包也就是 dl 目录下已经下载完成的工具包;
配置修改
make busybox-menuconfig
Location:
-> Settings
-> [ ]Build static binary (no shared libs) # Linux 支持动态编译后的可执行文件,否则仅能运行静态编译后的可执行文件
-> Support Unicode # 编解码支持
-> Check $LC_ALL, $LC_CTYPE and $LANG environment variables
源码修改
busybox-1.36.1/libbb/printable_string.c 修改如下
const char* FAST_FUNC printable_string2(uni_stat_t *stats, const char *str)
{
....
while (1) {
....
if (c < ' ')
break;
/* 删除对大于 0x7f 字符的限制
if (c >= 0x7f)
break;
*/
s++;
}
....
while (1) {
unsigned char c = *d;
if (c == '\0')
break;
/* 删除对大于 0x7f 字符的限制 */
/* if (c < ' ' || c >= 0x7f) */
if( c < ' ')
*d = '?';
d++;
}
....
}
busybox-1.36.1/libbb/unicode.c 下修改如下
static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags)
{
....
while ((int)--width >= 0) {
unsigned char c = *src;
if (c == '\0') {
do
*d++ = ' ';
while ((int)--width >= 0);
break;
}
/* 删除对大于 0x7f 字符的限制 */
/**d++ = (c >= ' ' && c < 0x7f) ? c : '?';*/
*d++ = (c >= ' ') ? c : '?';
src++;
}
....
while (*d) {
unsigned char c = *d;
/* 删除对大于 0x7f 字符的限制 */
/* if (c < ' ' || c >= 0x7f) */
if(c < ' ')
*d = '?';
d++;
}
....
}
编译测试
开始编译:
编译前需要下载所需要的软件包,所以需要保持网络连接。
make
如果想单独编译并指定的安装包,例如对 busybox 修改后需要单独编译 busybox 可以执行如下命令:
make busybox
然后重编译 buildroot ,完成rootfs 的打包:
make
编译产物
产物路径是:output/images/rootfs.tar.bz2
错误解决
编译时出现 kernel 版本错误问题:
Incorrect selection of kernel headers: expected 4.1.x, got 4.0.x
make[1]: *** [package/pkg-generic.mk:283: /home/lux/share/imx6ull/buildroot/buildroot-2023.02.3/output/build/toolchain-external-custom/.stamp_configured] Error 1
主要是由于我们再 buildroot 配置工具链支持的是 kernel 4.1.x 版本,
所以需要修改编译链下头文件中的版本号:
sudo vim /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include/linux/version.h
kernel 启动后出现文件夹缺失:
modprobe: can't change directory to '/lib/modules': No such file or directory
modprobe 在加载和卸载内核模块时出现如上问题,主要是由于 /lib 目录下缺少 modules 目录导致,修改如下:
cd /lib
mkdir modprobe
kernel 启动后 random 启动阻塞问题:
random: nonblocking pool is initialized
在 kernel 启动大概几十秒后出现如上答应,提示 random 相关的初始化完成,这主要是由于 4.1.15 版本的 kernel 中random 驱动存在 BUG 导致,修改 drivers/char/random.c 即可
修改前:
if ((fast_pool->count < 64) &&
!time_after(now, fast_pool->last + HZ))
return;
修改后:
if ((fast_pool->count < 64) &&
!time_after(now, fast_pool->last + HZ) &&
nonblocking_pool.initialized)
return;