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

uboot之do_bootm_linux启动内核函数源码解析

当配置了CONFIG_PPC时将调用common/cmd_bootm.c中的do_bootm_linux。本处是调用libarm/armlinux.c中的。u-boot.h中static struct tagparams;typedef struct bd_info {int bi_baudrate; /serial console baudrate/波特率unsigned long bi_ip_addr; /IP Address/即服务器IP地址unsigned char bi_enetaddr[6]; /Ethernet adress */struct environment_sbi_env;//开发板机器ID即1008(MACH_TYPE_SMDK2440)gd-bd-bi_arch_number MACH_TYPE_SMDK2440; (smdk2440.c)ulong bi_arch_number; /unique id for this board///准确地说这是启动参数的地址gd-bd-bi_boot_params 0x30000100;(smdk2440.c)与内核中需要一致。ulong bi_boot_params; /where this board expects params/准确地说,这是启动参数的地址struct /RAM configuration/{ulong start;//内存起始地址ulong size;//内存大小} bi_dram[CONFIG_NR_DRAM_BANKS];#ifdef CONFIG_HAS_ETH1/second onboard ethernet port */unsigned char bi_enet1addr[6];#endif} bd_t;在u-boot下输入bd就可以查看开发板的一些信息uplooking # bdarch_number 0x0000065Aenv_t 0x00000000boot_params 0x50000100DRAM bank 0x00000000- start 0x50000000- size 0x08000000ethaddr 00:40:5C:26:0A:5Bip_addr 192.168.1.20baudrate 115200 bps///////////////////////////////////////////////////////////////////////////////////////command.h/*Monitor Command Table*/struct cmd_tbl_s {charname; /Command Name//命令名/int maxargs; /maximum number of arguments//命令的最大参数个数/int repeatable; /autorepeat allowed?//是否自动重复//Implementation function */int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);/命令执行函数/charusage; /Usage message (short) */ /简单的使用说明/#ifdef CFG_LONGHELPcharhelp; /Help message (long)/ /详细使用说明/#endif#ifdef CONFIG_AUTO_COMPLETE /自动补全参数//do auto completion on the arguments */int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);#endif};在文件include/command.h中定义了结构体cmd_tbl_s各成员含义如上面注释。U-boot的每一条命令都将封装成结构体 cmd_tbl_s存到链接文件中指定的.u_boot_cmd区。当向u-boot中添加命令时都将调用宏 U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)来初始化一个cmd_tbl_s 结构体。typedef struct cmd_tbl_s cmd_tbl_t;////////////////////////////////////////////////////////////////////////////当定义了CONFIG_PPC时将使用common/cmd_bootm.c文件中的do_bootm_linux函数当系统中没有定义该宏时系统将使用lib_arm/armlinux.c文件中定义的do_bootm_linux函数。注意这两个函数有很大的区别void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],ulong addr, ulong *len_ptr, int verify){ulong len 0, checksum;ulong initrd_start, initrd_end;ulong data;void (theKernel)(int zero, int arch, uint params);image_header_thdr header;bd_tbd gd-bd;#ifdef CONFIG_CMDLINE_TAGcharcommandline getenv (“bootargs”);//调用了getenv将bootargs环境变量保存在commandline#endif//uboot set参数命令行bootm 50008000;//打印出来发现 hdr-ih_ep 0x800050 也就是必须ntohl之后才是50008000theKernel (void ()(int, int, uint))ntohl(hdr-ih_ep);//打印出来发现theKernel 0x50008000//设置内核入口地址(不是加载地址加载是程序存储地址)入口地址是PC指针倒是后程序跳到这个地址运行//mkimage.c//#define ntohl(a) SWAP_LONG(a)//#define htonl(a) SWAP_LONG(a)/#define SWAP_LONG(x)((__u32)((((__u32)(x) (__u32)0x000000ffUL) 24) |(((__u32)(x) (__u32)0x0000ff00UL) 8) |(((__u32)(x) (__u32)0x00ff0000UL) 8) |(((__u32)(x) (__u32)0xff000000UL) 24) ))***//Check if there is an initrd image //跳过 不是initrd镜像/if (argc 3) {addr simple_strtoul (argv[2], NULL, 16);printf (“## Loading Ramdisk Image at %08lx …\n”, addr);/Copy header so we can blank CRC field for re-calculation */#ifdef CONFIG_HAS_DATAFLASHif (addr_dataflash (addr)) {read_dataflash (addr, sizeof (image_header_t), (char *) header);}else#endifmemcpy (header, (char *) addr, sizeof (image_header_t));if (ntohl (hdr-ih_magic) ! IH_MAGIC) {printf (“Bad Magic Number\n”);do_reset (cmdtp, flag, argc, argv);}data (ulong) header;len sizeof (image_header_t);checksum ntohl (hdr-ih_hcrc);hdr-ih_hcrc 0;if (crc32 (0, (unsigned char) data, len) ! checksum) {printf (“Bad Header Checksum\n”);do_reset (cmdtp, flag, argc, argv);}print_image_hdr (hdr);data addr sizeof (image_header_t);len ntohl (hdr-ih_size);#ifdef CONFIG_HAS_DATAFLASHif (addr_dataflash (addr)) {read_dataflash (data, len, (char) CFG_LOAD_ADDR);data CFG_LOAD_ADDR;}#endif/**do_bootm函数中** s getenv (“verify”);verify (s (*s ‘n’)) ? 0 : 1;//为是否对镜像头做校验做准备读取uboot的环境变量verify如果环境变量verify等于’n’则局部变量verify赋值成为0如果环境变量verify为空即没有定义环境变量verify或者环境变量verify不等于’n’则局部变量verify赋值成为1。****/if (verify) {ulong csum 0;printf ( Verifying Checksum … );csum crc32 (0, (unsigned char) data, len);if (csum ! ntohl (hdr-ih_dcrc)) {printf (“Bad Data CRC\n”);do_reset (cmdtp, flag, argc, argv);}printf (“OK\n”);}if ((hdr-ih_os ! IH_OS_LINUX) || (hdr-ih_arch ! IH_CPU_ARM) || (hdr-ih_type ! IH_TYPE_RAMDISK)) {printf (“No Linux ARM Ramdisk Image\n”);do_reset (cmdtp, flag, argc, argv);}#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)/*we need to copy the ramdisk to SRAM to let Linux boot*/memmove ((void *) ntohl(hdr-ih_load), (uchar *)data, len);//与上文的memcpy (header, (char) addr, sizeof (image_header_t));区别data ntohl(hdr-ih_load);#endif /CONFIG_B2 || CONFIG_EVB4510//Now check if we have a multifile image/} //end of if (argc 3) {else if ((hdr-ih_type IH_TYPE_MULTI) (len_ptr[1])) {ulong tail ntohl (len_ptr[0]) % 4;int i;/skip kernel length and terminator/data (ulong) (len_ptr[2]);/skip any additional image length fields/for (i 1; len_ptr[i]; i)data 4;/add kernel length, and align/data ntohl (len_ptr[0]);if (tail) {data 4 - tail;}len ntohl (len_ptr[1]);}else {/no initrd image*/len data 0;}#ifdef DEBUGif (!data) {printf (“No initrd\n”);}#endifif (data) {initrd_start data;initrd_end initrd_start len;} else {initrd_start 0;initrd_end 0;}debug (“## Transferring control to Linux (at address %08lx) …\n”,(ulong) theKernel);#if defined (CONFIG_SETUP_MEMORY_TAGS) ||defined (CONFIG_CMDLINE_TAG) ||defined (CONFIG_INITRD_TAG) ||defined (CONFIG_SERIAL_TAG) ||defined (CONFIG_REVISION_TAG) ||defined (CONFIG_LCD) ||defined (CONFIG_VFD)setup_start_tag (bd);#ifdef CONFIG_SERIAL_TAGsetup_serial_tag (?ms);#endif#ifdef CONFIG_REVISION_TAGsetup_revision_tag (?ms);#endif#ifdef CONFIG_SETUP_MEMORY_TAGSsetup_memory_tags (bd);#endif#ifdef CONFIG_CMDLINE_TAGsetup_commandline_tag (bd, commandline); //设置启动命令行tags#endif#ifdef CONFIG_INITRD_TAGif (initrd_start initrd_end)setup_initrd_tag (bd, initrd_start, initrd_end);#endif#if defined (CONFIG_VFD) || defined (CONFIG_LCD)setup_videolfb_tag ((gd_t) gd);#endifsetup_end_tag (bd);#endif/we assume that the kernel is in place */printf (“\nStarting kernel …\n\n”);#ifdef CONFIG_USB_DEVICE{extern void udc_disconnect (void);udc_disconnect ();}#endifcleanup_before_linux ();//传递的参数//R0必须为0 //R1机器类型ID 本机为ARMbd- bi_arch_number//R2:启动参数列表在内存中的位置bd- bi_boot_paramstheKernel (0, bd-bi_arch_number, bd-bi_boot_params);//嵌入式linux应用开发P264 bd-bi_boot_params就是标记列表的开始地址。}///image.h/*all data in network byte order (aka natural aka bigendian)/typedef struct image_header {uint32_t ih_magic; /Image Header Magic Number/ /镜像幻数/uint32_t ih_hcrc; /Image Header CRC Checksum/ /镜像头CRC校验值*/uint32_t ih_time; /* Image Creation Timestamp/ /镜像创建时间*/uint32_t ih_size; /* Image Data Size//镜像大小*/uint32_t ih_load; /* Data Load Address//数据加载地址*/uint32_t ih_ep; /* Entry Point Address/ //theKernel函数指针指向这个地址也就是从uboot跳到内核的地址,镜像入口*/uint32_t ih_dcrc; /* Image Data CRC Checksum/ /镜像数据区的CRC校验值*/uint8_t ih_os; /* Operating System//操作系统类型*/uint8_t ih_arch; /* CPU architecture//CPU架构*/uint8_t ih_type; /* Image Type/ /镜像类型*/uint8_t ih_comp; /* Compression Type/ /压缩类型*/uint8_t ih_name[IH_NMLEN]; /* Image Name//镜像名*/} image_header_t;Linux编译出的二进制文件是zImageuboot中提供mkimage工具可将zImage制作成uImage实际上就是在zImage前加一个image_header头。制作uImage的命令如下。./mkimage -n ‘linux-2.6.36’ -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage.binMkimage工具参数的含义如下-A 设置体系架构类型-O 设置操作系统类型-T 设置镜像类型-C 设置压缩类型-a 设置加载地址-e 设置镜像入口位置-n 设置镜像名-d 设置生成最终镜像所需的文件-x 设置片上执行

相关文章:

uboot之do_bootm_linux启动内核函数源码解析

当配置了CONFIG_PPC时将调用common/cmd_bootm.c中的do_bootm_linux。本处是调用libarm/armlinux.c中的。 u-boot.h中 static struct tag params; typedef struct bd_info { int bi_baudrate; / serial console baudrate /波特率 unsigned long bi_ip_addr; / IP Address /即服务…...

头歌平台实战:如何通过预防性维护避免斐波那契数列计算的性能陷阱

头歌平台实战:斐波那契数列计算的性能优化与预防性维护 在编程学习与算法实践中,斐波那契数列计算是一个经典案例。它不仅帮助我们理解递归与迭代的区别,更是性能优化和代码维护的绝佳教材。本文将从头歌平台的实际任务出发,深入探…...

**开源项目教程:探索`awesome-campus-expert`**

开源项目教程:探索awesome-campus-expert 【免费下载链接】awesome-campus-expert 🕶 An awesome list of resources for campus experts! 🕶 项目地址: https://gitcode.com/gh_mirrors/aw/awesome-campus-expert 1. 项目目录结构及介…...

Invest模型年产水量计算:从数据获取到结果导出的全流程实战

1. Invest模型年产水量计算入门指南 刚接触Invest模型的朋友们可能对这个强大的生态系统服务评估工具既好奇又困惑。作为一款由斯坦福大学自然资本项目组开发的免费开源工具,Invest模型能够帮助我们量化生态系统的各项服务价值,其中年产水量计算是最基础…...

GitHub_Trending/we/WeChatMsg常见错误排查:导出失败解决方案

GitHub_Trending/we/WeChatMsg常见错误排查:导出失败解决方案 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/w…...

明道云Webhook与ERP双向同步:手把手教你实现发货状态实时更新

明道云与ERP系统深度集成:Webhook双向同步实战指南 在数字化转型浪潮中,企业系统间的数据孤岛问题日益凸显。明道云作为国内领先的低代码平台,与ERP系统的无缝对接成为众多企业提升运营效率的关键需求。本文将聚焦发货状态实时同步这一典型场…...

PC-DMIS最佳拟合坐标系实战:四种算法选择与避坑指南

PC-DMIS最佳拟合坐标系实战:四种算法选择与避坑指南 在精密制造领域,三坐标测量机(CMM)的测量精度直接影响产品质量控制的有效性。而坐标系作为测量的基准框架,其建立的准确性更是重中之重。当面对复杂零件或存在装配关系的特征组时&#xff…...

运用长尾关键词提升SEO效果与关键词优化策略解析

本文将深入探讨长尾关键词在提升SEO效果和关键词优化策略中的重要性。长尾关键词不仅帮助网站更好地匹配用户的搜索意图,还能在竞争激烈的市场中脱颖而出。我们会分析当前最佳实践,让您了解到如何高效地挖掘与应用这些关键词,从而提升您的内容…...

uboot网络配置避坑指南:为什么你的tftpserver总是ping不通?

U-Boot网络配置深度解析:从Ping不通到高效TFTP传输的终极指南 在嵌入式开发的世界里,U-Boot作为系统启动的"第一道门",其网络配置的稳定性直接影响着开发效率。当你在深夜加班调试,准备通过TFTP快速加载内核镜像时&…...

K3s容器健康检查配置:确保应用高可用性的完整指南 [特殊字符]

K3s容器健康检查配置:确保应用高可用性的完整指南 🚀 【免费下载链接】k3s K3s 是一个轻量级的 Kubernetes 发行版,用于在资源受限的环境和物联网设备上部署 Kubernetes 群集。 * 轻量级的 Kubernetes 发行版、在资源受限的环境和物联网设备上…...

【Autosar Can Sample】第二章之Ecuc模块配置实战:从PDU管理到硬件交互

1. Ecuc模块配置的核心逻辑 第一次接触Autosar的Ecuc模块时,我完全被它复杂的配置项搞懵了。直到在实际项目中踩过几次坑才明白,Ecuc本质上就是个"交通警察",负责协调各个模块间的数据流动。举个例子,就像城市交通系统中…...

终极Lorri教程:如何简化Nix Shell管理并提升开发效率

终极Lorri教程:如何简化Nix Shell管理并提升开发效率 【免费下载链接】lorri Your projects nix-env 项目地址: https://gitcode.com/gh_mirrors/lo/lorri Lorri是一款强大的Nix Shell管理工具,专为项目开发设计,能够替代传统的nix-sh…...

H3C三层链路聚合实战:路由场景下的高可用配置与故障恢复

1. 为什么需要三层链路聚合? 在企业网络的核心层或数据中心互联场景中,单条物理链路的带宽和可靠性往往无法满足业务需求。想象一下高速公路上的单车道突然封闭,所有车辆只能原地等待——这就是传统单链路网络的痛点。H3C的Route-Aggregation…...

为什么老项目必须升级Apache Commons Collections?从CC1链看第三方库的安全风险

为什么企业级Java项目必须紧急升级Apache Commons Collections? 当技术团队还在为业务需求疲于奔命时,一个潜伏在老旧组件中的"定时炸弹"可能随时引爆——Apache Commons Collections反序列化漏洞(CVE-2015-7501)至今仍…...

探秘UI宝盒:18个顶级UI片段让你的前端开发效率提升300%

探秘UI宝盒:18个顶级UI片段让你的前端开发效率提升300% 【免费下载链接】ui-snippets A collection of UI Snippets. 项目地址: https://gitcode.com/gh_mirrors/ui/ui-snippets 你还在为重复编写按钮动画、加载效果而浪费时间吗?还在为UI交互细节…...

Navicat Premium连接Oracle 11g保姆级教程(附instantclient配置避坑指南)

Navicat Premium连接Oracle 11g全流程指南与疑难解析 作为一名长期与Oracle数据库打交道的开发者,我深知Navicat Premium作为一款强大的数据库管理工具,在连接Oracle 11g时可能会遇到的各种"坑"。特别是instantclient配置和oci.dll问题&#…...

WineskinServer:一款强大的跨平台应用程序运行器

WineskinServer:一款强大的跨平台应用程序运行器 【免费下载链接】WineskinServer 项目地址: https://gitcode.com/gh_mirrors/wi/WineskinServer 项目基础介绍和主要编程语言 WineskinServer 是一个开源项目,旨在为 macOS 用户提供一个用户友好…...

WineskinServer常见问题解决方案

WineskinServer常见问题解决方案 【免费下载链接】WineskinServer 项目地址: https://gitcode.com/gh_mirrors/wi/WineskinServer 项目基础介绍 WineskinServer 是一个基于 Wine 技术构建的开源工具,专注于为 macOS 用户提供友好的接口,以便封装…...

Jitsi Meet安全配置最佳实践:从基础设置到高级防护

Jitsi Meet安全配置最佳实践:从基础设置到高级防护 【免费下载链接】jitsi-meet Jitsi Meet - Secure, Simple and Scalable Video Conferences that you use as a standalone app or embed in your web application. 项目地址: https://gitcode.com/GitHub_Trend…...

Dioxus应用状态管理:从简单到复杂应用的演进

Dioxus应用状态管理:从简单到复杂应用的演进 【免费下载链接】dioxus 该全栈图形用户界面(GUI)库可用于开发桌面、Web、移动设备以及更多平台上的应用程序。 项目地址: https://gitcode.com/GitHub_Trending/di/dioxus Dioxus作为全栈…...

Apktool实战应用:Android应用逆向工程案例

Apktool实战应用:Android应用逆向工程案例 【免费下载链接】Apktool A tool for reverse engineering Android apk files 项目地址: https://gitcode.com/GitHub_Trending/ap/Apktool Apktool是一款强大的Android应用逆向工程工具,能够帮助开发者…...

C# MVP架构力位移曲线监控源码:工业应用上位机开发实战,包含通信与数据监控处理功能

C# MVP架构力位移曲线监控源码! 1,完整工程,完整应。 2,现场实战项目,vs2015开发。 3,用到dev控件,我会赠送。 4,完整yuan代码可编译,可修改,可debug。 5,这是一个工业应用上位机,下位机为plc。…...

计算机毕业设计之springboot校园失物招领系统

伴随着我国社会的发展,人民生活质量日益提高。于是对系统进行规范而严格是十分有必要的,所以许许多多的信息管理系统应运而生。此时单靠人力应对这些事务就显得有些力不从心了。所以本论文将设计一套校园失物招领系统,帮助学校进行失物招领、…...

谓词逻辑入门:5个常见误区及如何避免(离散数学学习指南)

谓词逻辑入门:5个常见误区及如何避免(离散数学学习指南) 刚接触离散数学的同学,往往会在谓词逻辑这一关遇到思维瓶颈。那种明明每个符号都认识,连起来却不知所云的感觉,就像在解一道没有已知条件的数学题。…...

UR六自由度机械臂运动学解析与轨迹优化:Python/C实现与Webots仿真实战

1. UR六自由度机械臂运动学基础 六自由度机械臂是工业自动化领域的核心设备,其中UR(Universal Robots)系列因其高精度和灵活性备受青睐。要真正掌握机械臂控制,运动学分析是绕不开的第一道门槛。记得我第一次接触UR5机械臂时&…...

快速部署nanobot:超轻量AI助手打造个人QQ智能问答系统

快速部署nanobot:超轻量AI助手打造个人QQ智能问答系统 1. 引言:你的个人AI助手,从部署到聊天只需10分钟 你是否想过拥有一个专属的AI助手,不仅能回答你的技术问题,还能直接帮你查看服务器状态,甚至集成到…...

从2038年到2106年:STM32无符号时间戳的隐藏优势与实战应用

从2038年到2106年:STM32无符号时间戳的隐藏优势与实战应用 在嵌入式系统开发领域,时间管理一直是确保系统长期稳定运行的关键因素。对于需要连续工作数十年的工业设备、基础设施监控系统而言,时间戳的处理方式直接影响着系统的生命周期。传统…...

Spring Boot 2.6+与Swagger兼容性实战:规避WebMvcPatternsRequestConditionWrapper NPE陷阱

1. 问题背景:当Spring Boot 2.6遇上Swagger 最近在升级Spring Boot到2.6版本后,很多开发者都遇到了一个让人头疼的问题:应用启动时突然抛出WebMvcPatternsRequestConditionWrapper.getPatterns的NPE(NullPointerException&#xf…...

DeepSeekai文游指令300➕最新最全 古代、哨向、现代、西幻、诡异、修仙、系统穿越、末日生存、复仇重生、现代校园、后宫宅斗、斗罗大陆、………(板块特别多写不过来啦)

DeepSeekai文游指令300➕最新最全 古代、哨向、现代、西幻、诡异、修仙、系统穿越、末日生存、复仇重生、现代校园、后宫宅斗、斗罗大陆、………(板块特别多写不过来啦) 美化指令、美化界面合集、chatbox安装教程 云朵、莓莓、DD等等……我的数据库涵盖了…...

CTFHUB彩蛋逆向工程:用BurpSuite破解工具页面的404陷阱

CTFHUB彩蛋逆向工程:用BurpSuite破解工具页面的404陷阱 在网络安全竞赛中,逆向工程常常需要突破常规思维,从看似无用的404错误页面中寻找隐藏线索。本文将深入剖析如何利用BurpSuite这一专业工具,通过流量拦截与分析技术&#xff…...