通过移植bootm命令启动已经编译好…
来源:互联网 发布:淘宝运营每天做什么 编辑:程序博客网 时间:2024/05/22 09:32
首先在移植bootm命令之前,我们要了解bootloader的主要作用;除了初始化cpu和外设外,bootloader还有一个最大的作用就是启动Linux内核。但是在启动Linux内核之前,有几个部分是必须先初始化的
1.初始化内存
2.初始化串口(其实也不是必须的,但可以方便看输出,检查错误)
3.获取处理器型号(这里我们就只用一个处理器,所以不用去检测)
4.设置Linux启动参数
我们把Linux的启动参数设置在内存的一个区域里,然后在启动Linux内核之前先把设置启动参数的指针指向这个地址,完成参数设置;最后调用Linux内核映像
所以下面开始讲解启动Linux内核的函数boot_linux()
首先,参照uboot,设置一个指针theKernel来获得Linux内核的启动地址(到时候把Linux内核下载到这个位置)
void (*theKernel)(int , int , unsigned int );
这个指针没有类型,只是它可以指向一个地址的函数,这个函数的参数必须是(int,int,unsignedint),所以在使用内存里的地址时,必须进行强制类型转换
theKernel = (void (*)(int ,int ,unsignedint))SDRAM_KERNEL_START;
其中SDRAM_KERNEK_START是我们下载Linux内核的地址,也就是内核的基地址,我们把内核看做一个很大的函数,这个地址就是该函数的起始地址,而这个函数的参数类型是(int,int ,unsignedint),而我们用的Linux内核的这三个参数分别为0,CPU的型号(一个关于CPU的参数),Linux启动参数的基地址
接下来就要分别设置核心启动参数,内存启动参数,命令行启动参数,结束标志参数
1.设置核心启动参数setup_core_tag();
首先定义一个类型tag
struct tag {
struct tag_header hdr;
union {
struct tag_core core;
struct tag_mem32 mem;
struct tag_cmdline cmdline;
} u;
};
其中
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];
};
然后参照uboot,对其进行改写
struct tag *pCurTag;
void setup_core_tag()
{
pCurTag = (struct tag *)SDRAM_TAGS_START;
pCurTag->hdr.tag = ATAG_CORE;
pCurTag->hdr.size = tag_size(tag_core);
pCurTag->u.core.flags = 0;
pCurTag->u.core.pagesize = 4096;
pCurTag->u.core.rootdev = 0;
pCurTag = tag_next(pCurTag);
}
2.3.4对内存,命令行,结束标志的参数同理
void setup_mem_tag()
{
pCurTag->hdr.tag = ATAG_MEM;
pCurTag->hdr.size = tag_size(tag_mem32);
pCurTag->u.mem.start = SDRAM_ADDR_START;
pCurTag->u.mem.size = SDRAM_TOTAL_SIZE;
pCurTag = tag_next(pCurTag);
}
void setup_cmdline_tag()
{
int linelen = strlen(cmdline);
pCurTag->hdr.tag = ATAG_CMDLINE;
pCurTag->hdr.size = (sizeof (struct tag_header) +strlen(cmdline) + 1 + 4) >> 2;
strcpy (pCurTag->u.cmdline.cmdline, cmdline);
pCurTag = tag_next (pCurTag);
}
void setup_end_tag()
{
pCurTag->hdr.tag = ATAG_NONE;
pCurTag->hdr.size = 0;
}
最后调用Linux内核(这个大函数),函数名就是这个void指针指向的地址,参数(int,int,unsignedint)
theKernel(0, 1626, SDRAM_TAGS_START);
其中SDRAM_TAGS_START为第一个设置的启动参数,核心启动参数的基地址,后面的参数都是紧挨着的,这样就把CPU型号,启动参数的基地址告诉内核了
附上启动代码
#include "string.h"
#include "atag.h"
#define SDRAM_KERNEL_START 0x51000000
#define SDRAM_TAGS_START 0x50000100
#define SDRAM_ADDR_START 0x50000000
#define SDRAM_TOTAL_SIZE 0x16000000
void (*theKernel)(int , int , unsigned int );
struct tag *pCurTag;
const char *cmdline = "console=ttySAC0,115200init=/init";
void setup_core_tag()
{
pCurTag = (struct tag *)SDRAM_TAGS_START;
pCurTag->hdr.tag = ATAG_CORE;
pCurTag->hdr.size = tag_size(tag_core);
pCurTag->u.core.flags = 0;
pCurTag->u.core.pagesize = 4096;
pCurTag->u.core.rootdev = 0;
pCurTag = tag_next(pCurTag);
}
void setup_mem_tag()
{
pCurTag->hdr.tag = ATAG_MEM;
pCurTag->hdr.size = tag_size(tag_mem32);
pCurTag->u.mem.start = SDRAM_ADDR_START;
pCurTag->u.mem.size = SDRAM_TOTAL_SIZE;
pCurTag = tag_next(pCurTag);
}
void setup_cmdline_tag()
{
int linelen = strlen(cmdline);
pCurTag->hdr.tag = ATAG_CMDLINE;
pCurTag->hdr.size = (sizeof (struct tag_header) +strlen(cmdline) + 1 + 4) >> 2;
strcpy (pCurTag->u.cmdline.cmdline, cmdline);
pCurTag = tag_next (pCurTag);
}
void setup_end_tag()
{
pCurTag->hdr.tag = ATAG_NONE;
pCurTag->hdr.size = 0;
}
void boot_linux()
{
theKernel = (void (*)(int , int , unsignedint))SDRAM_KERNEL_START;
setup_core_tag();
setup_mem_tag();
setup_cmdline_tag();
setup_end_tag();
theKernel(0, 1626, SDRAM_TAGS_START);
}
附上头文件
#define ATAG_CORE 0x54410001
#define ATAG_MEM 0x54410002
#define ATAG_CMDLINE 0x54410009
#define ATAG_NONE 0x00000000
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;
};
#define tag_size(type) ((sizeof(struct tag_header) +sizeof(struct type)) >> 2)
#define tag_next(t) ((struct tag *)((unsigned long *)(t) +(t)->hdr.size))
阅读全文
0 0
- 通过移植bootm命令启动已经编译好…
- 移植 bootm 命令启动内核
- 四十二.移植bootm命令
- bootm命令移植
- bootm命令移植
- uboot使用bootm启动内核命令
- 如何通过Intent启动一个已经安装好的APP
- Bootm命令
- bootm命令
- bootm命令
- Uboot通过bootm命令向内核传递MAC地址
- Uboot通过bootm命令向内核传递MAC地址
- bootm内核的启动
- bootm命令分析
- bootm命令解析
- 删除已经编译好的内核
- u-boot bootm命令浅析
- uboot之bootm命令分析
- Linux程序地址分布
- Linux静态函数库的使用和制作/动态…
- $(window).on("load",function(){}和$(function(){})区别
- main函数的两个参数
- NYOJ:17-单调递增最长子序列
- 通过移植bootm命令启动已经编译好…
- main函数的两个参数使用
- 通过信号量达到进程对资源占用的互…
- 信号量同步编程
- 创建文件&复制文件&删除文件
- OK6410ping通Linux虚拟机
- linux进程间通信-------共享内存
- linux进程间通信-------消息队列
- synchronized与static synchronized 的区别