⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 armlinux bootloader全程详解.txt

📁 很全面的分析ARM Linux 下的 boot loader 设计和实现
💻 TXT
📖 第 1 页 / 共 2 页
字号:
{  

chkPt1 = chkBs;  

*(u32 *)chkPt1 = test;//写数据  

if(*(u32 *)chkPt1==1024))//读数据和写入的是否一样?  

{  

chkPt1 += 4;  

Led_Display(1);  

Led_Display(2);  

Led_Display(3);  

Led_Display(4);  

}  

else  

goto error;  

}  

Uart_SendString("\n\tSDRAM Check Successful!\n\tMemory Maping...");  

get_memory_map();  

//获得可用memory 信息,做成列表,后面会作为启动参数传给KERNEL  

//所谓内存映射就是指在4GB 物理地址空间中有哪些地址范围被分配用来寻址系统的 RAM 单元。  

Uart_SendString("\n\tMemory Map Successful!\n");  

//我用仿真器把KERNEL,RAMDISK直接放在SDRAM上,所以下面这段是不需要的,但是如果KERNEL,RAMDISK在FLASH里,那就需要.  

/*******************(copy linux KERNEL)*******************/  

Uart_SendString("\tLoading KERNEL IMAGE from FLASH... \n ");  

Uart_SendString("\tand copy KERNEL IMAGE to SDRAM at 0x31000000\n");  

Uart_SendString("\t\tby LEIJUN DONG dongleijun4000@hotmail.com \n");  

for(k = 0;k < 196608;k++,downPt += 1,fromPt += 1)//3*1024*1024/32linux KERNEL des,src,length=3M  

* (u32 *)downPt = * (u32 *)fromPt;  

/*******************(load RAMDISK)*******************/  

Uart_SendString("\t\tloading COMPRESSED RAMDISK...\n");  

downPt=(RAM_COMPRESSED_RAMDISK_BASE);  

fromPt=(FLASH_RAMDISK_BASE);  

for(k = 0;k < 196608;k++,downPt += 1,fromPt += 1)//3*1024*1024/32linux KERNEL des,src,length=3M  

* (u32 *)downPt = * (u32 *)fromPt;  

/******jffs2文件系统,在开发中如果用不到FLASH,这段也可以不要********/  

Uart_SendString("\t\tloading jffs2...\n");  

downPt=(RAM_JFFS2);  

fromPt=(FLASH_JFFS2);  

for(k = 0;k < (1024*1024/32);k++,downPt += 1,fromPt += 1)  

* (u32 *)downPt = * (u32 *)fromPt;  

Uart_SendString( "Load Success...Run...\n ");  

/*******************(setup param)*******************/  

setup_start_tag();//开始设置启动参数  

setup_memory_tags();//内存印象  

setup_commandline_tag("console=ttyS0,115200n8");//启动命令行  

setup_initrd2_tag();//root device  

setup_RAMDISK_tag();//ramdisk image  

setup_end_tag();  

/*关I-cache */  

asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i));  

i &= ~0x1000;  

asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i));  

/* flush I-cache */  

asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i));  

//下面这行就跳到了COMPRESSED KERNEL的首地址  

theKERNEL(0, ARCH_NUMBER, (unsigned long *)(RAM_BOOT_PARAMS));  

//启动kernel时候,I-cache可以开也可以关,r0必须是0,r1必须是CPU型号  

(可以从linux/arch/arm/tools/mach-types中找到),r2必须是参数的物理开始地址  

/*******************END*******************/  

error:  

Uart_SendString("\n\nPanic SDRAM check error!\n");  

return 0;  

}  

static void setup_start_tag(void)  

{  

params = (struct tag *)RAM_BOOT_PARAMS;//启动参数开始的地址  

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(void)  

{  

int i;  



for(i = 0; i < NUM_MEM_AREAS; i++) {  

if(memory_map.used) {  

params->hdr.tag = ATAG_MEM;  

params->hdr.size = tag_size(tag_mem32);  

params->u.mem.start = memory_map.start;  

params->u.mem.size = memory_map.len;  

params = tag_next(params);  

}  

}  

}  





static void setup_commandline_tag(char *commandline)  

{  

int i = 0;  

/* skip non-existent command lines so the kernel will still  

* use its default command line.  

*/  

params->hdr.tag = ATAG_CMDLINE;  

params->hdr.size = 8;  

//console=ttyS0,115200n8  

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

params = tag_next(params);  

}  





static void setup_initrd2_tag(void)  

{  

/* an ATAG_INITRD node tells the kernel where the compressed  

* ramdisk can be found. ATAG_RDIMG is a better name, actually.  

*/  

params->hdr.tag = ATAG_INITRD2;  

params->hdr.size = tag_size(tag_initrd);  

params->u.initrd.start = RAM_COMPRESSED_RAMDISK_BASE;  

params->u.initrd.size = 2047;//k byte  

params = tag_next(params);  

}  





static void setup_ramdisk_tag(void)  

{  

/* an ATAG_RAMDISK node tells the kernel how large the  

* decompressed ramdisk will become.  

*/  

params->hdr.tag = ATAG_RAMDISK;  

params->hdr.size = tag_size(tag_ramdisk);  

params->u.ramdisk.start = RAM_DECOMPRESSED_RAMDISK_BASE;  

params->u.ramdisk.size = 7.8*1024; //k byte  

params->u.ramdisk.flags = 1; // automatically load ramdisk  

params = tag_next(params);  

}  





static void setup_end_tag(void)  

{  

params->hdr.tag = ATAG_NONE;  

params->hdr.size = 0;  

} void Uart_Init(int pclk,int baud)//串口是很重要的  

{  

int i;  

if(pclk == 0)  

pclk = PCLK;  

rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable  

rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable  



//UART0  

rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits  

下面这段samsung好象写的不太对,但是我按照Normal,No parity,1 stop,8 bits算出来的确是0x245  



// [10] [9] [8] [7] [6] [5] [4] [3:2] [1:0]  

// Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err, Loop-back, Send break, Transmit Mode, Receive Mode  

// 0 1 0 , 0 1 0 0 , 01 01  

// PCLK Level Pulse Disable Generate Normal Normal Interrupt or Polling  

rUCON0 = 0x245; // Control register  

rUBRDIV0=( (int)(PCLK/16./ baud) -1 ); //Baud rate divisior register 0  

delay(10);  

}  

  经过以上的折腾,接下来就是kernel的活了.能不能启动kernel,得看你编译kernel的水平了.  

  这个BOOTLOADER不象blob那样需要交互信息,使用虚拟地址,总的来说非常简洁明了.  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -