| 
 (2) boot_prep  
    依旧查看imx-bootlets-src/boot_prep 目录下的link.lds  
-   OUTPUT_ARCH(arm)
 -   ENTRY(_start)
 -   SECTIONS
 -   {
 -    . = 0x00000000;
 -    . = ALIGN(4);
 -    .text : { *(.text) }
 -    .data : { *(.data) }
 -    .bss : { *(.bss) }
 -   }
 
 
  
 
link.lds和powe_prep下的link.lds一样,毫无压力,你们懂得。  
代码到此将进入boot_prep的_start() 过程很简单,结果很完美。  
  
    1:设置RAM为DDR2模式     2:设置CPU CLK      3:设置DDR2 的频率为166MHZ     4:测试RAM  
  
设置完全就是寄存器的配置。这里就不一一分析了,参照数据手册很好就明白了。 这里测试RAM的方法很简单, volatile int *pTest = 0x40000000; 向0x40000000写入1000个数,在读出来,没有错误就说明RAM正常。  
 
 
  
(3) linux_prep  
  
   向kernel传递正确的参数,引导linux kernel。设置好标记列表后就要调用内核了。但调用内核前,CPU寄存器的设置必须满足下面的条件:   Ø r0=0   Ø r1=机器码   Ø r2=内核参数标记列表在RAM中的起始地址 imx-bootlets-src/linux_prep/core/entry.S 承载着这一使命。  
  
_start: stmdbsp!, {r4-r12, lr} /* Check entry counter */ ldrr4, entry_count cmpr4, #0 bnestart_kernel //如果从休眠启动内核,entry_count > 0跳到try_to_resume;  //否则entry_count = 0;直接start_kernel bltry_to_resume /* Update counter to show we were here */ addr4, r4, #1 strr4, entry_count //增加entry_count,用以标示内核从什么状态启动。 /* Return to ROM */ ldmiasp!, {r4-r12, lr} bxlr //在来看看start_kernel 做了哪些工作呢? start_kernel: blclear_bss //首选清除BBS段,如果不清除,以后程序会出现执行错误 /* Initialize HW modules relevant for linux_prep */ blhw_init /* Setup tags for Linux kernel and save tags pointer in r2 */ blsetup_tags movr2, r0 //R2里面保持了内核启动参数的地址, r0里面存储的是setup_tags()的返回值。 //即内核启动参数的地址 //setup_tags()函数式用C语言编写,设置启动内核的参数 /* Store machine id in r1 */ ldrr1, =MACHINE_ID //R1保持了MX28_EVK的ID //其实就是个数字 #define  MACHINE_ID2531 /* Zero r0 register */ movr0, #0 //当然要清除R0了,这个启动内核前的需求。 /* Jump to Linux kernel */ ldrlr, =KERNEL_BASE_ADDRESS movpc, lr //跳到内核代码处,将执行内核代码的自解压程序 //如果从休眠状态启动内核,就跳到 try_to_resume .   
 
 
 
 
    设置启动内核的参数  
  
u32 setup_tags (void) {     enum magic_key magic_key;     magic_key = get_magic_key();     find_command_lines();     setup_start_tag();     setup_mem_tag();     setup_initrd_tag();     setup_cmdline_tag(cmdlines[magic_key]);     setup_end_tag();     return (u32)ATAGS_BASE_ADDRESS; }  
 
  
 
(1)setup_start_tag函数 static void setup_start_tag (bd_t *bd) { params = (struct tag*)ATAGS_BASE_ADDRESS; /* 内核的参数的开始地址 */          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); } 标记列表必须以ATAG_CORE开始,setup_start_tag函数在内核的参数的开始地址设置了一个ATAG_CORE标记。 (2)setup_memory_tags函数 static void setup_memory_tags (bd_t *bd) { params->hdr.tag = ATAG_MEM; params->hdr.size = tag_size(tag_mem32); params->u.mem.start = SDRAM_BASE; params->u.mem.size = get_sdram_size(); params = tag_next(params); } setup_memory_tags函数设置了一个ATAG_MEM标记,该标记包含内存起始地址,内存大小这两个参数。 (3)setup_initrd_tag函数 static void setup_initrd_tag(void) { params->hdr.tag = ATAG_INITRD2 ; params->hdr.size = tag_size(tag_initrd); params->u.initrd.start = 0x40400000; params->u.initrd.size =  0x00400000; params = tag_next(params); } 设置了 ramdisk image 的起始物理地址和大小。 (4)setup_end_tag函数 static void setup_end_tag (bd_t *bd) { params->hdr.tag = ATAG_NONE; params->hdr.size = 0; } 标记列表必须以标记ATAG_NONE结束,setup_end_tag函数设置了一个ATAG_NONE标记,表示标记列表的结束。 ldrlr, =KERNEL_BASE_ADDRESS movpc, lr 接下来,将KERNEL_BASE_ADDRESS 传递给PC指针,将代码控制权交给linux kernel。Boot-stream 精彩的生命到此结束了,留下了OS的各种膜拜和感激,让OS去走它自己的路吧。相信它会走的更好。  
四:IMX28-EVK编译bootlets. 直接启动linux 这种方法需要将生产的zImage镜像制成imx28_linux.sb镜像imx28_linux.sb镜像是对zImage镜像做了些加工,为zImage的运行准备环境。 在编译boot-stream前假定已经安装好了整个开发环境(ltib).如果没有安装,请参照宁一篇** 《Freescale Imx28 开发环境的搭建 》          #mkdir boot-stream      #cd boot-stream      #sudo tar xvfz /opt/freescale/pkgs/imx-bootlets-src     # cp  ~/linux/arch/arm/boot/zImage  ./imx-bootlets-src/     #make CROSS_COMPILE=    /opt/freescale/usr/local/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-      linux-gnueabi-     BOARD=iMX28_EVK    注意,这里可能会出现如下错误     elftosb2 -z -c ./linux_prebuilt.db -o imx28_linux.sb     make: elftosb2: Command not found     可能是环境设置不对,在这里为了图方便,直接cp /opt/freescale/ltib/usr/bin/elftosb2      到 imx-bootlets-src下。当然你也可以用export 导出环境变量。     编译完成后将生成imx28-linux.sb。这个就是将要烧写的linux。     然后插入SD卡,利用ltib提供的mk_hdr.sh 烧写进SDCARD就行.     #cp  imx28-linnux.sb  ~/ltib/rootfs/boot      #cd  ~/ltib     #./mk_hdr.sh  /dev/sdx       //sdx插入的SDCARD,sdb. 在烧写前,需要先umount SD卡。 烧写完成将SDCARD插入到IMX28-EVK的socket 0 。按下power,启动linux。Enjoy it!!! 到这里boot-stream 的讲解也ALT+F4了,不过探索linux的路才刚刚起步。  
 |