2410init. c file int main(int argc, char **argv) { u32 test = 0; void (*theKERNEL)(int zero, int arch, unsigned long params_addr) = (void (*)(int, int, unsigned long))RAM_COMPRESSED_KERNEL _BASE; //压缩后的IMAGE地址 int i, k=0; // downPt=(RAM_COMPRESSED_KERNEL_BASE); chkBs=(_RAM_STARTADDRESS);//SDRAM开始的地方 // fromPt=(FLASH_LINUXKERNEL); MMU_EnableICache(); ChangeClockDivider(1, 1); // 1:2:4 ChangeMPllValue(M_MDIV, M_PDIV, M_SDIV); //Fin=12MHz FCLK=200MHz Port_Init();//设置I/O端口, 在使用com口前, 必须调用这个函数, 否则通信芯片根本得不到数据 Uart_Init(PCLK, 115200);//PCLK使用默认的200000, 拨特率115200 /*******************(检查ram空间)*******************/ Uart_SendString("ntLinux S3C2410 Nor BOOTLOADERn"); Uart_SendString("ntChecking SDRAM 2410loader. c. . . n"); for(;chkBs<0x33FA0140;chkBs=chkBs+0x4, test++)//
/* 根据我的经验, 最好以一个字节为递增, 我们的板子, 在256byte递增检测的时候是没问题的, 但是以1byte递增就出错了, 第13跟数据线随几的会冒”1”, 检测出来是硬件问题, 现象如下:用仿真器下代码测试SDRAM, 开始没贴28F128A3J FLASH片子, 测试结果很好, 但在上了FLASH片子//之后, 测试数据(data)为0x00000400连续成批写入读出时, 操作大约1k左右内存空间就会出错, 而且随机. 那个出错数据总是变为0x00002400, 数据总线10位和13位又没短路 发生. 用其他数据//测试比如0x00000200;0x00000800没这问题. dx帮忙. 至今没有解决, 所以我用不了Flash. */
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("ntSDRAM Check Successful!ntMemory Maping. . . "); get_memory_map(); //获得可用memory 信息, 做成列表, 后面会作为启动参数传给KERNEL /* 所谓内存映射就是指在4GB 物理地址空间中有哪些地址范围被分配用来寻址系统的 RAM 单元. */
Uart_SendString("ntMemory 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 0x31000000n"); Uart_SendString("ttby 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("ttloading 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("ttloading 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("nnPanic 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[i]. used) {
params->hdr. tag = ATAG_MEM;
params->hdr. size = tag_size(tag_mem32);
params->u. mem. start = memory_map[i]. start;
params->u. mem. size = memory_map[i]. 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);
} |