[国嵌攻略][069][Bootm命令移植]
Bootloader作用
1.初始化软硬件
2.启动操作系统
内核分类
1.zImage 不加信息头的内核
2.uImage 加信息头后的内核,用bootm命令来启动
bootm作用
1.检测信息头:压缩、操作系统、幻数
2.根据OS信息调用相应的处理函数:获取内核地址、知道CPU型号、设置启动参数
代码编写
1.获取启动地址
2.设置启动参数
2.1设置核心启动参数
2.2设置内存参数
2.3设置命令行参数
2.4设置参数结束行标志
3.启动操作系统
/******************************************************************** *名称:bootm.c *作者:D *时间:2015.11.23 *功能:启动Linux系统 *********************************************************************/ /******************************************************************** *头文件 *********************************************************************/ #include "net.h" /******************************************************************** *宏定义 *********************************************************************/ #define KERNEL_ZERO 0 #define KERNEL_MACH 1999 //开发板ID,要与内核ID匹配 #define KERNEL_ADDR TFTP_DONWLOAD //内核地址 #define ATAG_ADDR 0x30000100 //标签地址 #define ATAG_CORE 0x54410001 //核心标签 #define ATAG_MEM 0x54410002 //内存标签 #define ATAG_CMDLINE 0x54410009 //命令标签 #define ATAG_NONE 0x00000000 //结束标签 #define MEM_ADDR 0x30000000 //内存地址 #define MEM_SIZE 0x04000000 //内存大小 #define tag_size(type) ( (sizeof(struct tag_header)+sizeof(struct type))>>2 ) //计算标签大小,除以4表示标签大小以4字节计算,用于移动标签指针 #define tag_next(type) ( (struct tag *)((unsigned int *)(type)+(type)->hdr.size) ) //移动标签指针 /******************************************************************** *类型定义 *********************************************************************/ struct tag_header { unsigned int size; unsigned int tag; }; struct tag_core { unsigned int flags; unsigned int pagesize; unsigned int rootdev; }; struct tag_mem32 { unsigned int size; unsigned int start; }; struct tag_cmdline { char cmdline[1]; }; struct tag{ struct tag_header hdr; union{ struct tag_core core; struct tag_mem32 mem; struct tag_cmdline cmdline; }u; }; struct tag *params; /******************************************************************** *全局变量声明 *********************************************************************/ const char *cmdline = "noinitrd console=ttySAC0,115200 init=/init root=/dev/nfs rw nfsroot=192.168.1.101:/space/temp/nfs ip=192.168.1.230:192.168.1.101:192.168.1.1:255.255.255.0::eth0:off"; /******************************************************************** *函数原型声明 *********************************************************************/ void do_bootm_linux(); void setup_core_tag(); void setup_memory_tag(); void setup_cmdline_tag(); void setup_end_tag(); /******************************************************************** *名称:do_bootm_linux *参数: * none *返回: * none *功能:启动Linux系统 *********************************************************************/ void do_bootm_linux(){ void (*theKernel)(int zero, int arch, unsigned int params); //内核函数指针 //设置启动地址 theKernel = (void (*)(int, int, unsigned int))KERNEL_ADDR; //将地址转换为函数指针 //设置启动参数 setup_core_tag(); //设置核心参数 setup_memory_tag(); //设置内存参数 setup_cmdline_tag(); //设置命令参数 setup_end_tag(); //设置结束标志 //启动操作系统 theKernel(KERNEL_ZERO, KERNEL_MACH, ATAG_ADDR); //不再返回 } /******************************************************************** *名称:setup_core_tag *参数: * none *返回: * none *功能:设置核心参数 *********************************************************************/ void setup_core_tag(){ //设置标签地址 params = (struct tag *)ATAG_ADDR; //设置核心参数 params->hdr.tag = ATAG_CORE; params->hdr.size = tag_size(tag_core); params->u.core.flags = 0; params->u.core.pagesize = 4096; params->u.core.rootdev = 0; //移动标签地址 params = tag_next(params); } /******************************************************************** *名称:setup_memory_tag *参数: * none *返回: * none *功能:设置内存参数 *********************************************************************/ void setup_memory_tag(){ //设置内存参数 params->hdr.tag = ATAG_MEM; params->hdr.size = tag_size(tag_mem32); params->u.mem.start = MEM_ADDR; params->u.mem.size = MEM_SIZE; //移动标签地址 params = tag_next(params); } /******************************************************************** *名称:setup_cmdline_tag *参数: * none *返回: * none *功能:设置命令参数 *********************************************************************/ void setup_cmdline_tag(){ //设置命令参数 params->hdr.tag = ATAG_CMDLINE; params->hdr.size = (sizeof(struct tag_header)+strlen(cmdline)+1+4)>>2; //'+1'表示字符结束标志'\0', '+4'表示除以4转换成整型时向上取整 strcpy(params->u.cmdline.cmdline, cmdline); //移动标签地址 params = tag_next(params); } /******************************************************************** *名称:setup_cmdline_tag *参数: * none *返回: * none *功能:设置结束标志 *********************************************************************/ void setup_end_tag(){ params->hdr.tag = ATAG_NONE; params->hdr.size = 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术