uboot学习之cp命令

Linux驱动开发:uboot启动流程详解_uboot是怎么启动的 reset 函数存在于 arch/arm/cpu/armv7/start.s 文件中,而 reset 函数跳转到 save_boot_params 函数,save_boot_params 函数又跳转到 save_boot_params_ret中,具体如下: 2.3 cpsr和cp15 STCLR reset 函数跳转到 save_boot_params_ret函数后,具体如下: 从上述代码能看出,代码包含5个部分:cpsr,cp15,cpu_init_cp15,cpu_init_crit和**_main** 阅读详情

一、uboot增加命令过程

在uboot起来后,我们可以在它的shell界面输入各种命令,而U-Boot的每一个命令都是通过U_BOOT_CMD宏定义的,这个宏在include/command.h头文件中定义,每一个命令定义一个cmd_tbl_t结构体。

#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage,_help)                                \

U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help,NULL)

每一个命令宏U_BOOT_CMD用cmd_tbl_t结构体描述一个命令:

#ifndef __ASSEMBLY__

/*

 * Monitor CommandTable

 */

 

struct cmd_tbl_s {

                char                       *name;                                /* Command Name这是命令名字,不需要用双引号括起来*/

                int                          maxargs;             /* maximum number of arguments最大参数个数      */

                int                          repeatable;        /* autorepeat allowed?               命令是否可重复,就是说下一次按回车时再执行     */

                                                                                /*Implementation function      */

                int                          (*cmd)(structcmd_tbl_s *, int, int, char * const []);//对应的执行函数

                char                       *usage;                                /* Usage message          (short)字符串对尖的简短说明             */

#ifdef    CONFIG_SYS_LONGHELP

                char                       *help;                   /* Help  message            (long) 帮助   */

#endif

#ifdef CONFIG_AUTO_COMPLETE

                /*do auto completion on the arguments */

                int                          (*complete)(int argc,char * const argv[], char last_char, int maxv, char *cmdv[]);

#endif

};

typedef struct cmd_tbl_s             cmd_tbl_t;

 

#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd,_usage, _help, _comp) \

                ll_entry_declare(cmd_tbl_t,_name, cmd) =                                      \

                                U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,     \

                                                                                                _usage,_help, _comp);

上面的宏函数是定义一个cmd_tbl_t的结构体,同时给它的每个成员给值,给值是通过U_BOOT_CMD_MKENT_COMPLETE这个宏来完成的。

#define ll_entry_declare(_type, _name, _list)                                                   \

                _type_u_boot_list_2_##_list##_2_##_name __aligned(4)                      \

                                                __attribute__((unused,                                                               \

                                                section(".u_boot_list_2_"#_list"_2_"#_name)))

在这个宏中可以看出所定义的这个结构体是放在u_boot_list段中,同时是四个字节以齐。

所定义的结构体的名子是通过双#号来连接一些参数名来完成。凡是带有__attribute__((unused,section (".u_boot_list"))属性声明的变量都将被存放在".u_boot_list"段中,并且即使该变量没有在代码中显式的使用编译器也不产生警告信息。“##”与“#”都是预编译操作符,“##”有字符串连接的功能,“#”表示后面紧接着的是一个字符串.

#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep,_cmd,                     \

                                                                _usage,_help, _comp)                                 \

                                {#_name, _maxargs, _rep, _cmd, _usage,                                         \

                                                _CMD_HELP(_help)_CMD_COMPLETE(_comp) }

上面的宏就是拆分各个参数。

 

编译完uboot后,就可以在uboot.lds和uboot.map中看到映射地址如下:

  . = ALIGN(4);

  .u_boot_list : {

 KEEP(*(SORT(.u_boot_list*)));

  }

  . = .;

  __start___ex_table =.;

  __ex_table : {*(__ex_table) }

  __stop___ex_table =.;

 

 

.u_boot_list   0x00000000efff886c      0x8ec

 *(SORT(.u_boot_list*))

 .u_boot_list_2_cmd_1

               0x00000000efff886c        0x0common/libcommon.o

 .u_boot_list_2_cmd_2_base

               0x00000000efff886c       0x1ccommon/libcommon.o

               0x00000000efff886c               _u_boot_list_2_cmd_2_base

 .u_boot_list_2_cmd_2_bdinfo

               0x00000000efff8888       0x1ccommon/libcommon.o

               0x00000000efff8888               _u_boot_list_2_cmd_2_bdinfo

 .u_boot_list_2_cmd_2_boot

               0x00000000efff88a4       0x1ccommon/libcommon.o

               0x00000000efff88a4               _u_boot_list_2_cmd_2_boot

 .u_boot_list_2_cmd_2_bootd

               0x00000000efff88c0       0x1ccommon/libcommon.o

                0x00000000efff88c0                _u_boot_list_2_cmd_2_bootd

 .u_boot_list_2_cmd_2_bootelf

               0x00000000efff88dc       0x1ccommon/libcommon.o

               0x00000000efff88dc               _u_boot_list_2_cmd_2_bootelf

 .u_boot_list_2_cmd_2_bootm

               0x00000000efff88f8       0x1ccommon/libcommon.o

               0x00000000efff88f8               _u_boot_list_2_cmd_2_bootm

 .u_boot_list_2_cmd_2_bootp

               0x00000000efff8914       0x1ccommon/libcommon.o

                0x00000000efff8914                _u_boot_list_2_cmd_2_bootp

 .u_boot_list_2_cmd_2_bootvx

               0x00000000efff8930       0x1ccommon/libcommon.o

               0x00000000efff8930               _u_boot_list_2_cmd_2_bootvx

 .u_boot_list_2_cmd_2_cmp

               0x00000000efff894c       0x1ccommon/libcommon.o

               0x00000000efff894c               _u_boot_list_2_cmd_2_cmp

 .u_boot_list_2_cmd_2_coninfo

               0x00000000efff8968       0x1ccommon/libcommon.o

               0x00000000efff8968               _u_boot_list_2_cmd_2_coninfo

 .u_boot_list_2_cmd_2_cp

               0x00000000efff8984       0x1ccommon/libcommon.o

               0x00000000efff8984               _u_boot_list_2_cmd_2_cp

 ………..

 

 

我们在uboot的源代码里,一些命令是在cmd_XXX.c中去定义和实现的。

在这里我们以cp命令来说明命令的执行和增加过程.

二、CP命令解析

Cp命令是在cmd_mem.c中定义。如下:

U_BOOT_CMD(

                cp,          4,            1,            do_mem_cp,

                "memorycopy",

                "[.b,.w, .l] source target count"

);

 

static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, intargc, char * const argv[])

{

                ulong    addr, dest, count, bytes;

                int          size;

                constvoid *src;

                void*buf;

 

                if(argc != 4)

                                returnCMD_RET_USAGE;

 

                /*Check for size specification.

                */

                if((size = cmd_get_data_size(argv[0], 4)) < 0)

                                return1;

 

                addr= simple_strtoul(argv[1], NULL, 16);

                addr+= base_address;

 

                dest= simple_strtoul(argv[2], NULL, 16);

                dest+= base_address;

 

                count= simple_strtoul(argv[3], NULL, 16);

 

                if(count == 0) {

                                puts("Zero length ???\n");

                                return1;

                }

 

#ifndef CONFIG_SYS_NO_FLASH

                /*check if we are copying to Flash */

                if ((addr2info(dest) != NULL)

#ifdef CONFIG_HAS_DATAFLASH

                   && (!addr_dataflash(dest))

#endif

                   ) {

                                intrc;

 

                                puts("Copy to Flash... ");

 

                                rc= flash_write ((char *)addr, dest, count*size); //调用flash_write写入数据,这个函数是在common/flash.c中定义

                                if(rc != 0) {

                                                flash_perror(rc);

                                                return(1);

                                }

                                puts("done\n");

                                return0;

                }

#endif

 

#ifdef CONFIG_HAS_DATAFLASH

                /*Check if we are copying from RAM or Flash to DataFlash */

                if(addr_dataflash(dest) && !addr_dataflash(addr)){

                                intrc;

 

                                puts("Copy to DataFlash... ");

 

                                rc= write_dataflash (dest, addr, count*size);

 

                                if(rc != 1) {

                                                dataflash_perror(rc);

                                                return(1);

                                }

                                puts("done\n");

                                return0;

                }

 

                /*Check if we are copying from DataFlash to RAM */

                if(addr_dataflash(addr) && !addr_dataflash(dest)

#ifndef CONFIG_SYS_NO_FLASH

                                                                 && (addr2info(dest) == NULL)

#endif

                   ){

                                intrc;

                                rc= read_dataflash(addr, count * size, (char *) dest);

                                if(rc != 1) {

                                                dataflash_perror(rc);

                                                return(1);

                                }

                                return0;

                }

 

                if(addr_dataflash(addr) && addr_dataflash(dest)){

                                puts("Unsupported combination of source/destination.\n\r");

                                return1;

                }

#endif

 

#ifdef CONFIG_BLACKFIN

                /*See if we're copying to/from L1 inst */

                if(addr_bfin_on_chip_mem(dest) || addr_bfin_on_chip_mem(addr)) {

                                memcpy((void*)dest, (void *)addr, count * size);

                                return0;

                }

#endif

 

                bytes= size * count;

                buf= map_sysmem(dest, bytes);

                src= map_sysmem(addr, bytes);

                while(count-- > 0) {

                                if(size == 4)

                                                *((ulong*)buf) = *((ulong  *)src);

                                elseif (size == 2)

                                                *((ushort*)buf) = *((ushort *)src);

                                else

                                                *((u_char*)buf) = *((u_char *)src);

                                src+= size;

                                buf+= size;

 

                                /*reset watchdog from time to time */

                                if((count % (64 << 10)) == 0)

                                                WATCHDOG_RESET();

                }

                return0;

}

 

 

int

flash_write (char *src, ulong addr, ulong cnt)

{

#ifdef CONFIG_SPD823TS

                return(ERR_TIMOUT);  /* any other error codesare possible as well */

#else

                inti;

                ulong         end        = addr + cnt - 1;

                flash_info_t*info_first = addr2info (addr);

                flash_info_t*info_last  = addr2info (end );

                flash_info_t*info;

                __maybe_unusedchar *src_orig = src;

                __maybe_unusedchar *addr_orig = (char *)addr;

                __maybe_unusedulong cnt_orig = cnt;

 

                if(cnt == 0) {

                                return(ERR_OK);

                }

 

                if(!info_first || !info_last) {

                                return(ERR_INVAL);

                }

 

                for(info = info_first; info <= info_last; ++info) {

                                ulongb_end = info->start[0] + info->size;           /*bank end addr */

                                shorts_end = info->sector_count - 1;

                                for(i=0; i<info->sector_count; ++i) {

                                                ulonge_addr = (i == s_end) ? b_end : info->start[i + 1];

 

                                                if((end >= info->start[i]) && (addr < e_addr) &&

                                                    (info->protect[i] != 0) ) {

                                                                return(ERR_PROTECTED);

                                                }

                                }

                }

 

                /*finally write data to flash */

                for(info = info_first; info <= info_last && cnt>0; ++info) {

                                ulonglen;

 

                                len= info->start[0] + info->size - addr;

                                if(len > cnt)

                                                len= cnt;

                                if((i = write_buff(info, (uchar *)src, addr, len)) != 0) {//调用cfi_flash.c中的write_buff写入数据

                                                return(i);

                                }

                                cnt  -= len;

                                addr+= len;

                                src  += len;

                }

 

#if defined(CONFIG_FLASH_VERIFY)

                if(memcmp(src_orig, addr_orig, cnt_orig)) {

                                printf("\nVerifyfailed!\n");

                                returnERR_PROG_ERROR;

                }

#endif /* CONFIG_SYS_FLASH_VERIFY_AFTER_WRITE */

 

                return(ERR_OK);

#endif /* CONFIG_SPD823TS */

}

【Uboot】Uboot启动流程分析 第 68 行,调用 bootz_start 函数,该函数用于支持 zImage 镜像的启动,定义在文件 cmd/bootz.c 中,设置 images 的 ep 成员变量,也就是系统镜像的入口点,使用 bootz 命令启动系 统的时候就会设置系统在 DRAM 中的存储位置,调用 bootz_setup 函数,此函数会判断当前的系统镜像文件是否为 Linux 的镜像 文件,并且会打印出镜像相关信息bootz_start 主要用于初始化 images 的相关成员变量。此时会进行一些初始化工作。 阅读详情

相关推荐

嵌入式Linux开发-uboot常用命令介绍(下篇)

这篇文章是UBOOT命令介绍的下篇,接着上篇文章介绍剩下的几个命令用法。 主要是涉及的命令是:磁盘分区、磁盘文件加载、内核引导、二进制文件加载、跳转命令、磁盘文件系统格式等等。

1354

uboot常见命令使用(一)

Uboot中的一些命令

qaqq55的博客 818

STM32测测速---编码电机读取速度的计算

速度计算:轮胎每转一圈的脉冲数取决于编码器的分辨率,可由下面公式进行计算:PPR是电机的线数最后可以计算轮胎每转一圈的脉冲数为:轮胎每转一圈的脉冲数 = 9.6 × 11 × 4 = 422.4最后的速度公式简化为:速度 = (0.01 秒内产生的脉冲数 ∗ 0.055 ∗ π )/(0.01 ∗422.4​。

weixin_69414084的博客 3811

uboot 命令使用(1)

1. version 查看uboot版本号 2. setenv saveenv 修改(新建、删除)和保存环境变量 3. md 显示内存值 4. nm 修改指定地址的内存值 5. mm 自动递增修改 指定地址的内存值 6. mw 用一个指定的数据填充一段内存

weixin_43096766的博客 988

工业组态软件Intouch(单机版)入门{第二篇}

第5步:*都装好之后,需要进行测试授权是否生效,测试1:能否正常运行项目和编辑项目(能否编辑项目,取决于你的授权是否包含开发功能,如果只是单一的runtime授权,则只能运行项目,不能编辑项目)。在线第3步:点击第一个框右边的按钮,弹出文件浏览窗口,选中你的XMl授权文件,打开,然后你的授权出现在下方的列表中,勾选你的授权,然后点击Activate,等待几秒,授权就会出现在管理器页面的列表中,并且Status会显示Activated。第1步:软件安装好之后,先要配置好授权服务器。等待几秒,激活完成。

weixin_41571357的博客 1万+

新手小白如何学习编程

学习目标推荐第一门语言优势网站 / APP 开发(前端)JavaScript浏览器原生支持,能快速做出可视化效果后端 / 服务器 / 数据分析Python语法简洁像英语,库多、应用广(入门友好)游戏开发先用电竞入门,再转专业引擎硬件 / 嵌入式(比如单片机)C 语言贴近硬件,行业标准办公自动化(Excel / 文档处理)Python快速解决重复工作(比如批量改文件)👉新手首选推荐。

2501_94331842的博客 2232

U-Boot常用命令

正点原子STM32MP157系统移植过程U-Boot常用命令记录

FallenCity185的博客 4159

PyTorch实战:从零构建CNN图像分类模型

卷积神经网络(CNN)作为计算机视觉的核心架构,通过局部连接和权值共享机制高效处理图像数据。其核心组件包括卷积层、池化层和全连接层,其中PyTorch的动态计算图特性为CNN实现提供了灵活的开发环境。在工程实践中,使用CIFAR-10这类标准数据集可以快速验证模型性能,而数据增强和批归一化等技术能有效提升模型泛化能力。通过PyTorch实现CNN不仅能够掌握图像分类的基本原理,还能为后续迁移学习和复杂视觉任务打下基础,特别是在结合Adam优化器和学习率调度策略后,模型收敛速度和准确率都能得到显著提升。

weixin_42405592的博客 318

U-Boot常用命令介绍

U-Boot 上电启动后,按任意键可以退出自动启动状态,进入命令行。U-Boot 可支持几十个常用命令,通过这些命令,可以对开发板进行调试,引导 Linux 内核,还可以擦写 Flash 完成系统部署等功 能。掌握这些命令的使用,才能够顺利地进行嵌入式系统的开发。

Leon的博客 2538

晶振(晶体振荡器)测试方法详解

晶振测试方法分为无源和有源两种类型。无源晶振(两脚)需用示波器测试波形,重点关注正弦波形状、200mV-1.5Vpp幅值和频率精度;有源晶振(四脚)通电后直接输出方波。测试要点包括:示波器使用10X探头、AC耦合,带宽需5倍于晶振频率;万用表可初筛短路/开路;替换法是工程最有效方法。常见故障排查顺序:供电→复位→焊接→型号→负载电容→波形观察→更换晶振→MCU配置。负载电容需按公式计算匹配,示波器观察是核心测试手段。

jiujiujinyuxi的博客 925

国密SKF库数字签名全解析:SM2签名与验证的详细实现

本文详细解析了基于国密SKF库实现SM2数字签名与验证的全过程。内容涵盖SKF库环境搭建、设备初始化、PIN码验证、SM2签名生成以及纯软件与SKF库两种验证方式的详细实现,为开发者提供了一份实用的国密算法开发指南。

weixin_29303701的博客 323

IMX6ULL移植篇-uboot的内存命令

uboot内存操作命令

wojiaxiaohuang2014的博客 718

复现基于混频因子模型的GDP即时预测方法

基于混频因子模型的GDP即时预测方法复现 本文复现了混频因子模型(MIDAS)在GDP即时预测中的应用。该方法整合7个月度宏观经济变量(工业增加值、CPI、PMI等)与季度GDP数据,通过状态空间模型实现高频预测。技术实现包括:1)使用PCA提取潜在共同因子;2)构建状态空间模型处理混频数据;3)通过卡尔曼滤波进行参数估计。实证结果显示模型预测效果良好(测试集R²=0.82),其中工业增加值对因子1贡献最大(0.82),CPI对因子2贡献显著(0.78)。该方法为决策者提供了更及时的季度GDP估算。

huanghm88的专栏 601

run命令 uboot_uboot命令大全

Printenv 打印环境变量。Uboot> printenvbaudrate=115200ipaddr=192.168.1.1ethaddr=12:34:56:78:9A:BCserverip=192.168.1.5Environment size: 80/8188 bytesSetenv 设置新的变量Uboot> setenv myboard AT91RM9200DKUboot&g...

weixin_39767124的博客 329

【异常】OpenClaw网关仪表盘 pairing required 报错排查与解决方案

在OpenClaw网关仪表盘页面,完成WebSocket URL、网关令牌等必填项配置后,点击「连接」按钮尝试建立网关连接时,页面下方出现红色报错提示框,核心报错内容为,无法完成网关连接建立,且该报错在令牌配置正确、网络链路通畅的场景下仍会触发。该报错常见于非本地回环地址的访问场景,包括局域网远程访问、公网域名/IP访问、云服务器部署的网关远程管理等场景,本地127.0.0.1回环地址访问通常可正常连接。

奶爸的编程之路,也就一周冷个三天 1078

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

run命令 uboot_UBoot常用命令手册

U-Boot还提供了更加详细的命令帮助,可以通过”?”显示支持的命令列表,通过help [CommandName]命令还可以查看每个命令的参数说明。1、bootmbootm [addr [arg ...]]- boot application image stored in memorypassing arguments 'arg ...'; when booting a Linux kernel...

weixin_39735166的博客 509

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

UBoot常用命令手册

http://blog.sina.com.cn/s/blog_3e3a29b301016uif.html UBoot常用命令手册 U-Boot还提供了更加详细的命令帮助,可以通过”?”显示支持的命令列表,通过help [CommandName]命令还可以查看每个命令的参数说明。 1、bootm bootm [addr [arg ...]] - boot application i...

boazheng的博客 666

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

uboot学习(2)-uboot常用命令

uboot全称Universal Boot Loader。作用:简单来说就是,初始化DDR等外设,将Linux内核从flash中拷贝到DDR中,最后启动Linux内核。

嵌入式Linux开发从业者,立志做一名优秀的博客输出者! 808

[uboot] (第五章)uboot流程——uboot启动流程

uboot启动流程

ooonebook的博客 1万+

Linux---Uboot命令

以后调试时就烧录到SD卡,因为命令行烧录要烧写整个系统【耗时、浪费产品开发周期。

EE_xx33333的博客 395

IMX6ULL学习笔记 (二) —— uboot 命令

随记 , 记录 uboot 命令⭐️目录。

个人博客 : https://ye2020.github.io/ 1092

uboot命令使用学习(2)

学习目标: uboot命令使用学习(2) 学习内容: 学习使用了正点原子的I.MX6ULL教程及开发平台。 使用uboot的内存操作命令,直接对DRAM进行读写操作。 1、md 2、nm 3、mm 4、mw 5、cp 6、cmp 学习时间: 2022-05-29 学习产出: 一、md显示内存值 ”md“命令用于显示内存值,格式如下: md[.b,.w,.l] address [#of objects] 命令中的[.b,.w,.l]对应byte,word,long,也就是分别以1字节、2字节、4字节来显示内存

qq_41545736的博客 2533

[uboot] (第三章)uboot流程——uboot-spl代码流程

以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为例。[uboot] uboot流程系列: [project X] tiny210(s5pv210)上电启动流程(BL0-BL2)[uboot] (第一章)uboot流程——概述[uboot] (第二章)uboot流程——uboot-spl编译流程建议参考文章 [kernel 启动流程] (第二章)第一阶段之—

ooonebook的博客 1万+

Uboot命令理解与实践

这段bootloader程序会先初始化DDR等外设,然后将Linux内核从flash拷贝到 DDR 中,最后启动 Linux 内核。主要的工作就是启动 Linux 内核, bootloader 和 Linux 内核的关系就跟 PC 上的 BIOS 和 Windows 的关系一样, bootloader 就相当于 BIOS。uboot 的全称是 Universal Boot Loader, uboot 是一个遵循 GPL 协议的开源软件, uboot 是一个裸机代码。

nollysoul的博客 294

嵌入式开发环境之uboot命令

help #显示uboot支持所有的命令?命令 #查看命令的内容。

m0_46392035的博客 710
上一篇: Astyle使用方法
下一篇: intel xscale PXA270 porting :unsupported machine ID大杂烩
Bean Huo
博客等级 码龄19年 40粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值