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系统
***********************************************************/
/**********************************************************
*头文件
***********************************************************/
(很重要,加大仔细看,刚开始并不懂为什么要右移2位)
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;
}