首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

BootLoader —— S3C2440(2)

BootLoader —— S3C2440(2)

[url=][/url]
static void init_autorun_timer(int sec){U32 val = (PCLK>>4)/100-1;autorun_10ms = sec*100;pISR_TIMER4 = (U32)autorun_proc;rTCFG0 &= ~(0xff<<8);rTCFG0 |= 3<<8; //prescaler 1 = 3+1 ,for Timer 2,3,4rTCFG1 &= ~(0xf<<16);rTCFG1 |= 1<<16; //mux = 1/4 ,for Timer 4rTCNTB4 = val; //val = (PCLK>>4)/100-1rTCON &= ~(0xf<<20);rTCON |= 7<<20; //interval, inv-off, update TCNTB4&TCMPB4[占空比], start timer 4rTCON &= ~(2<<20); //clear manual update bitEnableIrq(BIT_TIMER4); //清0对应位,使能对应中断}static __irq void autorun_proc(void){ClearPending(BIT_TIMER4);if(autorun_ds) //自动运行标识位,为1时禁止自动运行;系统启动时有按键按下时为1  DisableIrq(BIT_TIMER4); //禁能对应中断autorun_10ms--;if(!autorun_10ms) //当中断一百次时执行下面的程序{  DisableIrq(BIT_TIMER4);  //CLR_IF(); //in irq service routine, irq is disabled  //autorun_trig = 1; //masked by lqm!  //NandLoadRun();  //NandLoadRun_wince();//added by lqm,2008-06-29 ?????????不能加载?????????  EnRunWINCE=1;}}[url=][/url]

中断程序中有个变量EnRunWINCE,默认为0.当autorun_10ms值减到0后,即定时的时间已到,
这时EnRunWINCE=1,后面的程序通过该变量判断时间到了,然后执行自动加载NK的代码。
具体代码如下:
if(EnRunWINCE){  NandLoadRun_wince();}

三:LCD设置

bootloader运行时可以附加显示开机图片,这就需要对LCD控制器的相关寄存器进行设置。
由于寄存器较多,这里不一一列举,仅给LCD显示的函数如下:
[url=][/url]
void LCD_Play(){U32 i,j,k;U32* palette;Lcd_Init();LcdBkLtSet( 70 ) ;//背光PWM设置Lcd_PowerEnable(0, 1);  Lcd_EnvidOnOff(1); //turn on vedio  for(k=0,j=0;j<LCD_YSIZE_TFT_320240;j++)  for(i=0;i<LCD_XSIZE_TFT_320240;i++)  {     PutPixel(i,j,ackj[k++]);     }}[url=][/url]


四:USB,MMU,ISR,DMA等寄存器的设置

这里尤其是USB和DMA的寄存器设置,由于下载BIN文件是通过USB走的DMA下载的,因此设置这些寄存器至关重要。相关寄存器实在太多,这里不一一列举。
五:EBOOT
核心代码如下:
while(1){  if(menuUsed==1)Menu();  WaitDownload();}
前面各寄存器初始化完成后,进入这个死循环,默认menuUsed=0,这时将执行函数WaitDownload()。
在WaitDownload()中,如果没有点击DNW的下载,这时没有检测到下载的BIN文件的大小,此时
downloadFileSize=0,这时执行下面的代码:
[url=][/url]
while(downloadFileSize==0){  //检测到USB连上后打印下面连接上的信息。  if(first==1 && isUsbdSetConfiguration!=0)  {  Uart_Printf("USB host is connected. Waiting a download.\n");//unmasked by lqm!  first=0;  }  //在没有按DNW下载时一个LED闪  if(j%0x100000==0)Led_Display(0x8);  if(j%0x100000==0x80000)Led_Display(0x0);  j++;  key=Uart_GetKey();  /*  if(autorun_trig) //Timer4倒计时到后autorun_trig置1,执行下面的函数。  AutoNandLoadRun(); //run it in svc mode  */  /****************************************************  ; 注意这里面的autorun_ds标识变量!  ; 当系统启动后没有键按下时,autorun_ds=0;  ; 此时timer4中断使能,通过中断自动运行系统;  ; 如果按下键后,则运行Menu()函数,显示具体  ; 的菜单供用户选择。  ; 这时autorun_ds=1,timer4中断禁能;  ; 系统不再自动加载。  ****************************************************/  if(key!=0)  {  autorun_ds = 1;  //printf("disable autorun\n");  Menu();  first=1;  //To display the message,"USB host ...."  //在串口下载返回后downloadFileSize不为0,因此不能再执行USB下载!  }  //在这里添加自动加载NK的程序!added by lqm,2009-06-29  if(EnRunWINCE)  {  NandLoadRun_wince();  }   }[url=][/url]

通过程序可以看到,此时LED会不停闪烁。
一旦通过DNW下载点击后,downloadFileSize将被赋值为下载的BIN文件或nb0文件的大小,不再为0,这个while循环将结束,程序继续往后运行,USB通过DMA将PC上的BIN或nb0文件下载到DRAM中。
在下载BIN或nb0文件时,开启定时器,用于计算下载整个文件所花的时间,并打印出来。
开始下载时,执行如下两个函数:
Timer_InitEx();   Timer_StartEx();
下载完后,执行如下函数:
time=Timer_StopEx();
下载一次所花的时间被保存在变量time中,并通过串口打印出来。
下载完后将执行数据校验,确保数据无误。
校验无误后,将根据前面是否选择下载并运行,如果下载时选择的下载并运行,这时将运行下载的程序。这里指下载到DRAM中才有这种功能。具体代码如下:
[url=][/url]
if(download_run==1){  register void(*run)(void); //使用寄存器变量以防止禁止DCACHE后数据不一致!!!  rINTMSK=BIT_ALLMSK;  run=(void (*)(void))downloadAddress; //使用DCACHE且RW区也在CACHE区间downloadAddress会在cache中  {  MMU_DisableDCache(); //download program must be in  MMU_DisableICache(); //non-cache area  MMU_InvalidateDCache(); //使所有DCACHE失效,本程序的MMU_Init中将会刷新DCACHE到存储器,  //为使应用此MMU_Init方式的程序能被正确运行必须先使DCACHE失效!!!  MMU_DisableMMU();  //call_linux(0, 193, downloadAddress); //或不用上面3个函数而直接使用call_linux  }run();}[url=][/url]

如果选择的下载到NAND,bootloader先将下载的BIN文件下载进DRAM,再将DRAM的数据拷到NAND中。拷备完后,执行引导系统的程序。
具体程序如何拷到NAND,再如何引导系统,代码做了非常详尽的注释,这里不多说了。
bootloader生成的BIN文件:
继承事业,薪火相传
返回列表