底软驱动 | U-boot移植点点滴滴

u-boot 移植要点

一般厂家直接提供 u-boot 源码,做查看、修改(增加新功能) 或 u-boot 版本升级这三大块的用处;后两种都需要对新板子做适配/移植。

如果没有提供 u-boot 源码,那么就从 u-boot 官方版本中找到一个最相近的板子配置进行移植,这个需要水平较高。

一般把 u-boot 做成对应平台通用的和最小化的,即只保留必要的板级外设初始化代码(如串口、网口和 FLASH 等需要主要做适配,都尽量找能现成使用的),其他更多板级外设初始化在 Linux 移植部分中完成。

如果要深入学习,有以下要点可以参考:

如果芯片公司或者单位提供了移植好的 u-boot,可以用 beyong 软件把移植好的 u-boot 文件夹与 官方原版(版本要一致)进行对比,看一看改动了哪些文件夹和哪些文件,帮助学习。
uboot移植新手入门实践_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili。版本比较新。

  • 韦东山 _ 嵌入式Linux _ 第1期与2期间的衔接课程 _ u-boot编译体验和源码深度分析

  • linux-----uboot和kernel移植 - 灰信网

芯片公司、开发板厂家和用户三者之间的联系:

  • 芯片公司移植的 u-boot 从一开始是基于官方的 u-boot 拿来修改,添加/修改自家的 EVK 评估版的板子型号、相关外设初始化文件,并修改 u-boot 的 Makefile 配置,然后把自家芯片的 EVK 评估版的硬件原理图、u-boot、Linux 和 根文件系统以及使用说明文档等等全部开源,以供下游做应用的公司/厂家和做开发板的公司拿来做修改或直接应用;
  • 做开发板的厂家在拿到了芯片公司提供的芯片评估版 EVK 板子的原理图后,与 SoC 直接相关的比如 PMIC、DDR、FLASH、以太网 PHY 芯片等等不会做大改,一般直接照搬过来画自己的开发板。因为在移植 u-boot 的时候就不用再为新选型的芯片做代码适配,一般没必要做这种费力但效果不大的事情,能直接用的就尽量直接用,能不用改的就尽量不改。然后再拿到芯片公司提供的芯片评估版 EVK 板子对应的 u-boot 源码之后,同样的再添加/修改为自家开发板的型号、添加一点点自己板子的外设初始化代码(这个要求比较高)并修改 Makefile,便得到自家开发板适配的又一个 u-boot;
  • 当用户(比如现在的我)拿到了开发板厂家 或者 芯片公司提供的 u-boot 源码,即所有相关文件和初始化代码都写好了,便可以直接编译进而使用,或者自己再进一步定制化。
  • 作者:thatway1989
  • 链接:https://juejin.cn/post/7385776247600988170

U-boot移植应用开发手册

感兴趣可以看一下这个清华的实验课,讲述了U-Boot的移植过程:https://oscourse-tsinghua.gitbook.io/loongsoncsprj2020-manual/ucore/uboot-yi-zhi-guo-cheng

U-boot移植步骤

参考自**链接**

1. 复制现有板子目录,创建新板子

// 板级目录
xingyanl@yocto:uboot$ cd board/freescale/
// 创建新板子
xingyanl@yocto:uboot$ cp -R mx6sabresd mx6qsensorgw

2. 修改相关文件

2.1 修改Makefile文件
// 修改mx6qsensorgw目录下得到Makefile文件
xingyanl@yocto:mx6qsensorgw$ vi Makefile
xingyanl@yocto:mx6qsensorgw$ cat Makefile
obj-y  := mx6qsensorgw.o  // 更新内容
2.2 重命名.c文件
// 更改板级c文件
xingyanl@yocto:mx6qsensorgw$ cp  mx6sabresd.c  mx6qsensorgw.c
2.3 修改Kconfig文件

a) 修改/board/freescale/mx6qsensorgw目录下的Kconfig

xingyanl@yocto:mx6qsensorgw$ vi Kconfig
xingyanl@yocto:mx6qsensorgw$ cat Kconfig
if TARGET_MX6QSENSORGW  // 新板子名字config SYS_BOARDdefault "mx6qsensorgw"  // 新板子名字config SYS_VENDORdefault "freescale"config SYS_CONFIG_NAMEdefault "mx6qsensorgw"  // 新板子名字endif

b) 修改/arch/arm/cpu/armv7/mx6目录下的Kconfig

// 添加如下内容
xingyanl@yocto:mx6$ vi Kconfig
......
// 添加新板类型
config TARGET_MX6QSENSORGWbool "Support mx6qsensorgw"select BOARD_LATE_INITselect SUPPORT_SPLselect DMselect DM_THERMALselect BOARD_EARLY_INIT_F
......
// source新板子文件Kconfig文件
source "board/freescale/mx6qsensorgw/Kconfig"
......
2.4 更新include/configs/xxx.h文件
xingyanl@yocto:uboot$ cd include/configs
// copy mx6sabresd.h文件
xingyanl@yocto:configs$ cp mx6sabresd.h mx6qsensorgw.h// 修改#include "mx6sabre_common.h"为 #include "mx6qsensorgw_common.h"
xingyanl@yocto:configs$ vi mx6qsensorgw.h
#include "mx6qsensorgw_common.h"// copy mx6sabre_common.h文件
xingyanl@yocto:configs$ cp mx6sabre_common.h mx6qsensorgw_common.h// 一些宏定义
CONFIG_LOADADDR         // ZImage内核会load到这个地址引导
CONFIG_SYS_MALLOC_LEN   // Heap内存大小
CONFIG_STACKSIZE        // stack的大小
CONFIG_NR_DRAM_BANKS    // DDR banks的数量
PHYS_SDRAM_SIZE         // DDR的大小,以MB为单位
PHYS_SDRAM             // DDR的物理地址
fdt_file               // 配置宏定义"#define CONFIG_DEFAULT_FDT_FILE <customer>.dtb"// 或者直接修改
"fdt_file=<customer>.dtb"// Config文件对U-Boot很重要,它决定了u-boot.bin的大小,功能和性能

3. 为新板创建配置文件

xingyanl@yocto:uboot$ cd configs/
xingyanl@yocto:configs$ cp mx6qsabresd_defconfig mx6qsensorgw_defconfig
xingyanl@yocto:configs$ vi mx6qsensorgw_defconfig
// 替换TARGET
# CONFIG_TARGET_MX6SABRESD=y  // 删除
CONFIG_TARGET_MX6QSENSORGW=y // 添加// 更新cfg文件目录,和内存相关配置文件
# CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg,MX6Q"
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6qsensorgw/mx6q_4x_mt41j128.cfg,MX6Q"// 更新设备树文件
#CONFIG_DEFAULT_DEVICE_TREE="imx6q-sabresd"
CONFIG_DEFAULT_DEVICE_TREE="imx6q-sensorgw"

4. 为新板子指定设备树文件

// 添加设备树文件
xingyanl@yocto:uboot$ cd arch/arm/dts/
xingyanl@yocto:dts$ cp imx6q-sabresd.dts imx6q-sensorgw.dts

5. 创建u-boot的build脚本

5.1 创建u-boot编译脚本

xingyanl@yocto:uboot$ vi u-boot.sh
#!/bin/bash
export ARCH=arm
# 指定交叉编译器目录---重要
export CROSS_COMPILE=/opt/fsl-imx-x11/4.1.15-2.0.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-
make distclean;
make mx6qsensorgw_defconfig
make                                                                                                            

5.2 编译u-boot

// 添加权限
xingyanl@yocto:uboot$ chmod a+x u-boot.sh// 编译
xingyanl@yocto:uboot$ ./u-boot.sh

适用人员

本文适用于需要使用Uboot的所有人员。

开发环境

Uboot代码编译环境,环境搭建见:快速入门

Siflower开发板测试环境。

相关背景

UBOOT属于bootloader的一种,是用来引导启动系统/内核的。随着客制化的需求越来越多,硬件的差异也越来越多,而不同的硬件需要不同的引导程序,所以就需要适配不同的Uboot,开发对应的Uboot就显得尤为重要。

功能概述

本文介绍了U-boot的结构和使用方法。其中使用方法包括了代码下载,开发,编译,烧录uboot镜像,以及通过uboot更新内核镜像。本文介绍的U-boot包括了uboot-spl和uboot两部分。

U-boot的介绍

SPL

SPL是介于芯片内部rom程序与uboot之间的一个BootLoader,其主要功能为初始化ddr,系统管理器,时钟,以及加载uboot。SPL程序本身需要加载到系统内部ram中运行,是一个轻量级的uboot。
在U-boot开源程序中,本身是包含SPL选项的。Uboot-spl是用Uboot同一套代码,通过CONFIG_SPL_BUILD宏分割编译出的结果。在MPW0和MPW1的测试时,我们采用了Uboot-spl作为Irom与Uboot之间的BootLoader,但FULLMASK版本将芯片内部ram减少到了64KB,不足以同时支持Uboot-spl的rom+ram的需求,因此采用了一份裸机实现的bare_spl。Bare_spl相比于原Uboot-spl更加简单可控,也可以同样实现引导uboot的功能。同时,bare_spl也同时支持mpw0和mpw1芯片,并且减少了存储空间,为flash优化、分区的重新定义提供了支持。
SPL的流程如下(uboot-spl和bare-spl实现主要功能一致):

SPL 流程图
IROM
CPU初始化
板级初始化
DDR初始化
从device读取镜像
校验镜像信息
跳转到uboot
uboot

在bare_spl中,默认支持三种boot device:spi-flash,sd card,emmc。按照spi>sd>emmc的优先级,只要检测到device存在,spl便会自动从其启动。因此如果想要在同时包含spi-flash与sd的板子中,使用sd作为device存放uboot镜像,需要定义SKIP_SPI_FLASH。由于spi与emmc存在复用关系,因此不会同时存在。Uboot-spl需要在编译阶段就指定使用哪一种boot device。而SF19A2890目前仅支持一种boot device:spi-flash,依据读取flash型号决定使用nand falsh还是nor flash。

SPL与uboot相同,引导的镜像需要包含一个uimage的header,其中会包含所引导镜像的类型。因此,SPL不只可以引导uboot,进而启动内核,还可以引导pcba测试程序。

U-boot

Uboot的启动分为两个阶段:stage1和stage2。stage1可以认为是uboot认定的rom阶段,stage2是ram阶段。Stage1向stage2转换的主要标志就是代码段的relocation,即将代码段从“rom”复制到“ram”。
Uboot的流程图如下:

每个stage都有一个主要执行的函数序列,即init_sequence_f和init_sequence_r。由于SPL的存在,uboot的stage1其实并没有什么实质性的功能,整个uboot都是运行在ddr上的。在进入stage2前,uboot会进行一个代码段的重定向,由于uboot本身是位置无关的,因此只需要同时更新堆栈信息,全局变量表等即可,重定向后的代码依旧可以正常执行。按照uboot的思想,这个stage2是运行在ram中的,因此速度要比stage1要快。

init_sequence_r中主要是进行了各个模块驱动的初始化,网络的初始化和一些其他准备工作,比如环境变量的初始化等。在准备结束后,uboot最终会进入一个main_loop,进行控制台的初始化。此时uboot提供了一个3s的倒计时,如果不在时间内从控制台(默认串口)进行输入,则会进入自动启动流程,根据预设的环境变量参数,进行引导启动;如果有输入,就可以停下来进入控制台,与uboot进行交互。此时uboot会根据输入的命令情况进行解析并执行,目前支持的命令如下:

sfa18 # help
?       - alias for 'help'
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm   - boot application image from memory
bootp   - boot image via network using BOOTP/TFTP protocol
bootvx  - Boot vxWorks from an ELF image
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
date    - get/set/reset date & time
dhcp    - boot image via network using DHCP/TFTP protocol
dm      - Driver model low level access
echo    - echo args to console
editenv - edit environment variable
env     - environment handling commands
exit    - exit script
false   - do nothing, unsuccessfully
fdt     - flattened device tree utility commands
go      - start application at address 'addr'
help    - print command description/usage
httpd   - start www server for firmware recovery with [localAddress]iminfo  - print header information for application image
imxtract- extract a part of a multi-image
itest   - return true/false on integer compare
loop    - infinite loop on address range
lzmadec - lzma uncompress a memory region
md      - memory display
mm      - memory modify (auto-incrementing address)
mmc     - MMC sub system
mmcinfo - display MMC info
mw      - memory write (fill)
nm      - memory modify (constant address)
ping    - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv  - set environment variables
sf      - SPI flash sub-system
showvar - print local hushshell variables
sleep   - delay execution for some time
source  - run script from memory
spld    - update spl from device
test    - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
true    - do nothing, successfully
version - print monitor, compiler and linker version

想要增加新的命令,可以通过menuconfig在编译时选择对应的command。如果有新的功能需求,也可以添加自己的命令进去,只需要按照格式在cmd目录下添加相应处理函数并注册即可。
其中有一些常用的命令:boot 可以让uboot继续执行默认命令; reset 可以重启;sf 与 mmc 分别对应spi-flash与mmc的操作命令。Spld 与 httpd 会在后面镜像更新部分详述。
Uboot环境变量可以通过env命令进行查询和设置:

sfa18 # env print -a
baudrate=115200
bootcmd=sf probe 0 33000000;sf read 0x81000000 0xa0000 0xa00000;bootm
bootdelay=2
ethact=sf_eth0
fdtcontroladdr=8fe9d57c
stderr=serial@8300000
stdin=serial@8300000
stdout=serial@8300000Environment size: 219/65532 bytessfa18 # setenv efuse_data aabbccdd
sfa18 # printenv efuse_data 
efuse_data=aabbccdd

通过环境变量可以设置一些如串口波特率,auto boot delay时间等,最终环境变量会保存u-boot-env分区中,因此下次启动也是有效的。
Uboot引导kernel也是通过控制台命令进行的,默认的命令bootcmd保存在default env中,可以在include/configs/sfax8.h中进行配置。目前这个过程分为两步:1.将镜像从boot device中读到ram中。2.引导ram中的镜像。
根据boot device的不同,读取的命令也不同。从spi-flash中加载是通过 sf 命令实现的:

sfa18 # help sf
sf - SPI flash sub-system
Usage:
sf probe [[bus:]cs] [hz] [mode] - init flash device on given SPI busand chip select
sf read addr offset|partition len       - read `len' bytes starting at`offset' or from start of mtd`partition'to memory at `addr'
sf write addr offset|partition len      - write `len' bytes from memoryat `addr' to flash at `offset'or to start of mtd `partition'
sf erase offset|partition [+]len        - erase `len' bytes from `offset'or from start of mtd `partition'`+len' round up `len' to block size
sf update addr offset|partition len     - erase and write `len' bytes from memoryat `addr' to flash at `offset'or to start of mtd `partition'
sf protect lock/unlock sector len       - protect/unprotect 'len' bytes startingat address 'sector'
sfa18 #

根据当前的分区情况,uboot从flash的0xa0000位置加载内核镜像,并读取到ram地址0x81000000。

sfa18 # sf probe 0 33000000
do_spi_flash----cmd = probe
SF: Detected W25Q128BV with page size 256 Bytes, erase size 4 KiB, total 16 MiB
sfa18 # sf read 0x81000000 0xa0000 0xa00000
do_spi_flash----cmd = read
device 0 offset 0xa0000, size 0xa00000
SF: 10485760 bytes @ 0xa0000 Read: OK
sfa18 # 

Sf read的最后一个参数是读取的长度,目前默认是0xa00000,10MB。

从设备中读取镜像后,从ram引导镜像的命令为bootm:

sfa18 # help bootm
bootm - boot application image from memoryUsage:
bootm [addr [arg ...]]- boot application image stored in memorypassing arguments 'arg ...'; when booting a Linux kernel,'arg' can be the address of an initrd imageWhen booting a Linux kernel which requires a flat device-treea third argument is required which is the address of thedevice-tree blob. To boot that kernel without an initrd image,use a '-' for the second argument. If you do not pass a thirda bd_info struct will be passed insteadSub-commands to do part of the bootm sequence.  The sub-commands must be
issued in the order below (it's ok to not issue all sub-commands):start [addr [arg ...]]loados  - load OS imageramdisk - relocate initrd, set env initrd_start/initrd_endfdt     - relocate flat device treecmdline - OS specific command line processing/setupbdt     - OS specific bd_t processingprep    - OS specific prep before relocation or gogo      - start OS
sfa18 # 

Bootm启动的默认地址由CONFIG_SYS_LOAD_ADDR宏来定义,目前为0x81000000。因此可以通过任何方法将镜像加载到ram的这个地址后通过bootm引导,而不仅限于从flash中读取。

sfa18 # bootm
## Booting kernel from Legacy Image at 81000000 ...Image Name:   MIPS OpenWrt Linux-3.18.29Created:      2017-08-31   6:27:49 UTCImage Type:   MIPS Linux Kernel Image (lzma compressed)Data Size:    1635008 Bytes = 1.6 MiBLoad Address: 80100000Entry Point:  80105360Verifying Checksum ... OKUncompressing Kernel Image ... OK

代码下载、编译

代码下载
  • 账号注册

uboot代码需要向siflower申请gerrit权限,同意开放后需要提供相关邮箱进行账号注册,注册通过后会给到对应的账号以及密码

  • 账号登录

    • 获取账号后,使用账号密码登陆gerrit网站
  • 获取代码

    • 登陆gerrit.siflower.cn:9011后

    • 打开申请列表可以看到代码仓库信息,获取复制下载链接

    • 开始下载代码,下载密码在基本资料,Git密码

  • 开始下载
编译
  • 编译uboot

由于同时需要spl和uboot两部分,而为了简化烧录过程,会将两部分拼成一个镜像,统一作为BootLoader,因此uboot的编译推荐直接使用编译脚本sf_make.sh。
由于存在不同的板型和芯片,因此该脚本还支持若干个参数:use_mti,ver,prj,mode和cmd。
use_mti:表示编译工具链选择,支持0(默认)和1。其中0表示使用当前目录toolchain中工具链,1表示使用系统编译工具链。  
Cmd:表示命令,支持distclean、clean、make、dmake(默认)。其中dmake指的是先进行distclean,再make。
Mode:表示选择release或debug模式,支持r(默认)和d。Mode=r时编译出的binary文件包含设备树信息,elf debug文件不包含;mode=d时binary不包含,debug文件包含。Mode=d一般是配合jtag进行调试使用的。
Ver:表示芯片型号,支持mpw0(默认)、mpw1和fullmask。
Prj:表示板型,支持sfa28_evb、sfa28_p20b、sfa28_ac28等
因此,实际编译时只要根据板子的情况,设置非default的参数即可。比如想要编译一个flash启动的fullmask最新evb镜像,编译命令如下:

./sf_make.sh ver=fullmask

想要提交代码时,可以通过

./sf_make.sh cmd=clean  

删掉编译生成的多余文件。

  • 编译带版型编号的uboot镜像

当需要生成正式的带版型名称编号分支版本号等信息的uboot镜像时,可以使用如下面指令进行编译,具体可以参考该脚本的实现

./make.sh sfa28_evb 

这样编译的进行会生成在根目录,此镜像就等同于uboot/sfax8/uboot_full.img,但是带有分支版型版本号等信息

编译结果

编译生成的文件均copy到了uboot/sfax8/目录下,包括:
uboot_full.img:spl和uboot的组合,烧录就使用这个文件。
spl_128k.img:spl编译的binary镜像添加了irom-header后,扩充到128KB的结果,可以用于更新mpw验证代码在使用boot_ddr时的BootLoader.bin。
u-boot.img:uboot的binary镜像加uimage header。
u-boot-spl.img:spl binary加irom header。
p20b.img:与uboot_full.img相同,会以板子型号命名。

以太网烧录

适用平台

sf16a18/sf19a28 evb开发板。

烧录步骤
  1. 板子接串口,重启进入uboot,回车进入command模式,输入命令httpd 192.168.1.1 (或者其它和PC同网段的ip),回车,界面如下:

  2. 电脑网线接板子上的网口。
    浏览器地址根据不同的需求输入不同的网址,如下表,以192.168.1.1为例:

网址功能适合文件
192.168.1.1烧录firmware*sysupgrade.bin, uImage-initramfs.lzma, uImage.lzma
192.168.1.1/uboot.html烧录纯ubootuboot_full.img (慎用)

正常的烧录界面如下:

  1. 烧录完毕会自动重启

uboot新版型引入

uboot引入新版型主要涉及到新版型配置文件改动,以太网驱动适配等,下面将以ac28为例给出uboot新版型引入的示例。

配置文件适配
  • 增加对应版型的配置文件夹,如uboot/board/siflower/sfa28_ac28/,目录内容如下:

    qin@ubuntu:~/uboot$ ls board/siflower/sfa28_ac28/
    Kconfig  MAINTAINERS  Makefile
    

    其中Kconfig定义了版型的名字等信息,MAINTAINERS定义了配置文件的地址,Makefile定义了新版型编译的方式。

  • 修改公共代码增加对应版型定义,对应文件board/siflower/sfax8_common/siflower.c和board/siflower/sfax8_common/Kconfig,主要用于新版型定义的使用方式。

  • 增加对应版型的Kconfig,对应文件arch/mips/mach-sfax8/Kconfig,用于make menuconfig时供用户选择此版型;

  • 增加新版型的defconfig配置文件,对应文件configs/sfa28_mpw0_ac28_defconfig,对应版型的所有参数,可以通过拷贝相似版型的配置文件得来,并通过make menuconfig重新进行个性化配置;

  • 增加新版型编译方式,对应文件sf_make.sh,如下:

    225     ac28)
    226         DEFCONFIG="sfa28_"$ver"_ac28"
    227         add_sfbl_flag sf19a28_mpw0=1
    228         add_sfbl_flag crystal_40m=1
    229         add_sfbl_flag odt=0
    230 #       [ -z $ddr2 ] && ddr2=em68b16cwqh
    231         [ -z $ddr2 ] && ddr2=pme809416dbr
    232         ;;
    
  • 其他:新增版型一般不需要修改dts,如果需要修改i2c、uart、gpio等硬件信息时需要修改dts,对应文件arch/mips/dts/sfa28_mpw0.dts

以太网驱动适配

当新增版型引入了新的有线设备时,需要对应适配以太网驱动,对应文件drivers/net/sfa18_gmac.c,详细引入新的有线设备(gphy、gswitch)可以参考:gmac外围芯片对接手册

Uboot物料对接

Siflower Uboot支持多种物料对接,包含不同DDR和Flash型号,详细参考:Flash和DDR物料调试指南

DDR通用参数使用配置

现在uboot代码中支持较为普遍的1G和2G容量的DDR3,以及512M和1G容量的DDR2。分别参照《JEDEC Standard No.79-3A》协议标准文档和《JEDEC Standard No.79-2F》协议标准文档,进行时序参数整理和DDR通用代码实现。
在编译时,按照实际使用的物料容量在编译选择脚本文件sf_make.sh中进行对应ddr选择:
1Gb ddr3物料:

[ -z $ddr3 ] && ddr3=ddr3_1gcommon

2Gb ddr3物料:

[ -z $ddr3 ] &&; ddr3=ddr3_2gcommon

512Mb ddr2物料:

[ -z $ddr2 ] && ddr2=ddr2_512mcommon

1Gb ddr3物料:

[ -z $ddr2 ] &&; ddr2=ddr2_1gcommon

项目引用

参考文档

快速入门

Flash和DDR物料调试指南

FAQ

Q:uboot烧录失败怎么处理
A:uboot烧录失败后无法继续通过uboot更新镜像,可通过irom usb下载,或者摘下flash使用烧录器的方式重新烧录镜像,详细使用方法参考:快速入门

Q:uboot中gpio使用例子
A:
如果想要在uboot中对gpio进行设置,以在uboot代码的common/main.c main_loop函数中加入控制gpio12的代码为例

#define msleep(a)      udelay(a * 1000)
#define ssleep(a)      msleep(a * 1000)
/* We come here after U-Boot is initialised and ready to process commands */
#include <asm/gpio.h>
void main_loop(void)
{const char *s; if (gpio_request(12, "sf_gpio")) {  //申请GPIOprintf("Failed to request gpio %d\n",12);}if (gpio_direction_output(12,1)) {  //配置GPIO输入/输出printf("Failed to set gpio value %d\n",12);}for (;;) {msleep(1000);gpio_set_value(12,0);     //设置GPIO高低电平msleep(1000);gpio_set_value(12,1);}gpio_free(12);bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");#ifdef CONFIG_VERSION_VARIABLEsetenv("ver", version_string);  /* set version variable */
#endif /* CONFIG_VERSION_VARIABLE */cli_init();run_preboot_environment_command();
..
...
....
}   

Q:如何修改cpu clk
A:
cpu clk = CPU_PLL / 分频比
CPU_PLL的计算方式如下:(我们的外部晶振一般是40MHZ频率)

  1. 配置PLL
    PLL计算的分频公式见下图。
    Fref :参考时钟,一般为外部晶振频率。
    Refdiv:参考时钟,分频参数。
    Fbdiv:升频参数,实现整数部分。
    Frac:升频参数,实现小数部分。(小数部分暂不支持,使用的时候忽略)
    Postdiv1:升频后,再做分频参数1。
    Postdiv2:升频后,再做分频参数2。

parmmeter寄存器参数如下,CM_PLL_BASEADDR=0x19E01000

  1. 配置cpu clk分频比
    寄存器信息如下, CM_CFG_BASEADDR=0x19E01500

注意该寄存器配置的分频比应该为寄存器里的值加1
0-> 1分频
1-> 2分频
2-> 3分频

  1. uboot中代码的位置
  • 修改PLL,代码路径
    uboot/bare_spl/common/clk.c
    修改如下红框的位置, 此处为修改PLL

  • 修改分频比
    默认为2分频,如有需要,请自行在合适位置修改, 通过配置前面所述配置分频比的寄存器。

文档信息

  • 本文作者:Phoenix
  • 本文链接:https://siflower.github.io/2020/09/08/ubootDevelopmentManual/
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/45817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【QT】布局管理器

布局管理器 布局管理器1. 垂直布局2. 水平布局3. 网格布局4. 表单布局5. Spacer 布局管理器 之前使⽤ Qt 在界⾯上创建的控件, 都是通过 “绝对定位” 的⽅式来设定的&#xff1b;也就是每个控件所在的位置, 都需要计算坐标, 最终通过 setGeometry 或者 move ⽅式摆放过去。 …

排序-java(详解)

一&#xff0c;分类 主要的排序大致分为以下几类&#xff1a; 1&#xff0c;插入排序&#xff0c;又分为直接插入排序和希尔排序 2&#xff0c;选择排序&#xff0c;又分为选择排序和堆排序 3&#xff0c;交换排序&#xff0c;又分为冒泡排序和快速排序 4&#xff0c;归并…

【linux】服务器安装及卸载pycharm社区版教程

【linux】服务器安装及卸载pycharm社区版教程 【创作不易&#xff0c;求点赞关注收藏】 文章目录 【linux】服务器安装及卸载pycharm社区版教程1、到官网下载安装包2、通过终端wget下载安装包3、解压4、安装5、设置环境变量6、运行pycharm7、删除pycharm安装包、卸载pycharm …

从“卷模型”到“卷应用”:AI时代的价值重塑与个性化智能探索

&#x1f308;所属专栏&#xff1a;【其它】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点…

【漏洞复现】华测监测预警系统2.2 UserEdit.aspx SQL注入

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 华测监测预警系统2.2&#xff08;HuaCe Monitoring and Early Warning System 2.2&#xff09;是一款由华…

人工智能算法工程师(中级)课程9-PyTorch神经网络之全连接神经网络实战与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程9-PyTorch神经网络之全连接神经网络实战与代码详解。本文将给大家展示全连接神经网络与代码详解&#xff0c;包括全连接模型的设计、数学原理介绍&#xff0c;并从手写数字识别到猫狗识…

【第32章】MyBatis-Plus之代码生成器配置

文章目录 前言一、概述1.特点说明2.示例配置3. 数据库配置 (DataSourceConfig) 二、全局配置 (GlobalConfig)1.方法说明2.示例配置 三、包配置 (PackageConfig)1. 方法说明2. 示例配置 四、模板配置 (TemplateConfig)1. 方法说明2. 示例配置 五、注入配置 (InjectionConfig)1. …

使用 exe4j 转换 Java jar 程序为 Windows 平台可执行文件 (.exe)

使用 exe4j 转换 Java jar 程序为 Windows 平台可执行文件 &#xff08;.exe&#xff09; 介绍exe4j 特点&#xff1a;转换全过程&#xff08;软件操作&#xff09;1、注册2、选择模式3、配置应用4、选择执行的方式&#xff08;我这里管这个叫呈现方式&#xff09;5、选择 JAR …

Java 中的正则表达式

转义字符由反斜杠\x组成&#xff0c;用于实现特殊功能当想取消这些特殊功能时可能在前面加上反斜杠\ 例如在Java中\也具有特殊意义&#xff0c;前面加一个反斜杠表示取消特殊意义&#xff0c;表示1个普通的反斜杠\&#xff0c;\\\\表示2个普通的反斜杠\\。其实就是要求Java中的…

Python那些优质可视化工具!

作者&#xff1a;Lty美丽人生 https://blog.csdn.net/weixin_44208569 本次分享10个适用于多个学科的Python数据可视化库&#xff0c;其中有名气很大的也有鲜为人知的&#xff01; 1、matplotlib 两个直方图 matplotlib 是Python可视化程序库的泰斗。经过十几年它任然是Pytho…

【前端速通系列|第二篇】Vue3前置知识

文章目录 1.前言2.包管理工具npm2.1下载node.js2.2配置 npm 镜像源2.3 npm 常用命令 3.Vite构建工具4.Vue3组件化5.Vue3运行原理 1.前言 本系列文章旨在帮助大家快速上手前端开发。 2.包管理工具npm npm 是 node.js中进行 包管理 的工具. 类似于Java中的Maven。 2.1下载nod…

Autoware 定位之基于ARTag的landmark定位(六)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务&#xff0c;并且需要GPU资源&#xff0c;可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&…

CSS相对定位和绝对定位的区别

CSS相对定位和绝对定位的区别 区别1&#xff1a;相对的对象不同 相对定位是相对于自己绝对定位是相对于离自己最近的有定位的祖先 区别2:是否会脱离文档流 相对定位不会脱离文档流&#xff0c;不会影响其他元素的位置绝对定位会脱离文档流&#xff0c;会影响其他元素的布局 代…

玩转springboot之SpringBoot打成jar包的结构

SpringBoot打成jar包的结构 springboot通常会打成jar包&#xff0c;然后使用java -jar来进行执行&#xff0c;那么这个jar包里的结构是什么样的呢 其中 BOOT-INF 中包含的classes是我们程序中所有的代码编译后的class文件&#xff0c;lib是程序所引用的外部依赖 META-INF 这个…

AM243-Timer

目录 简介初始化代码测试API补充 简介 定时中断。 初始化 开启定时器&#xff0c;最多支持8个硬件定时器 定时周期1ms 增加一个GPIO输出口PRG0_PRU1_GPO15/M4 &#xff0c;我们会在定时中断中每隔1ms翻转该引脚&#xff0c;理想情况下应该在该引脚上测得2ms周期500Hz的矩形…

手把手教你打数学建模国赛!!!第一天软件准备篇

第一天软件准备 MATLAB MATLAB&#xff08;Matrix Laboratory&#xff09;是一种强大的数值计算和科学编程软件。它提供了丰富的数学函数和工具&#xff0c;用于数据分析、算法开发、信号处理、图像处理、控制系统设计、仿真等应用领域。 MATLAB具有直观的语法&#xff0c;使…

Postman接口模拟请求工具使用技巧

Postman是一款非常强大的接口模拟请求工具&#xff0c;可以帮助开发者快速测试、调试API接口。下面集合实际使用过程中的经验&#xff0c;分享大家一些基础使用技巧&#xff1a; 1. 安装与启动&#xff1a;首先在官网&#xff08;Download Postman | Get Started for Free&…

【Linux信号】阻塞信号、信号在内核中的表示、信号集操作函数、sigprocmask、sigpending

我们先来了解一下关于信号的一些常见概念&#xff1a; 实际执行 信号的处理动作 称为信号递达。 信号从产生到递达的之间的状态称为信号未决。 进程可以选择阻塞(Block)某个信号。 被阻塞的信号产生时是处于未决状态的&#xff0c;知道进程解除对该信号的阻塞&#xff0c;该…

零信任作为解决方案,Hvv还能打进去么?

零信任平台由“中心组件服务”三大部分构成&#xff0c;以平台形式充分融合软件定义边界&#xff08;SDP&#xff09;、身份与访问管理&#xff08;IAM&#xff09;、微隔离 &#xff08;MSG&#xff09;的技术方案优势&#xff0c;通过关键技术的创新&#xff0c;实现最佳可信…

手机数据恢复篇:如何从 Android 手机恢复消失的照片

丢失 Android 手机中的照片现在已成为您可能遇到的最糟糕的情况之一。随着手机在相机方面越来越好&#xff0c;即使是那些不热衷于拍照的人也成为了摄影师。 如今&#xff0c;人们可以随时随地拍摄照片&#xff0c;每一张照片都保存着回忆和数据&#xff0c;因此&#xff0c;丢…