u-boot第二阶段代码(仅启动linux)

来源:互联网 发布:淘宝店网页制作 编辑:程序博客网 时间:2024/06/07 07:26

主函数文件main.c

/*  *文件名:  main.c  *作者:  李炼  *时间: 2014.07.22  *功能:u-boot第二阶段代码,引导linux启动*/#include "main.h"#include "type.h"#include "common.h"#include "setup.h"//static int is_auto_run_cmd;static struct tag *params;        //全局参数存放结构体void dara_main(void){/* 浜伅 */       int i;       GPBCON = 0x0157ff;       GPBDAT = 0x0000;                     /* 0xF0 CLOSE LED *//*0、设置串口*/ini_uart();uart_put_char('a');                      //单个字符输出测试uart_put_char('b');puts("\r\n");//回车换行print_tag(); //字符串输出void (*theKernel)(int zero, int arch, unsigned int params);   //存放真正内核的第一个函数        volatile unsigned int *p = (volatile unsigned int *)0x30008000;       /*1、从NAND读内核到SDRAM*/printf("Copy kernel from nand flash \r\n");nand_read_ll_lp(0x30008000,0x00200000,0x00300000);//puthex(0x1234ABCD);//puts("\n\r");//puthex(*p);//puts("\n\r");/*2、设置参数*/printf("Setup boot params \r\n");setup_start_tag ();setup_memory_tags ();setup_commandline_tag ("noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0");setup_end_tag ();/*3、跳转执行*/printf("Boot Kernel...\r\n");theKernel = (void (*)(int, int,unsigned int))0x30008000;theKernel(0,168,0x30000100);           /*  * mov r0,#0  * ldr   r1, =168       //TQ2440对应机器码168  * ldr   r2, =0x30000100        //全局参数的存放起始地址  * mov pc,#0x30008000        */         printf("Error!\n\r"); /*程序无异常,不会到达此处*/         //return -1;}void  setup_start_tag(void){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);}void  setup_memory_tags(void){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);}int stringlen(char * str){int i=0;while(str[i]){              i++;}return i;}void stringcpy(char *dest,char *src){char *tmp = dest;while ((*dest++ = *src++) != '\0');}void setup_commandline_tag(char *cmdline){int len = stringlen(cmdline) + 1; params->hdr.tag = ATAG_CMDLINE;params->hdr.size =(sizeof (struct tag_header) + len+3) >> 2;stringcpy (params->u.cmdline.cmdline, cmdline);params = tag_next(params);}void  setup_end_tag(void){params->hdr.tag = ATAG_NONE;params->hdr.size = 0;}/*void puthex(unsigned int val){ int i; int j;puts("0x");for(i=0;i<8;i++){j = (val >> ((7-i)*4)) &0xf;if((j >= 0) && (j <= 9))uart_put_char('0' + j);elseuart_put_char('A' + j - 0xa);     }}*/void ini_uart(void){int i;    GPHCON = 0x00faaa;    GPHUP  = 0x7ff;for(i=0;i<100;i++);    UFCON0 = 0x0;  /*FIFO disable*/    UMCON0 = 0x0;  /* 绂佺敤AFC妯″紡 */    ULCON0 = 0x03; /* 鏅€氭ā寮?鏃犳牎楠屼綅,1涓仠姝綅,8浣嶅抚 */    UCON0  = 0x245; /* 寰堝璁剧疆...娉㈢壒鐜囦娇鐢ㄧ殑鏃堕挓婧愭槸PCLK */    UBRDIV0 = ((long)(50000000 / 16./115200+0.5) - 1); /* Baud-Rate */for(i=0;i<100;i++);}void delay(int value){    volatile int j=0;    while(j++ < value)    {        volatile int i=0x1FFFF;        while(i--);    }}void uart_put_char(u8 c){        int i;    while(!(UTRSTAT0 & 0x2));    UTXH0 = c;    }u8 uart_get_char(void){    while(!(UTRSTAT0 & 0x1));    return URXH0;}   void puts(u8 *str){         int i;    while(*str)    {        uart_put_char(*str++);    }}#if 0void gets(char *str){    volatile unsigned char tmp_char;    volatile char *tmp_buff = str;    while((tmp_char = uart_get_char())){        if(is_auto_run_cmd){            is_auto_run_cmd = 0;            printf("\r\ns3c2440 # ");        }        switch(tmp_char){            case 0x7F:    //delete                backspace:    if(tmp_buff > str){                    tmp_buff--;                    uart_put_char(0x08);  //退格                    uart_put_char(0x1B);  //escape 溢出                    uart_put_char(0x5B);  //"["                    uart_put_char(0x4A);  //'J'                }                break;            case 0x08:                goto backspace;                break;        case 0x0D:                goto gets_finish;                break;            case 0x1B:                uart_get_char();                char dire = uart_get_char();                break;            default:        uart_put_char(tmp_char);                *tmp_buff++ = tmp_char;               break;        }    }    gets_finish:    *tmp_buff = 0;}#endifvoid print_tag(void){    printf("************************************************************\r\n");    printf("*                                                          *\r\n");    printf("*                     Hello World !                        *\r\n");    printf("*                   writer :Li Lian                        *\r\n");    printf("*                   date :2014.07.22                       *\r\n");    printf("*                                                          *\r\n");    printf("************************************************************\r\n");}


 

文件setup.h

/* *  linux/include/asm/setup.h * *  Copyright (C) 1997-1999 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * *  Structure passed to kernel to tell it about the *  hardware it's running on.  See linux/Documentation/arm/Setup *  for more info. * * NOTE: *  This file contains two ways to pass information from the boot *  loader to the kernel. The old struct param_struct is deprecated, *  but it will be kept in the kernel for 5 years from now *  (2001). This will allow boot loaders to convert to the new struct *  tag way. */#ifndef __ASMARM_SETUP_H#define __ASMARM_SETUP_H/* * Usage: *  - do not go blindly adding fields, add them at the end *  - when adding fields, don't rely on the address until *    a patch from me has been released *  - unused fields should be zero (for future expansion) *  - this structure is relatively short-lived - only *    guaranteed to contain useful data in setup_arch() */#define COMMAND_LINE_SIZE 1024/* This is the old deprecated way to pass parameters to the kernel */struct param_struct {    union {struct {    unsigned long page_size;/*  0 */    unsigned long nr_pages;/*  4 */    unsigned long ramdisk_size;/*  8 */    unsigned long flags;/* 12 */#define FLAG_READONLY1#define FLAG_RDLOAD4#define FLAG_RDPROMPT8    unsigned long rootdev;/* 16 */    unsigned long video_num_cols;/* 20 */    unsigned long video_num_rows;/* 24 */    unsigned long video_x;/* 28 */    unsigned long video_y;/* 32 */    unsigned long memc_control_reg;/* 36 */    unsigned char sounddefault;/* 40 */    unsigned char adfsdrives;/* 41 */    unsigned char bytes_per_char_h;/* 42 */    unsigned char bytes_per_char_v;/* 43 */    unsigned long pages_in_bank[4];/* 44 */    unsigned long pages_in_vram;/* 60 */    unsigned long initrd_start;/* 64 */    unsigned long initrd_size;/* 68 */    unsigned long rd_start;/* 72 */    unsigned long system_rev;/* 76 */    unsigned long system_serial_low;/* 80 */    unsigned long system_serial_high;/* 84 */    unsigned long mem_fclk_21285;       /* 88 */} s;char unused[256];    } u1;    union {char paths[8][128];struct {    unsigned long magic;    char n[1024 - sizeof(unsigned long)];} s;    } u2;    char commandline[COMMAND_LINE_SIZE];};/* * The new way of passing information: a list of tagged entries *//* The list ends with an ATAG_NONE node. */#define ATAG_NONE0x00000000struct tag_header {u32 size;u32 tag;};/* The list must start with an ATAG_CORE node */#define ATAG_CORE0x54410001struct tag_core {u32 flags;/* bit 0 = read-only */u32 pagesize;u32 rootdev;};/* it is allowed to have multiple ATAG_MEM nodes */#define ATAG_MEM0x54410002struct tag_mem32 {u32size;u32start;/* physical start address */};/* VGA text type displays */#define ATAG_VIDEOTEXT0x54410003struct tag_videotext {u8x;u8y;u16video_page;u8video_mode;u8video_cols;u16video_ega_bx;u8video_lines;u8video_isvga;u16video_points;};/* describes how the ramdisk will be used in kernel */#define ATAG_RAMDISK0x54410004struct tag_ramdisk {u32 flags;/* bit 0 = load, bit 1 = prompt */u32 size;/* decompressed ramdisk size in _kilo_ bytes */u32 start;/* starting block of floppy-based RAM disk image */};/* describes where the compressed ramdisk image lives (virtual address) *//* * this one accidentally used virtual addresses - as such, * its depreciated. */#define ATAG_INITRD0x54410005/* describes where the compressed ramdisk image lives (physical address) */#define ATAG_INITRD20x54420005struct tag_initrd {u32 start;/* physical start address */u32 size;/* size of compressed ramdisk image in bytes */};/* board serial number. "64 bits should be enough for everybody" */#define ATAG_SERIAL0x54410006struct tag_serialnr {u32 low;u32 high;};/* board revision */#define ATAG_REVISION0x54410007struct tag_revision {u32 rev;};/* initial values for vesafb-type framebuffers. see struct screen_info * in include/linux/tty.h */#define ATAG_VIDEOLFB0x54410008struct tag_videolfb {u16lfb_width;u16lfb_height;u16lfb_depth;u16lfb_linelength;u32lfb_base;u32lfb_size;u8red_size;u8red_pos;u8green_size;u8green_pos;u8blue_size;u8blue_pos;u8rsvd_size;u8rsvd_pos;};/* command line: \0 terminated string */#define ATAG_CMDLINE0x54410009struct tag_cmdline {charcmdline[1];/* this is the minimum size */};/* acorn RiscPC specific information */#define ATAG_ACORN0x41000101struct tag_acorn {u32 memc_control_reg;u32 vram_pages;u8 sounddefault;u8 adfsdrives;};/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */#define ATAG_MEMCLK0x41000402struct tag_memclk {u32 fmemclk;};struct tag {struct tag_header hdr;union {struct tag_corecore;struct tag_mem32mem;struct tag_videotextvideotext;struct tag_ramdiskramdisk;struct tag_initrdinitrd;struct tag_serialnrserialnr;struct tag_revisionrevision;struct tag_videolfbvideolfb;struct tag_cmdlinecmdline;/* * Acorn specific */struct tag_acornacorn;/* * DC21285 specific */struct tag_memclkmemclk;} u;};struct tagtable {u32 tag;int (*parse)(const struct tag *);};#define __tag __attribute__((unused, __section__(".taglist")))#define __tagtable(tag, fn) \static struct tagtable __tagtable_##fn __tag = { tag, fn }#define tag_member_present(tag,member)\((unsigned long)(&((struct tag *)0L)->member + 1)\<= (tag)->hdr.size * 4)#define tag_next(t)((struct tag *)((u32 *)(t) + (t)->hdr.size))#define tag_size(type)((sizeof(struct tag_header) + sizeof(struct type)) >> 2)#define for_each_tag(t,base)\for (t = base; t->hdr.size; t = tag_next(t))/* * Memory map description */#define NR_BANKS 8struct meminfo {int nr_banks;unsigned long end;struct {unsigned long start;unsigned long size;int           node;} bank[NR_BANKS];};extern struct meminfo meminfo;#endif

 

 

0 0
原创粉丝点击