当前位置: 首页 > news >正文

【uboot/kernel1】启动流程,环境变量,内存,initramfs

文章目录

  • 1.启动流程
  • 2.环境变量
    • 2.1 bootcmd
    • 2.2 EMMC和SD卡操作
  • 3.内存压测
  • 4.initramfs


1.启动流程

在这里插入图片描述

# recipes-bsp/u-boot/u-boot-bird_2020.04.bb: 引用了u-boot-common.inc, 如下变量重新赋值
LICENSE = "GPLv2+"
LIC_FILES_CHKSUM = "file://Licenses/gpl-2.0.txt;md5=b234ee4d69f5fce4486a80fdaf4a4263"
SRCBRANCH = "master"
UBOOT_SRC ?= "git:////${BSPDIR}/bird-imx-uboot;protocol=file"  # 指向本地fsl-release-yocto/bird-imx-uboot路径
SRC_URI = "${UBOOT_SRC};branch=${SRCBRANCH}"
SRCREV = "${AUTOREV}"  # 通过bird-imx-uboot下使用git log查看(commit id),也可这一行使用代码分支下的最新版本

最终会调用arch/arm/lib/crt0.S文件中的_main函数:调用board_init_f()调用nitcall_run_list(init_sequence_f),只要init_sequence_f所定义的其中一个函数(如display_options、display_text_info、print_cpuinfo、show_board_info等用于在U-Boot启动时输出一些启动信息至控制台)出错,U-Boot启动就会停止。

board_init_f中并没有初始化完所有的外设,还需要通过board_init_r(同样调用initcall_run_list执行初始化序列init_sequence_r)来完成,board_init_r函数的最后会调用run_main_loop函数(会进入一个main_loop死循环,在main_loop函数里会根据是否按下回车键进入uboot命令模式,还是在倒计时结束之后,通过执行环境变量bootcmd启动Linux内核。

U-Boot的环境变量是用来存常用的参数变量,U-Boot会使用这些参数变量进行配置。启动过程中将env从静态存储器中读出放到RAM中,之后在U-Boot下对env的操作(如printenv、editenv、setenv)都是对RAM中env的操作,只有在执行saveenv时才会将RAM中的env重新写入静态存储器(nand flash、nor flash、eeprom、mmc)。

2.环境变量

2.1 bootcmd

// mx6ullevk.h,将Linux内核从flash(sf命令)或网络(nfs,tftp)拷贝到DDR,一旦内核镜像和设备树文件加载完成,U-Boot启动内核并将bootargs传给内核。
#define CONFIG_BOOTCOMMAND  // 保存bootcmd的默认值// 如下从emmc中启动: 网络启动同理fatload mmc 1:1换成tftp
mmc dev 1  //切换到EMMC
fatload mmc 1:1(设备号:分区号) 0x80800000 zImage   //读取zImage到0x80800000处
fatload mmc 1:1 0x83000000 *dtb //读取设备树到0x83000000处
bootz 0x80800000 - 0x83000000   //启动Linux内核 // md.b 80000000 14 : 0X80000000(内存地址)开始,20的十六进制0x14(uboot命令中的数字都是十六进制),.b表示20个字节,.w表示20个word,[.b .w .l]对应byte/word/long
# fdtspiaddr和loadaddr变量已知:
bootspi=fdt addr ${fdtspiaddr} &&                   # 设置SPI Flash中FIT镜像的地址 fdt spi addrfdt header get fitsize totalsize &&         # 从FIT头部读取镜像大小,保存到变量fitsizecp.b ${fdtspiaddr} ${loadaddr} ${fitsize} && # 将SPI Flash中的FIT镜像拷贝到内存地址bootm ${loadaddr};                          # 启动内核echo Error loading kernel FIT image          # 失败提示# linux内核源码编译成vmlinux(elf格式),通过objcopy(GNU Binutils)删除符号和重定位信息等,变成Image(二进制格式),再通过gzip和objcopy变成ZImage
# UImage是ZImage加上64字节头信息(uboot启动kernel时用到字节头如压缩类型等)

在这里插入图片描述

# 在uboot中通过tftp更新BMC:如下在30服务器:
# sudo apt-get install tftp-hpa tftpd-hpa
# 修改/etc/default/tftpd-hpa, service tftpd-hpa restart
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/mnt/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"
# cp by/build/tmp/deploy/images/hp/fit-hp.itb /mnt/tftp 【.itb=.fit,参考【openbmc2】】
# 如下在开发板:
dhcp # 没tftp serverip错误
setenv serverip ....30 # setenv a 清空环境变量a
saveenv
tftpboot 0x83000000 fit-hp.itb  # go 8300000表示执行fit-hp.itb
bootm或boot

2.2 EMMC和SD卡操作

1.mmc info:输出当前选中的设备信息,?mmc即可查看mmc有关的命令。
在这里插入图片描述
2.mmc rescan:用于扫描当前开发板上所有的MMC设备,包括EMMC和SD卡。
3.mmc list:用于来查看当前开发板一共有几个MMC设备。 0是SD卡,1是EMMC。
4.mmc dev 1:切换到EMMC。
5.mmc part:查看分区(此时EMMC有两个分区),如果EMMC里面烧写了Linux系统的话,第0个分区存放uboot,第1个分区存放Linux镜像文件和设备树,第2个分区存放根文件系统。但是在下图中只有两个分区,那是因为第0个分区没有格式化,所以识别不出来,实际上第0个分区是存在的。一个新的SD卡默认只有一个分区,那就是分区0。
在这里插入图片描述
6.mmc read addr blk cnt:读取mmc设备数据到内存:addr是数据读取到DRAM中的地址, blk是要读取的块起始地址(十六进制),一个块(块和扇区是一个意思,MMC设备中通常说扇区)是512字节,cnt是要读取的块数量(十六进制)。
在这里插入图片描述
7.mmc write addr blk cnt:读取内存写到mmc设备里:在uboot中更新uboot:这里要用到nfs或tftp命令将新的u-boot.bin下载到开发板的DRAM中【tftp/tftpboot 80800000 u-boot.imx,重新编译uboot并将编译出来的u-boot.imx (u-boot.bin前面加了一些头文件) 拷贝到 Ubuntu 中的tftpboot 目录下】,u-boot.imx大小为379904字节, 379904/512=742,所以我们要向SD卡中写入742个块,如果有小数的话就要加1个块。从SD卡分区0(如下第一行)第2个扇区开始烧写(不要写SD卡或者EMMC的前2个扇区,因为里面保存着分区表),一共烧写742(0x2E6)个块。烧写成功后重启开发板(从SD卡启动)再输入version查版本号。
在这里插入图片描述

3.内存压测

CONFIG_CMD_MEMTEST ,dts memory节点,大块内存检测
89400000 - 83000000 = 6400000(十进制104857600 约 100M)。uboot console的mtest命令的开始地址从83000000往后都可以(因为0x80000000-0x83000000存的是uboot自己,uboot console还没load kernel进ram,boot命令才会load kernel到83000000)。
在这里插入图片描述
开启内存ECC:bit位内存检测。
在这里插入图片描述
如下读取寄存器的bit7,uboot不用map物理地址到虚拟地址,kernel才需要。
在这里插入图片描述

#define SDMC_CONFIG_ECC_STATUS_GET(x)    ((x) & BIT(7))  // 取出x的第7bit

如下0x1e6e 0000基地址,04h寄存器的bit7。
在这里插入图片描述
如下2个相同。
在这里插入图片描述
如下dev_read_bool底层调用of_find_property()方法匹配设备属性(dts或驱动中写如下字符串)。
在这里插入图片描述

# workspace/sources/linux-aspeed/oe-local-files这里临时改defconfig(芯片出厂自带,和lincoln.cfg不一样,内容互补)和lincoln.cfg,最终生成build/ast2700-default/tmp/work/ast2700_default-openbmc-linux/u-boot-aspeed-sdk/v2023.10+git/u-boot-aspeed-sdk-v2023.10+git/.config。# 1.添加uboot宏
在conf/machine/xx.conf文件中,通过UBOOT_MACHINE变量定义编译过程中使用的配置文件即xx_defconfig(这文件新增在uboot/configs里,相当于kernel的.cfg,不是.conf),采用make xx_defconfig命令(不是menuconfig)配置U-Boot :在htam_defconfig中定义CONFIG_TARGET_TAM=y。在u-boot/arch/arm/Kconfig文件中新增:config TARGET_TAM ..,source "board/hua/Kconfig",添加u-boot/board/hua文件夹里有`Kconfig文件`(if TARGET_TAM ..,config SYS_BOARD  default "ast-g5"  【配置宏用ast-g5】)和`MAINTAINERS文件`(include/configs/htam.h,configs/htam_defconfig)。# 2.添加uboot硬件平台头文件
mx6ullevk.h(类似htam.h定义的宏给u-boot/board里ast-g5.c或u-boot/driver里aspeednic.c用),某些宏定义在mx6_common.h中,CONFIG_BOOTCOMMAND,CONFIG_NET_RANDOM_ETHADDR(随机分配的ETH MAC Address)。

layout.inc中增大os-fit(64M),kernel解压os-fit区会报错(Initramfs unpacking failed),uboot中用tftp正常启动kernel,uboot/common/image.c中memove(to,from,len)把flash中数据拷贝到内存出错(Loading到Ramdisk),解决如下:单次拷贝最大支持32M。
在这里插入图片描述

4.initramfs

initramfs替代initrd(rd:ram disk基于块设备/dev/initrd即需要内核有文件系统驱动,大小固定,小了导致init脚本放不下),initramfs为了挂载rootfs,参考【openbmc2】。
在这里插入图片描述
如下kernel_init_freeable通过调用prepare_namespace()来挂载根文件系统。根文件系统也是由命令行参数指定即U-Boot的bootargs环境变量。比如“root=/dev/mmcblk1p2 rootwait rw”就表示根文件系统在/dev/mmcblk1p2即EMMC的分区2中。

ramdisk_execute_command是值为“/init”即根目录下的init程序。该值也可通过U-Boot bootargs中用rdinit=xxx,xxx 为具体的init程序名字。如果存在“/init”程序的话就通过函数run_init_process来运行此程序。

如果ramdisk_execute_command为空的话就看execute_command是否为空, execute_command的值是通过U-Boot bootargs中使用init=xxx,如“init=/linuxrc”表示根文件系统中的linuxrc就是要执行的用户空间init程序。

如果上面2个变量都为空,就依次查找“/sbin/init”…这四个相当于备用init程序。如果都没有找到用户空间的init程序,就提示错误发生。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

sf probe(单这命令查看flash型号等) 0:0;  sf erase 0 0x2000000;  sf write   0x$fileaddr  0 0x$filesize;  sf remove;
http://www.lryc.cn/news/596591.html

相关文章:

  • 【数学建模】基础知识
  • 【Verilog】竞争、冒险
  • 本地大模型VRAM需求计算器:原理与实现详解
  • Web3介绍(Web 3.0)(一种基于区块链技术的去中心化互联网范式,旨在通过技术手段实现用户对数据的自主权、隐私保护和价值共享)
  • 浙江大学PTA程序设计C语言基础编程练习题1-5
  • 高并发场景下的缓存问题与一致性解决方案(技术方案总结)
  • Redis 初识
  • Vue项目中的AJAX请求与跨域问题解析
  • Trae安装指定版本的插件
  • 网络编程---TCP协议
  • 浏览器解码顺序xss
  • Matlab学习笔记:界面使用
  • 基础算法思想(递归篇)
  • Linux Bridge Cost
  • Java常用API(1)
  • csp基础知识——递推
  • 激光雷达-自动驾驶的“三维感知中枢“
  • postgresql导入导出数据;pg_restore: error: did not find magic string in file header
  • 学习pwn需要的基本汇编语言知识
  • 快速了解pandas库
  • Unity之C# 脚本与Unity Visual Scripting 交互
  • 嵌入式开发学习(第三阶段 Linux系统开发)
  • Model Control Protocol 使用MCP进行各种任务适配,调用工具和资源进行客户端开发
  • 基于AD7147电容触摸芯片与STC12C5A60S2单片机方案
  • SQL基础④ | 多表查询篇
  • AG32 mcu+cpld 联合编程(概念及流程)
  • OpenMVG OpenMVS 安装全流程常见问题与解决方法总结
  • 学习软件测试的第十九天
  • imx6ull-系统移植篇18——linux顶层 Makefile(下)
  • API是什么,如何保障API安全?