嵌入式开发神器-buildroot使用记录-(持续更新)

嵌入式开发神器-buildroot使用记录-(持续更新) 阿帅 2023-11-03 17:57:08 341

[toc]

概述

buildroot用于嵌入式开发的整体编译环境,可以根据用户的配置,编译kernel,uboot,rootfs,用户的app等。
通过包含外部的Config.in,获取外部自定义的编译规则,进行编译。

在实际项目开发时,能够管理多业务场景,和多个硬件平台之间的关系,极大提高业务代码、平台代码的管理和维护。

源码下载

https://buildroot.org/downloads/

配置文件

法1:在configs下添加以_defconfig结尾的文件
编译: make xxx_defconfig
法2:直接拷贝自己的buildroot.config到buildroot/.config
编译:make

编译buildroot目录外的代码

目的:
创建两个目录:app, platform
app目录结构体:

app$ tree -L 1
.
├── buildroot
├── build.sh
├── Config.in
├── external.desc
├── external.mk
├── my_package
├── my_source
├── prebuilts
└── rootfs_overlay

buildroot: buildroot源码
build.sh:提供给外部调用(platform),最终进入buildroot make
my_package: 放置自己包的编译规则
my_source: 放置自己包的源码
buildroot编译放在它的目录之外的源码时,需要提供以下几个文件:
external.desc、external.desc、external.mk

external.desc

指定外部编译的顶层目录

book@suns:~/ss_sdk/app$ cat external.desc 
name: MY_APP
desc: my app external tree

其中,name是必须写出的,external.desc将导致buildroot/.config生成BR2_EXTERNAL_MY_APP_PATH
BR2_EXTERNAL_MY_APP_PATH的值,是由:在app目录下执行:

make -C ./buildroot/ BR2_EXTERNAL=/home/book/ss_sdk/app

得到的,即最终.config会写入:

BR2_EXTERNAL_MY_APP_PATH="/home/book/ss_sdk/app"

Config.in

包含子目录的Config.in

book@suns:~/ss_sdk/app$ cat ./Config.in 
source "$BR2_EXTERNAL_MY_APP_PATH/my_package/*/Config.in"

external.mk

包含子目录的编译规则

book@suns:~/ss_sdk/app$ cat external.mk 
include $(sort $(wildcard $(BR2_EXTERNAL_MY_APP_PATH)/my_package/*/*.mk))

my_package

包含自己的包的编译规则
该目录下的子目录名字,必须buildroot.config中的BR2_PACKAGE_XXXX中的XXXX一致(大写变小写)
目录结构:

book@suns:~/ss_sdk/app/my_package$ tree 
.
└── sstest
    ├── Config.in
    └── local.mk

1 directory, 2 files

其中,sstest文件夹是我们需要添加的一个进程对应的编译规则。

Config.in

告诉buildroot,本目录是BR2_PACKAGE_SSTEST对应的编译规则的目录。

book@suns:~/ss_sdk/app/my_package/sstest$ cat Config.in 
config BR2_PACKAGE_SSTEST
    bool "sstest"
    help
      ss test module

bool:标识
select,自动依赖:如果 A select B,则当A使能时,B自动使能。
depends on,手动依赖:如果A depends on B,则只有在B使能以后,A才可见,并需要手动进行使能。

*.mk:

book@suns:~/ss_sdk/app/my_package/sstest$ cat sstest.mk 
################################################################################
#
# SSTEST
#
################################################################################

SSTEST_VERSION = 1.0
SSTEST_SITE_METHOD = local
SSTEST_SITE = $(BR2_EXTERNAL_MY_APP_PATH)/my_source/sstest

SSTEST_LICENSE = Custom
SSTEST_LICENSE_FILES = license.txt
# Installs only a static library and a header file
SSTEST_INSTALL_STAGING = YES
SSTEST_INSTALL_TARGET = YES

define SSTEST_BUILD_CMDS
    $(TARGET_MAKE_ENV) $(MAKE) -C $(@D)
endef

define SSTEST_CLEAN_CMDS
    $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) clean
endef

define SSTEST_INSTALL_STAGING_CMDS
    $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) stage
endef

define SSTEST_INSTALL_TARGET_CMDS
    $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) install
endef

$(eval $(generic-package))

xxxx_CMDS:分别对用source下的makefile中的目标
上例,分别对应all、stage、install
注意:
xxx_STAGING : 该命令将host所需头文件或库拷贝到staging目录,用于编译其他模块是链接用
XXX_TARGETS : 该命令将拷贝目标到文件系统中
上述命令的实现都是在source下的makefile中实现的。

my_source

该目录下的子目录名字,必须buildroot.config中的BR2_PACKAGE_XXXX中的XXXX一致(大写变小写)
目录结构:

book@suns:~/ss_sdk/app/my_source$ tree
.
└── sstest
    ├── main.c
    └── Makefile

1 directory, 2 files

编译

fs: 包括所有格式文件系统编译和制作规则
boot: uboot编译规则
linux: kernel编译规则
package: 应用软件包编译规则

kconfig语法

基本语法

buildroot、kernel、uboot的kconfig语法是一致的。
buildroot中一般文件名为Config.in

config BR2_PACKAGE_ORION
        bool "ORION chip"
        help
                Use rockchip's orion chip

以上为例,make menuconfig可以看到ORION chip的选线,它的类型是bool,help为解释其作用的内容

默认值

单默认值
config BR2_PACKAGE_RKWIFIBT_BTUART
    string "bt uart"
    default "ttyS4"
    depends on BR2_PACKAGE_RKWIFIBT
    help
        tty that bt used
多默认值
config BR2_PACKAGE_RKWIFIBT_WIFI_KO
    string
    default "bcmdhd.ko" if BR2_PACKAGE_RKWIFIBT_AP6181
    default "bcmdhd.ko" if BR2_PACKAGE_RKWIFIBT_AP6212A1

单选框

choice
    prompt "Device type"
    default STM32F100RC
    config STM32F100RC
        bool "STM32F100RC"
    config STM32F100RD
        bool "STM32F100RD"
endchoice

menuconfig进入Device type后,将弹出单选框,内容为STM32F100RC和STM32F100RD

应用编译框架

包含支持的所有软件包的编译规则

pkg-*

各个文件定义了各种编译方式,例如generic-package,cmake-package等等

Makefile.in

将本录下的pkg-*包含进来,并指定buildroot编译时的编译环境

项目功能宏

项目功能宏:使用该宏来区分不同的项目,例如硬件平台名,产品名称等等
作用:通过项目宏来控制全局CFLAGS

全局CFLAGS定义在:

package/Makefile.in:
    TARGET_CONFIGURE_OPTS
        TARGET_CFLAGS
TARGET_CONFIGURE_OPTS 包含各package中所需的所有环境,可以在TARGET_CFLAGS中增加不同项目特定的CFLAGS

1、创建package/item_config.mk,写入

# 存放针对项目所有app可能用到的配置项
config BR2_PACKAGE_K_EEPROM_I2C_ADDR
    string
    default "0"
    help
        "eeprom i2c bus address"

在package/Config.in 中include “package/item_config.mk”即可
2、 创建package/pkg-item.mk,写入

# 将影响所有app的编译,如果每个选项只特定app使用,则在其的package/*.mk中条件编译
ifneq ($(BR2_PACKAGE_K_EEPROM_I2C_ADDR),)
TARGET_CFLAGS += -DK_I2C_ADDR=$(BR2_PACKAGE_K_EEPROM_I2C_ADDR)
endif

在package/Makefile.in后面include package/pkg-item.mk,即可

应用功能宏

应用功能宏: 该宏用来开/关应用中某个具体功能模块。
应为该功能宏只在某应用中使用,故需要在应用的package中进行控制

具体使用方法如下:
1、package/xx/Config.in

choice
    prompt "flash type"
        depends on BR2_PACKAGE_DEV_CFG
    default BR2_PACKAGE_DEV_CFG_USE_FACTORY_PART
    config BR2_PACKAGE_DEV_CFG_USE_FACTORY_PART
        bool "data in factory part"
    config BR2_PACKAGE_DEV_CFG_USE_EEPROM
        bool "data in eeprom"
endchoice

择一功能宏使用上述choice来定义即可
2、package/xx/module.mk

ifeq ($(BR2_PACKAGE_DEV_CFG_USE_EEPROM),y)
DEV_CFG_CONF_OPTS += DEV_CFG_USE_EEPROM=y
else ifeq ($(BR2_PACKAGE_DEV_CFG_USE_FACTORY_PART),y)
DEV_CFG_CONF_OPTS += DEV_CFG_USE_FACTORY_PART=y
endif

define DEV_CFG_BUILD_CMDS
        $(TARGET_CONFIGURE_OPTS) $(MAKE) $(DEV_CFG_CONF_OPTS) -C $(@D)
endef

define DEV_CFG_INSTALL_TARGET_CMDS
        $(TARGET_CONFIGURE_OPTS) $(MAKE) $(DEV_CFG_CONF_OPTS) -C $(@D) install
endef

3、source/XX/Makefile

ifeq ($(DEV_CFG_USE_FACTORY_PART),y)
CFLAGS += -DNVRAM_FACTORY_PART
else
CFLAGS += -DEEPROM_PART
endif

...

ifeq ($(DEV_CFG_USE_FACTORY_PART),y)
MODULE_SRC_FILES += nvram.c hashmap.c mem.c
else
MODULE_SRC_FILES += eeprom.c 24cxx_eeprom.c
endif

注意:
不能直接在各模块的package//.mk中,直接对TARGET_CFLAGS或TARGET_CONFIGURE_OPTS,这种赋值会直接影响所有模块的编译,例如:

package/dev_cfg/module.mk 增加:
TARGET_CFLAGS += -DK_I2C_ADDR=1

编译其他模块时的CFLAGS也会包含上述设置的信息,虽然没有错误,但不便于管理维护。

buildroot宏

BR2_ROOTFS_OVERLAY

所指的路径将在制作rootfs img前,覆盖target/rootfs下的指定文件

BR2_ROOTFS_POST_BUILD_SCRIPT

制作文件系统img前执行该脚本
1、用于移动rootfs下的文件到其他目录中,例如usrfs中
2、修改文件/目录权限等等

BR2_GLOBAL_PATCH_DIR

在package目录外,指定开源软件包补丁路径
例如:

buildroot.config:
BR2_GLOBAL_PATCH_DIR="$(TOPDIR)/../buildroot_patch/patchs"

ls -l $(TOPDIR)/../buildroot_patch/patchs
drwxrwxr-x 2 ss ss 4096 5  23 16:04 android-tools
drwxrwxr-x 2 ss ss 4096 5  23 16:04 bluez5_utils
drwxrwxr-x 2 ss ss 4096 5  23 16:04 boost
drwxrwxr-x 2 ss ss 4096 5  23 16:04 busybox
drwxrwxr-x 2 ss ss 4096 5  23 16:04 ffmpeg
drwxrwxr-x 2 ss ss 4096 5  23 16:04 madplay
drwxrwxr-x 2 ss ss 4096 5  23 16:04 qt5base
drwxrwxr-x 2 ss ss 4096 5  23 16:04 qt5webkit
drwxrwxr-x 2 ss ss 4096 5  23 16:04 squashfs
drwxrwxr-x 2 ss ss 4096 9  14 13:49 tinyalsa

├── boost
   └── fix_pthread_stack_min_compile_error.patch
├── busybox
   └── fix-stime-not-exist.patch
├── ffmpeg
   ├── ffmpeg_alsa_dec_read_method.patch
   ├── ffmpeg_mipsgcc520_build_fix.patch

按上例,只需要在patchs放置和package同名目录,在目录中放入补丁文件即可
编译时,优先打package目录下的补丁

多个补丁文件,打补丁的优先级怎么确定?

应用编译

编译选项

编译时所看到的编译选项,例如CFLAGS, CPPFLAGS,它们是在如下文件中配置的:
buildroor/package/Makefile.in文件中。
如果想增加一些条件编译,可以修改此文件,或者在文件结尾include自己的.mk文件,在该文件中,增加类似如下内容(推荐):

ifeq ($(BR2_STATIC_LIBS),y)
TARGET_CFLAGS += -DOPEN_SS_TEST
endif

编译方式

1、Makefile方式
示例:

define DEV_CFG_BUILD_CMDS
        $(TARGET_CONFIGURE_OPTS) $(MAKE) $(DEV_CFG_CONF_OPTS) -C $(@D)
endef

define DEV_CFG_CLEAN_CMDS
        $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) clean
endef

define DEV_CFG_INSTALL_TARGET_CMDS
        $(TARGET_CONFIGURE_OPTS) $(MAKE) $(DEV_CFG_CONF_OPTS) -C $(@D) install
endef

$(eval $(generic-package))

2、cmake方式

ZLMEDIAKIT_CONF_OPTS = -DENABLE_API_STATIC_LIB=1
$(eval $(cmake-package))

package/module/local.mk
################################################################################
#
# module
#
################################################################################

APP_UTILS_VERSION = 1.0
APP_UTILS_SITE_METHOD = local
APP_UTILS_SITE = $(BR2_EXTERNAL_SDK_APP_PATH)/app_source/app_utils
APP_UTILS_LICENSE = Custom
APP_UTILS_LICENSE_FILES = license.txt
# Installs only a static library and a header file
APP_UTILS_INSTALL_TARGET = YES
APP_UTILS_INSTALL_STAGING = YES

define APP_UTILS_BUILD_CMDS
    $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D)
endef

define APP_UTILS_INSTALL_STAGING_CMDS
    $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) stage
endef

define APP_UTILS_INSTALL_TARGET_CMDS
    $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) install
endef

$(eval $(generic-package))

编译库一般需要把头文件和库提供到staging目录下,提供给其他模块编译时使用。

source/module/Makefile
#CROSS_COMPILE := ## for host debug
CXX ?= $(CROSS_COMPILE)g++
CC ?= $(CROSS_COMPILE)gcc
STRIP ?= $(CROSS_COMPILE)strip
INSTALL ?= install
#
# Dir
#
OBJDIR ?= objs/
HEADR_FILE := include

#
# Compiler flags
#
COMMON_FLAGS := -Wall -fPIC -g -Os -rdynamic -fasynchronous-unwind-tables
CFLAGS := -I$(HEADR_FILE) $(COMMON_FLAGS)

#
# Linker flags
#
LDLIBS := -pthread
LDFLAGS += -shared $(LDLIBS)


#
# c objs, c depends
#
OBJ_c = $(filter %.o, $(patsubst %.c,$(OBJDIR)%.o, $(filter %.c, $(SRC-y))))
DEP_c = $(filter %.d, $(patsubst %.c,$(OBJDIR)%.d, $(filter %.c, $(SRC-y))))
DEPS += $(DEP_c)
OBJS += $(OBJ_c)

#
# cc objs, cc depends
#
OBJ_cc  = $(filter %.o, $(patsubst %.cc,$(OBJDIR)%.o, $(filter %.cc, $(SRC-y))))
DEP_cc = $(filter %.d, $(patsubst %.cc,$(OBJDIR)%.d, $(filter %.cc, $(SRC-y))))
OBJS += $(OBJ_cc)
DEPS += $(DEP_cc)

#
# cpp objs, cpp depends
#
OBJ_cpp += $(filter %.o, $(patsubst %.cpp,$(OBJDIR)%.o, $(filter %.cpp, $(SRC-y))))
DEP_cpp += $(filter %.d, $(patsubst %.cpp,$(OBJDIR)%.d, $(filter %.cpp, $(SRC-y))))
OBJS += $(OBJ_cpp)
DEPS += $(DEP_cpp)

#####################################################################
# Sources
######################################################################
SRC-y += common.c

TARGET := libutils.so

all: clean $(TARGET)

$(TARGET) : $(OBJS)
    @echo $(MSG_LD) $@
    $(CC) $(LDFLAGS) $(OBJ_c) -o $@
    $(STRIP) --strip-unneeded $@

install:
    libtool --mode=install $(INSTALL) -c $(TARGET) $(TARGET_DIR)/lib

stage:
    libtool --mode=install $(INSTALL) -D -m 644 $(HEADR_FILE)/*.h $(STAGING_DIR)/usr/include
    libtool --mode=install $(INSTALL) -D -m 644 $(TARGET) $(STAGING_DIR)/usr/lib
#
# make .c
#
$(OBJ_c): $(OBJDIR)%.o : %.c
    @mkdir -p $(dir $@)
    @echo $(MSG_CC) $<
    $(CC) -c $(CFLAGS) $< -o $@

$(DEP_c): $(OBJDIR)%.d:%.c
    @mkdir -p $(dir $@);
    $(CC) -MM $(CFLAGS) -MT $(@:%.d=%.o) $< >$@

#
# make .cc
#
$(OBJ_cc): $(OBJDIR)%.o : %.cc
    @mkdir -p $(dir $@)
    @echo $(MSG_CC) $<
    $(CC) -c $(CCFLAGS) $< -o $@

$(DEP_cc): $(OBJDIR)%.d:%.cc
    @mkdir -p $(dir $@)
    $(CC) -MM $(CCFLAGS) -MT $(@:%.d=%.o) $< >$@

#
# make .cpp
#
$(OBJ_cpp): $(OBJDIR)%.o : %.cpp
    @mkdir -p $(dir $@)
    @echo $(MSG_CC) $<
    $(CC) -c $(CCFLAGS) $< -o $@

$(DEP_cpp): $(OBJDIR)%.d:%.cpp
    @mkdir -p $(dir $@)
    $(CC) -MM $(CCFLAGS) -MT $(@:%.d=%.o) $< >$@


sinclude $(DEPS)

clean:
    @rm -f $(DEP_c)
    @rm -f $(OBJ_c)

distclean:clean

.PHONY: all install stage clean distclean

该Makefile编译出的动态库,即使代码中include了不存在的文件,也可以正常编译。
目前无解,在开发库代码时,就写main接口,做测试用,并去掉-shared。可最大程度避免问题发生。

app

package/module/local.mk
################################################################################
#
# module
#
################################################################################

APP_BIND_VERSION = 1.0
APP_BIND_SITE_METHOD = local
APP_BIND_SITE = $(BR2_EXTERNAL_SDK_APP_PATH)/app_source/app_bind
APP_BIND_DEPENDENCIES = app_utils
APP_BIND_LICENSE = Custom
APP_BIND_LICENSE_FILES = license.txt
# Installs only a static library and a header file
APP_BIND_INSTALL_TARGET = YES

define APP_BIND_BUILD_CMDS
    $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D)
endef

define APP_BIND_INSTALL_TARGET_CMDS
    $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) install
endef

$(eval $(generic-package))

注意:
APP_BIND_DEPENDENCIES指定了编译APP_BIND前需要编译APP_UTILS,内容是,以BR2_PACKAGE_APP_UTILS为例,取它的后缀的小写,即app_utils

特别要和Config.in中的depends on或select区分开,Config.in中的时表示依赖的项is not set时,本模块不执行编译,而不是说编译本模块前需要先编译依赖的模块

source/module/Makefile
#CROSS_COMPILE := ## for host debug
CXX ?= $(CROSS_COMPILE)g++
CC ?= $(CROSS_COMPILE)gcc
STRIP ?= $(CROSS_COMPILE)strip
INSTALL ?= install
#
# Dir
#
OBJDIR ?= objs/
HEADR_FILE := 

#
# Compiler flags
#
COMMON_FLAGS := -Wall -fPIC -g -Os
CFLAGS := $(COMMON_FLAGS)

#
# Linker flags
#
LDLIBS := -pthread -lutils
LDFLAGS += -shared $(LDLIBS)

#
# c objs, c depends
#
OBJ_c = $(filter %.o, $(patsubst %.c,$(OBJDIR)%.o, $(filter %.c, $(SRC-y))))
DEP_c = $(filter %.d, $(patsubst %.c,$(OBJDIR)%.d, $(filter %.c, $(SRC-y))))
DEPS += $(DEP_c)
OBJS += $(OBJ_c)

#
# cc objs, cc depends
#
OBJ_cc  = $(filter %.o, $(patsubst %.cc,$(OBJDIR)%.o, $(filter %.cc, $(SRC-y))))
DEP_cc = $(filter %.d, $(patsubst %.cc,$(OBJDIR)%.d, $(filter %.cc, $(SRC-y))))
OBJS += $(OBJ_cc)
DEPS += $(DEP_cc)

#
# cpp objs, cpp depends
#
OBJ_cpp += $(filter %.o, $(patsubst %.cpp,$(OBJDIR)%.o, $(filter %.cpp, $(SRC-y))))
DEP_cpp += $(filter %.d, $(patsubst %.cpp,$(OBJDIR)%.d, $(filter %.cpp, $(SRC-y))))
OBJS += $(OBJ_cpp)
DEPS += $(DEP_cpp)

#####################################################################
# Sources
######################################################################
SRC-y += main.c

TARGET := app_bind

all: clean $(TARGET)

$(TARGET) : $(OBJS)
    @echo $(MSG_LD) $@
    $(CC) $(LDFLAGS) $(OBJ_c) -o $@
    $(STRIP) --strip-unneeded $@

install:
    libtool --mode=install $(INSTALL) -c $(TARGET) $(TARGET_DIR)/bin

#
# make .c
#
$(OBJ_c): $(OBJDIR)%.o : %.c
    @mkdir -p $(dir $@)
    @echo $(MSG_CC) $<
    $(CC) -c $(CFLAGS) $< -o $@

$(DEP_c): $(OBJDIR)%.d:%.c
    @mkdir -p $(dir $@);
    $(CC) -MM $(CFLAGS) -MT $(@:%.d=%.o) $< >$@

#
# make .cc
#
$(OBJ_cc): $(OBJDIR)%.o : %.cc
    @mkdir -p $(dir $@)
    @echo $(MSG_CC) $<
    $(CC) -c $(CCFLAGS) $< -o $@

$(DEP_cc): $(OBJDIR)%.d:%.cc
    @mkdir -p $(dir $@)
    $(CC) -MM $(CCFLAGS) -MT $(@:%.d=%.o) $< >$@

#
# make .cpp
#
$(OBJ_cpp): $(OBJDIR)%.o : %.cpp
    @mkdir -p $(dir $@)
    @echo $(MSG_CC) $<
    $(CC) -c $(CCFLAGS) $< -o $@

$(DEP_cpp): $(OBJDIR)%.d:%.cpp
    @mkdir -p $(dir $@)
    $(CC) -MM $(CCFLAGS) -MT $(@:%.d=%.o) $< >$@


sinclude $(DEPS)

clean:
    @rm -f $(DEP_c)
    @rm -f $(OBJ_c)

distclean:clean

.PHONY: all install clean distclean

kernel

目的,使用外部的kernel源码进行编译。
kernel配置文件放在外部。
主要包括:
1、修改buildroot中kernel相关的配置项
2、开始进入buildroot编译前,将kernel源码拷贝到dl目录下

源码以压缩包+patch形式维护

buildroot.conf中kernel相关的配置如下:

#
# Kernel
#
BR2_LINUX_KERNEL=y
# BR2_LINUX_KERNEL_LATEST_VERSION is not set
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
# BR2_LINUX_KERNEL_CUSTOM_TARBALL is not set
# BR2_LINUX_KERNEL_CUSTOM_GIT is not set
# BR2_LINUX_KERNEL_CUSTOM_HG is not set
# BR2_LINUX_KERNEL_CUSTOM_SVN is not set
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="linux"
BR2_LINUX_KERNEL_VERSION="3.10.14"
BR2_LINUX_KERNEL_PATCH="n"
# BR2_LINUX_KERNEL_USE_DEFCONFIG is not set
# BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG is not set
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="../../my_gateway_platform/configs/kernel.config"
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES=""
BR2_LINUX_KERNEL_UBOOT_IMAGE=y
BR2_LINUX_KERNEL_UIMAGE=y
# BR2_LINUX_KERNEL_VMLINUX_BIN is not set
# BR2_LINUX_KERNEL_VMLINUX is not set
# BR2_LINUX_KERNEL_VMLINUZ is not set
# BR2_LINUX_KERNEL_VMLINUZ_BIN is not set
# BR2_LINUX_KERNEL_IMAGE_TARGET_CUSTOM is not set
# BR2_LINUX_KERNEL_GZIP is not set
# BR2_LINUX_KERNEL_LZ4 is not set
# BR2_LINUX_KERNEL_LZMA is not set
# BR2_LINUX_KERNEL_LZO is not set
BR2_LINUX_KERNEL_XZ=y
# BR2_LINUX_KERNEL_DTS_SUPPORT is not set
# BR2_LINUX_KERNEL_USE_INTREE_DTS is not set
# BR2_LINUX_KERNEL_USE_CUSTOM_DTS is not set
BR2_LINUX_KERNEL_INTREE_DTS_NAME=""
# BR2_LINUX_KERNEL_INSTALL_TARGET is not set

其中:
BR2_LINUX_KERNEL:决定是否编译kernel
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE:指定外部配置文件路径
BR2_LINUX_KERNEL_UIMAGE:编译出uImage
BR2_LINUX_KERNEL_VERSION: 必须指定kernel版本号
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE:该值-版本号就是dl下kernel源码包的名字,buildroot根据这个名字去dl下找源码包,并解压编译。
BR2_LINUX_KERNEL_XZ: kernel源码包的压缩格式

实际使用过程:
kernel源码包和patch放在platform目录下,整体编译时,将kernel源码包拷贝到dl目录下即可。

源码以目录文件形式维护

# Kernel
#
# BR2_LINUX_KERNEL is not set
# BR2_LINUX_KERNEL_LATEST_VERSION is not set
# BR2_LINUX_KERNEL_LATEST_CIP_VERSION is not set
# BR2_LINUX_KERNEL_LATEST_CIP_RT_VERSION is not set
# BR2_LINUX_KERNEL_CUSTOM_VERSION is not set
# BR2_LINUX_KERNEL_CUSTOM_TARBALL is not set
# BR2_LINUX_KERNEL_CUSTOM_GIT is not set
# BR2_LINUX_KERNEL_CUSTOM_HG is not set
# BR2_LINUX_KERNEL_CUSTOM_SVN is not set
# BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE is not set
# BR2_LINUX_KERNEL_VERSION is not set
# BR2_LINUX_KERNEL_PATCH is not set
# BR2_LINUX_KERNEL_USE_DEFCONFIG is not set
# BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG is not set
# BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG is not set
# BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE is not set
# BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES is not set
# BR2_LINUX_KERNEL_CUSTOM_LOGO_PATH is not set
# BR2_LINUX_KERNEL_UIMAGE is not set
# BR2_LINUX_KERNEL_VMLINUX_BIN is not set
# BR2_LINUX_KERNEL_VMLINUX is not set
# BR2_LINUX_KERNEL_VMLINUZ is not set
# BR2_LINUX_KERNEL_VMLINUZ_BIN is not set
# BR2_LINUX_KERNEL_IMAGE_TARGET_CUSTOM is not set
# BR2_LINUX_KERNEL_GZIP is not set
# BR2_LINUX_KERNEL_LZ4 is not set
# BR2_LINUX_KERNEL_LZMA is not set
# BR2_LINUX_KERNEL_LZO is not set
# BR2_LINUX_KERNEL_XZ is not set
# BR2_LINUX_KERNEL_ZSTD is not set
# BR2_LINUX_KERNEL_DTS_SUPPORT is not set
# BR2_LINUX_KERNEL_INSTALL_TARGET is not set
# BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL is not set
# BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF is not set
# BR2_LINUX_KERNEL_NEEDS_HOST_PAHOLE is not set

BR2_LINUX_KERNEL_CUSTOM_LOCAL=y
BR2_LINUX_KERNEL_CUSTOM_LOCAL_LOCATION="$(TOPDIR)/../kernel"

修改编译规则

kernel的编译规则在buildroot/linux/linux.mk文件中指定

注意

kereel有修改时,通过buildroot重编kernel后,如果不想整编的话,要把targets/lib/modules/下的其他kernel模块相关文件夹删掉,并且在烧写kernel时要同时烧写rootfs

uboot

在此添加buildroot中和uboot编译相关的内容

rootfs

重要配置项

BR2_TARGET_GENERIC_HOSTNAME:将影响/etc/hostname的内容,以及终端root@hostname的显示
BR2_TARGET_ROOTFS_XXXX:指定文件系统类型, 例如BR2_TARGET_ROOTFS_JFFS2、BR2_TARGET_ROOTFS_EXT2
BR2_ROOTFS_OVERLAY:rootfs overlay,指定的该目录存放自己定制的rootfs,在buildroot制作完rootfs后,将拷贝overlay目录替换output下的部分文件。

时区

  • 如果有BR2_PACKAGE_TZDATA=y时

    时区通过/etc/localtime标识
    此外:
    env中不能有TZ成员,否则localtime将无法生效
    

    切换时区:

    在post脚本中写入:
    ln -sf ../usr/share/zoneinfo/America/New_York localtime
    echo "America/New_York" > /etc/timezone
    

    其中timezone文件影响jdk中的时间显示

  • 如果没有tzdata时
    通过在profile中增加TZ成员设置时区

    export TZ=CST-8
    

工具链

目的:使用外部的已经制作好的交叉编译工具链。

单编toochain

rm -rf output/build/toolchain-external;make toolchain-external;

buildroot配置

#
# Toolchain
#
BR2_TOOLCHAIN=y
BR2_TOOLCHAIN_USES_GLIBC=y
# BR2_TOOLCHAIN_BUILDROOT is not set
BR2_TOOLCHAIN_EXTERNAL=y

#
# Toolchain External Options
#
# BR2_TOOLCHAIN_EXTERNAL_CODESOURCERY_MIPS is not set
# BR2_TOOLCHAIN_EXTERNAL_CODESCAPE_MTI_MIPS is not set
# BR2_TOOLCHAIN_EXTERNAL_MUSL_CROSS is not set
BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
# BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD is not set
BR2_TOOLCHAIN_EXTERNAL_PREINSTALLED=y
BR2_TOOLCHAIN_EXTERNAL_PATH="$(TOPDIR)/../prebuilts/toolchains/mips-gcc520-glibc222"
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="mips-linux-gnu"
BR2_TOOLCHAIN_EXTERNAL_PREFIX="mips-linux-gnu"
BR2_TOOLCHAIN_EXTERNAL_GLIBC=y
# BR2_TOOLCHAIN_EXTERNAL_GCC_6 is not set
BR2_TOOLCHAIN_EXTERNAL_GCC_5=y
# BR2_TOOLCHAIN_EXTERNAL_GCC_4_9 is not set
# BR2_TOOLCHAIN_EXTERNAL_GCC_4_8 is not set
# BR2_TOOLCHAIN_EXTERNAL_GCC_4_7 is not set
# BR2_TOOLCHAIN_EXTERNAL_GCC_4_6 is not set
# BR2_TOOLCHAIN_EXTERNAL_GCC_4_5 is not set
# BR2_TOOLCHAIN_EXTERNAL_GCC_4_4 is not set
# BR2_TOOLCHAIN_EXTERNAL_GCC_4_3 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_8 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_7 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_6 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_5 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_4 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_3 is not set
BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_2=y
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_1 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_0 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_19 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_18 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_17 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_16 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_15 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_14 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_13 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_12 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_11 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_10 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_9 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_8 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_7 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_6 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_5 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_4 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_3 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_2 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_1 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_0 is not set
# BR2_TOOLCHAIN_EXTERNAL_HEADERS_REALLY_OLD is not set
# BR2_TOOLCHAIN_EXTERNAL_CUSTOM_UCLIBC is not set
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
# BR2_TOOLCHAIN_EXTERNAL_CUSTOM_MUSL is not set
BR2_TOOLCHAIN_EXTERNAL_HAS_SSP=y
BR2_TOOLCHAIN_EXTERNAL_INET_RPC=y
BR2_TOOLCHAIN_EXTERNAL_CXX=y
# BR2_TOOLCHAIN_EXTERNAL_FORTRAN is not set
BR2_TOOLCHAIN_EXTRA_EXTERNAL_LIBS=""
# BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY is not set

注意:
BR2_TOOLCHAIN_EXTERNAL_GCC_5:gcc版本号5开头
BR2_TOOLCHAIN_EXTERNAL_HAS_SSP:堆栈粉碎保护(Stack Smashing Protection)
BR2_TOOLCHAIN_EXTERNAL_INET_RPC:是否支持RPC,远程过程调用,主要用于NFS
BR2_TOOLCHAIN_EXTERNAL_PATH:指定交叉编译链路径
BR2_TOOLCHAIN_HEADERS_AT_LEAST指定的版本要和交叉编译工具链的version.h中的一致,例如

version.h:
#define LINUX_VERSION_CODE 262656
LINUX_VERSION_CODE >> 16 => 主版本号4
LINUX_VERSION_CODE >> 8 => 次版本号2

配置文件对应做如下配置:
BR2_TOOLCHAIN_HEADERS_AT_LEAST_4_2=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST="4.2"

使能BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_2

BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_2=y

其他问题

整编后没有output/images下没有文件

具体log具体分析,一般是由于系统没有安装mkimage工具导致的:
sudo apt-get install u-boot-tools -y

Incorrect selection of kernel headers: expected 3.10.x, got 4.2.x

使用外部交叉编译工具链,在整编时,在编译交叉工具链阶段出现上述error log
原因:
配置文件中的kernel header版本,和交叉编译工具链的version.h不一致导致,具体可看toolchain/toolchain-external/toolchain-external-custom/Config.in.options,中关于LINUX_VERSION_CODE的说明。
解决:
配置文件中:
1、BR2_TOOLCHAIN_HEADERS_AT_LEAST指定的版本要和交叉编译工具链的version.h中的一致

BR2_TOOLCHAIN_HEADERS_AT_LEAST_4_2=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST="4.2"

2、使能BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_2

BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_2=y

单编报LINUX_SIZE为空错误

指buildroot整体编译后,通过buildroot/Makefile编译某个模块(app、uboot、kernel)。

该错误是,每次整编后,make show-targets时报该异常:
这种情况发生在使用自己的.config,来替换buildroot下的.config的情况。
每次单编,需要重新拷贝自己的.config到buildroot目录下的.config文件。
解决:
修改buildroot/Makefile:
分别在_all目标和all目标下添加如下:

_all:
    @cp -rf $(CURDIR)/../../gateway_platform/configs/buildroot.config $(CURDIR)/.config

all:

# add
ifeq ($(BR2_EXTERNAL),)
BR2_EXTERNAL=$(CURDIR)/../
endif

每次单编,例如make sstest之后,.config变成自动生成的,而不是我们指定的config文件
原因:单编时先执行了silentoldconfig,编译生成了.config:

原:
$(BUILD_DIR)/buildroot-config/auto.conf: $(BR2_CONFIG)
    $(MAKE1) $(EXTRAMAKEARGS) HOSTCC="$(HOSTCC_NOCCACHE)" HOSTCXX="$(HOSTCXX_NOCCACHE)" silentoldconfig
改:
$(BUILD_DIR)/buildroot-config/auto.conf: $(BR2_CONFIG)
    @cp -rf $(CURDIR)/../../gateway_platform/configs/buildroot.config $(CURDIR)/.config
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
阿帅
红包 5 2 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
阿帅
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区