上面一小节我们介绍了uboot的启动流程,里面最终走到了查看extlinx文件,并根据此文件来选择后续的启动镜像、设备树和内核参数。本章节详细分析一下extlinux相关的内容。首先我们看下ST官方的开发板uboot启动时使用的extlinux.conf文件长什么样:
粗看上面的配置可以盲猜里面内容的意思:
MENU: 从配置可以看到是一张bmp的照片,应该是进入此阶段选择的splansh图片
TIMEOUT: 选择超时配置
DEFAULT: 默认启动的目标选项,应该是下面LABEL中的一种
LABEL: 一个启动项,每一个LABLE下面有三个子配置
KERNEL: 该启动项选择的DTB文件
INITRD: 该启动项支持的ramdisk
APPEND:该启动项传递的内核参数
下面我们详细分析一下ST官方是怎么生成上面这个配置文件的,涉及到的相关文件如下:
conf/machine/include/st-machine-extlinux-config-stm32mp.inc
conf/machine/stm32mp15-robot.conf
class/extlinuxconf-stm32mp.bbclass
recipes-bsp/u-boot/u-boot-stm32mp-extlinux.bb
这些文件的大致关系如图所示:
其中st-machine-extlinux-config-stm32mp.inc里面填充了非常多EXTLINUX相关的配置项目,然后stm32mp15-robot.conf这个machine的配置文件会引用st-machine-extlinux-config-stm32mp.inc同时部分配置项目可能会覆写,这些配置会最终控制配置文件里面的具体内容;extlinuxconf-stm32mp.bbclass里面提供了一个task 叫do_create_multiextlinux_config,里面会根据配置项目来生成extlinux的实际conf文件,u-boot-stm32mp-extlinux.bb引用了extlinuxconf-stm32mp.bbclass并且完善整个生成配置文件、编译和安装等工作,这就是大概完整的流程图。
下面的重点就是看一下do_create_multiextlinux_config里面具体是怎么根据一系列的配置来生成具体的extlinux.conf文件了。
从最后看可以知道create_multiextlinux_config task是在compile之前运行。
addtask create_multiextlinux_config before do_compile
下面是 do_create_multiextlinux_config的主体内容,部分删减
python do_create_multiextlinux_config() {
targets = d.getVar('UBOOT_EXTLINUX_TARGETS')
# Need to deconflict the targets with existing overrides
target_overrides = targets.split()
default_overrides = d.getVar('OVERRIDES').split(':')
# We're keeping all the existing overrides that aren't used as a target
# an override for that target will be added back in while we're processing that target
keep_overrides = list(filter(lambda x: x not in target_overrides, default_overrides))
# Init FIT parameter
fit_config = d.getVar('UBOOT_EXTLINUX_FIT')
for target in targets.split():
bb.note("Loop for '%s' target" % target)
# Append target as OVERRIDES
d.setVar('OVERRIDES', ':'.join(keep_overrides + [target]))
# Initialize labels
labels = d.getVar('UBOOT_EXTLINUX_LABELS')
if not labels:
bb.fatal("UBOOT_EXTLINUX_LABELS not defined, nothing to do")
if not labels.strip():
bb.fatal("No labels, nothing to do")
# Initialize extra target configs
extra_extlinuxtargetconfig = d.getVar('UBOOT_EXTLINUX_TARGETS_EXTRA_CONFIG') or ""
# Initialize subdir for config file location
if len(targets.split()) > 1 or len(extra_extlinuxtargetconfig.split()) > 0:
bootprefix = d.getVar('UBOOT_EXTLINUX_BOOTPREFIXES') or ""
subdir = bootprefix + 'extlinux'
else:
subdir = 'extlinux'
# Initialize config file
cfile = os.path.join(d.getVar('B'), subdir , 'extlinux.conf')
# Create extlinux folder
bb.utils.mkdirhier(os.path.dirname(cfile))
# Standard extlinux file creation
if fit_config == '1':
bb.note("UBOOT_EXTLINUX_FIT set to '1'. Skip standard extlinux file creation")
else:
bb.note("Create %s/extlinux.conf file for %s labels" % (subdir, labels))
create_extlinux_file(cfile, labels, d)
# Manage UBOOT_EXTLINUX_TARGETS_EXTRA_CONFIG
extra_extlinuxtargetconfigflag = d.getVarFlags('UBOOT_EXTLINUX_TARGETS_EXTRA_CONFIG')
# The "doc" varflag is special, we don't want to see it here
extra_extlinuxtargetconfigflag.pop('doc', None)
# Handle new targets and labels append
if len(extra_extlinuxtargetconfig.split()) > 0:
bb.note("Manage EXTRA target configuration:")
for config in extra_extlinuxtargetconfig.split():
# Init extra config vars:
extra_extlinuxlabels = ""
extra_cfile = ""
# Specific case for 'fit' to automate configuration with device tree name
if fit_config == '1':
# Override current 'labels' with 'config' from UBOOT_EXTLINUX_TARGETS_EXTRA_CONFIG
# Under such configuration, UBOOT_EXTLINUX_TARGETS_EXTRA_CONFIG should contain the
# list of supported device tree file (without '.dtb' suffix) to allow proper extlinux
# file creation for each device tree file.
bb.note(">>> Override default init to allow default extlinux file creation with %s config as extra label." % config)
labels = config
# Update extra config vars for this specific case:
extra_extlinuxlabels = labels
extra_cfile = os.path.join(d.getVar('B'), subdir , config + '_' + 'extlinux.conf')
# Configure dynamically the default menu configuration if there is no specific one configured
if d.getVar('UBOOT_EXTLINUX_DEFAULT_LABEL_%s' % config):
bb.warn(">>> Specific configuration for UBOOT_EXTLINUX_DEFAULT_LABEL var detected for %s label: %s" % (config, d.getVar('UBOOT_EXTLINUX_DEFAULT_LABEL_%s' % config)))
else:
bb.warn(">>> Set UBOOT_EXTLINUX_DEFAULT_LABEL to %s" % config)
d.setVar('UBOOT_EXTLINUX_DEFAULT_LABEL', config)
# Append extra configuration if any
for f, v in extra_extlinuxtargetconfigflag.items():
if config == f:
bb.note(">>> Loop for '%s' extra target config." % config)
if len(v.split()) > 0:
bb.note(">>> Set '%s' to extra_extlinuxlabels." % v)
extra_extlinuxlabels = labels + ' ' + v
extra_cfile = os.path.join(d.getVar('B'), subdir , config + '_' + 'extlinux.conf')
else:
bb.note(">>> No extra labels defined, no new config file to create")
break
# Manage new config file creation
if extra_extlinuxlabels != "":
socname_list = d.getVar('STM32MP_SOC_NAME')
if socname_list and len(socname_list.split()) > 0:
for soc in socname_list.split():
if config.find(soc) > -1:
if d.getVar('UBOOT_EXTLINUX_SPLASH_%s' % soc):
splash = d.getVar('UBOOT_EXTLINUX_SPLASH_%s' % soc)
bb.note(">>> Specific configuration for SPLASH Screen detected with configuration: %s" % config)
bb.note(">>> Set UBOOT_EXTLINUX_SPLASH to %s" % splash)
d.setVar('UBOOT_EXTLINUX_SPLASH', splash)
bb.note(">>> Create %s/%s_extlinux.conf file for %s labels" % (subdir, config, extra_extlinuxlabels))
create_extlinux_file(extra_cfile, extra_extlinuxlabels, d)
}
上面主要就是就跟环境变量来生成,我修改的stm32mp15-robot.conf和extlinux相关的配置如下:
UBOOT_SPLASH_TTROBOT_IMAGE ?= “splash_ttrobot”
UBOOT_EXTLINUX_SPLASH_stm32mp15 = “KaTeX parse error: Expected 'EOF', got '#' at position 31: …TROBOT_IMAGE}" #̲UBOOT_EXTLINUX_…{STM32MP_DT_FILES_ROBOT}”