通过移植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))