注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小白的博客

嵌入式爱好者

 
 
 

日志

 
 

最小bootloader程序之boot.c  

2012-08-09 18:23:23|  分类: 韦东山视频第二轮 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
#include "setup.h"
#define GPHCON (*(volatile unsigned long *)0x56000070)
#define ULCON0 (*(volatile unsigned long *)0x50000000)
#define UCON0 (*(volatile unsigned long *)0x50000004)
#define UFCON0 (*(volatile unsigned long *)0x50000008)
#define UBRDIV0 (*(volatile unsigned long *)0x50000028)
#define UTRSTAT0 (*(volatile unsigned long *)0x50000010)
#define UTXH0 (*(volatile unsigned long *)0x50000020)
#define URXH0 (*(volatile unsigned long *)0x50000024)

static struct tag *params;

static void uart_init()
{
      GPHCON = (2<<2*2) | (2<<2*3);
      ULCON0 = 0x03 ;
      UCON0 = 0x05 ;
      UFCON0 = 0;
      UBRDIV0 = (50000000/(115200*16))-1 ;
}

void putc(unsigned char c)
{
    while(!(UTRSTAT0 & (1<<2)));
    UTXH0 = c ;
}

void puts(unsigned char *str)
{
    int i = 0;
    while(str[i])
        {
            putc(str[i]);
            i++;
        }
}

char strlen(const char * s)
{
const char *sc;

for (sc = s; *sc != '\0'; ++sc)
/* nothing */;
return sc - s;
}

char * strcpy(char * dest,const char *src)
{
char *tmp = dest;

while ((*dest++ = *src++) != '\0')
/* nothing */;
return tmp;
}

static void setup_start_tag ()
{
params = (struct tag *) 0x30000100 ;

params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);

params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;

params = tag_next (params);
}

static void setup_memory_tags ()
{
        params->hdr.tag = ATAG_MEM;
        params->hdr.size = tag_size (tag_mem32);

        params->u.mem.start = 0x30000000;
        params->u.mem.size = 64*1024*1024;

        params = tag_next (params);
}

static void setup_commandline_tag (char *commandline)
{

params->hdr.tag = ATAG_CMDLINE;
params->hdr.size =
(sizeof (struct tag_header) + strlen (commandline) + 1 + 3) >> 2;

strcpy (params->u.cmdline.cmdline, commandline);

params = tag_next (params);
}

static void setup_end_tag ()
{
params->hdr.tag = ATAG_NONE;
params->hdr.size = 0;
}

int main(void) 
{
    void (*theKernel)(int,  int, unsigned int);
    uart_init();
    puts("uart_init\n\r");
    
    puts("read kernel to 0x30008000\n\r");
    nand_read(0x60000+64,(unsigned char *)0x30008000,0x200000);

    puts("set params\n\r");
    setup_start_tag ();
    setup_memory_tags();
    setup_commandline_tag ("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");
    setup_end_tag();
    
    puts("go to the kernel\n\r");
    theKernel = (void(*)(int,  int, unsigned int))0x30008000;
    theKernel(0 , 362 , 0x30000100 );
    
    return  -1 ;
}

关于这个文件有两点需要说明:
1、如何跳转:
我们将内核拷贝到内存某处,然后定义一个指针函数,这个函数指向内核的入口地址,当执行这个函数的时候,就跳转到了内核!!!
2、如何传递参数:
约定好参数的具体格式,然后设置参数。并将设置好的参数放在内存某处,我们上面定义的函数将负责将参数的地址告诉内核!!!另外需要说明的是,还要传递机器码!!!

  评论这张
 
阅读(639)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018