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

📄 nand.c

📁 s3c2440 bootloader适用于S3C2440开发板
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct param_struct *params = (struct param_struct *)0x30000100;
	int size;
	
	memset(params, 0, sizeof(struct param_struct));
	/*{
		U32 *pD = (U32 *)0x30000100;
		
		for(i=0; i<0x1000; i++)
			pD[i] = 0;
	}*/
	if(boot_params.start.val) {
		char parameters[512];
		char *rootfs;
		char initrd[32];
		char *tty_sel;
		char *devfs_sel;
		
		switch (boot_params.root_sel.val) {
		case 0:
			rootfs = "/dev/ram";
			break;
		case 1:
			rootfs = "nfs";
			break;
		case 2:
			rootfs = "/dev/mtdblock1";
			break;
		case 3:
			rootfs = "/dev/mtdblock2";
			break;
		case 4:
			rootfs = "/dev/hda1";
		default:
			rootfs="";	//user define
			break;
		}
/*	
		if(boot_params.root_sel.val)
			sprintf(initrd, "load_ramdisk=0");
		else
			sprintf(initrd, "initrd=0x%08x,0x%08x",
						boot_params.initrd_addr.val,
						boot_params.initrd_len.val);
*/	
//printf("boot_params.tty_sel.val = (%d)\n", boot_params.tty_sel.val);
		switch (boot_params.tty_sel.val) {
		case 0:
			tty_sel="ttySAC0";
			break;
		case 1:
			tty_sel="ttySAC1";
			break;
		case 2:
			tty_sel="tty1";
			break;
		default:
			tty_sel="";	//user define
			break;
		}
/*	
		if(boot_params.devfs_sel.val)
			devfs_sel = "devfs=mount";
		else
			devfs_sel = "";
*/		
		memset(parameters, 0, sizeof(parameters));
/*		sprintf(parameters,
					"root=%s rw init=/linuxrc %s console=%s,%d mem=%dK %s %s",
					rootfs,
					initrd,
					tty_sel,
					boot_params.serial_baud.val,
					boot_params.mem_cfg.val>>10,
					devfs_sel,
					boot_params.string);
		sprintf(parameters,
					"root=%s rw init=/linuxrc console=%s,%d mem=%dK %s",
					rootfs,
					tty_sel,
					boot_params.serial_baud.val,
					boot_params.mem_cfg.val>>10,
					boot_params.string);
*/					
	if(boot_params.user_params.val)
		memcpy(parameters, boot_params.string, boot_params.user_params.val);
	else
		strcpy(parameters,"root=/dev/mtdblock1 rw rootfstype=jffs2 noinitrd init=/linuxrc console=ttySAC1,115200 mem=64M ip=192.168.1.7:192.168.1.1:192.168.1.1:255.255.255.0:avantech:eth0:off\0");

		params->u1.s.page_size = LINUX_PAGE_SIZE;
		params->u1.s.nr_pages = (boot_params.mem_cfg.val >> LINUX_PAGE_SHIFT);
		memcpy(params->commandline, parameters, strlen(parameters));
	
		printf("Set boot params = (%s)\n", params->commandline);
	}
	
//	SetTAG();

	printf("Load Kernel...\n");	

	if(boot_params.osstor.val)	//load program from NOR or NAND FLASH
		memcpy((void *)buf, (void *)(0x04000000+0x00020000), 0x001e0000);
	else {
		StartPage = NandPart[1].offset>>9;
//		size = NandPart[1].size;
		size = boot_params.initrd_len.val;
		ram_addr = buf;	
	printf("StartPage:0x%x,size:0x%x \n",StartPage, size);
		for(i=0; size>0; ) {
			if(!(i&0x1f)) {
				if(CheckBadBlk(i+StartPage)) {
					printf("Skipped bad block at 0x%x\n", i+StartPage);
					i += 32;
					size -= 32<<9;
					continue;
				}
			}
			ReadPage((i+StartPage), (U8 *)ram_addr);
			i++;
			size -= 512;
			ram_addr += 512;
		}
	}
/*	
	if(!boot_params.root_sel.val) {
		int ramdisk_sz;
		
		printf("Load Ramdisk...\n");
		
		StartPage = NandPart[2].offset>>9;
		size = NandPart[1].size;
		
		ram_addr = boot_params.initrd_addr.val;
		ramdisk_sz = boot_params.initrd_len.val;
		
		for(i=0; size>0&&ramdisk_sz>0; ) {
			if(!(i&0x1f)) {
				if(CheckBadBlk(i+StartPage)) {
					printf("Skipped bad block at 0x%x\n", i+StartPage);
					i += 32;
					size -= 32<<9;
					continue;
				}
			}
			ReadPage((i+StartPage), (U8 *)ram_addr);
			i++;
			size -= 512;
			ram_addr += 512;
			ramdisk_sz -= 512;
		}
	}
*/	
	DsNandFlash();
printf("READ finish\n");
	call_os(0, boot_params.machine.val, buf);
}

/************************************************************/
static int have_nandflash;
static void InitNandFlash(int info)
{	
	U32 i;
	
	InitNandCfg();
	i = ReadChipId();
	if(info)
		printf("Read chip id = %x\n", i);	
	if((i==0x9873)||(i==0xec75))	
		NandAddr = 0;
	else if(i==0xec76)
		NandAddr = 1;
	else {
		if(info)	
			puts("Chip id error!!!\n");
		have_nandflash = 0;
		return;
	}
	have_nandflash = 1;
	if(info)
		printf("Nand flash status = %x\n", ReadStatus());
}

void NandErase(int bootType)
{
	int i, err = 0;

	boot_params.start.val = bootType;
	if(bootType < 2){//linux
		NandPart[1].offset = 0x00040000;
		NandPart[1].size = 0x200000 - NandPart[1].offset;
		strcpy(NandPart[1].name, "KERNEL\0");
		NandPart[2].offset = 0x200000;
//		NandPart[2].size = 0x04000000 - NandPart[2].offset;
//		NandPart[2].size = 0x00700000 - NandPart[2].offset;
		NandPart[2].size = 0x03700000 - NandPart[2].offset;
		strcpy(NandPart[2].name, "ROOTFS\0");
	}
	else{//wince
		NandPart[1].offset = 0x00040000;
		NandPart[1].size = 0x02300000;
		strcpy(NandPart[1].name, "WINCE\0");
		NandPart[2].offset = NandPart[1].offset + NandPart[1].size;
		NandPart[2].size = 0x04000000 - NandPart[2].offset;
		strcpy(NandPart[2].name, "USER\0");
	}
		
	InitNandFlash(1);
	if(!have_nandflash)
		return;
	
	i = NandSelPart("erase");
	if(i<0)
		return;
	if(auto_nk==1)
		sel_part = i;	
	
	printf("Are you sure to erase nand flash from page 0x%x, block count 0x%x ? [y/n]\n", StartPage, BlockCnt);
	while(1) {
		char c;
		
		c = getch();
		if((c=='y')||(c=='Y'))
			break;
		if((c=='n')||(c=='N'))
			return;
	}	
	
	for(i=0; BlockCnt; BlockCnt--, i+=32) {
		if(EraseBlock(i+StartPage)) {
			err ++;
			puts("Press any key to continue...\n");
			getch();
		}
	}	

	DsNandFlash();		//disable nand flash interface
	puts("Erase Nand partition completed ");
	if(err)
		printf("with %d bad block(s)\n", err);
	else
		puts("success\n");
}

void NandWrite(void)
{
	InitNandFlash(1);
	if(!have_nandflash)
		return;
	WrFileToNF();
	DsNandFlash();		//disable nand flash interface
}

extern MemoryTest(void);
int RelocateNKBIN(U32 img_src, U32 *pStart, U32 *pLength, U32 *pLaunch);

static void LoadRunWince(void)
{
U32 i, ram_addr, buf = boot_params.initrd_addr.val;
int size;
int loading,loadsize;

	printf("Load Kernel...\n");	


	StartPage = NandPart[1].offset>>9;	// 0x40000.
	size = boot_params.initrd_len.val;  // 35M

	ram_addr = buf;                     // 下载地址,也是wince的启动地址
	loadsize = size / 512;              // 页数

	for(i=0; size>0; ) {                // 读取应用程序
		if(!(i&0x1f)) {
			if(CheckBadBlk(i+StartPage)) {
				printf("Skipped bad block at 0x%x\n", i+StartPage);
				i += 32;
				continue;
			}
		}
		ReadPage((i+StartPage), (U8 *)ram_addr);
		i++;
		size -= 512;
		ram_addr += 512;
		//output download info			
		if(!(i%500)) {                   // 显示滚动条
			U16 (*frameBuffer16BitTft)[SCR_XSIZE_TFT];
			int y,x;
			int loadtemp;
			frameBuffer16BitTft=(U16 (*)[SCR_XSIZE_TFT])LCDFRAMEBUFFER;
			printf("*");
			loadtemp = loading;
			loading = i * LCD_XSIZE_TFT / loadsize;
			for(y=LCD_YSIZE_TFT-15; y<LCD_YSIZE_TFT; y++){
				for(x=loadtemp; x<loading; x++)
				frameBuffer16BitTft[y][x] = COLOR_RED_TFT16 - (loading>>3) - 2;
			}
		}
	}
    // 启动wince 或 linux,注意启动ram的地址很重要,boot_params.run_addr.val
	printf("\nrun 0x%08x...\n", boot_params.run_addr.val);
	call_os(0, 0, boot_params.run_addr.val);
}


//Copy应用程序,启动应用程序
// 2008.5.13
void NandLoadRun(void)
{
	U32 *pt;
	InitNandFlash(1);
	//if(!have_nandflash)
	//	return;
	if(boot_params.start.val<2)	//linux
		LoadRun();


    	pt=(U32 *)(0x30000000);	//hzh
    	while((U32)pt<(0x33800000))
    	{
		*pt=(U32)0;
		pt++;
    	}
	// copy wince 并运行	
	LoadRunWince();
}



#include "norflash.h"
#define	NOR_PARAMS_OFFSET	0x1c000

int search_params(void)
{
U32 page, page_cnt;
S32 ret = -1;
U8  dat[528];

BootParams *pBP = (BootParams *)dat;

	
	InitNandFlash(0);	                                // don't show info in InitNandFlash!
	if(have_nandflash) {                                // 如果是从Nandflash 
		page     = NandPart[0].offset>>9;               // >>9 = /512 {0,0x40000,"ATBOOT"},求出便宜量
		page_cnt = NandPart[0].size>>9;                 // >>9 = /512 ,求出页数
	
		// search from the last page
		while(page_cnt--) {                             // 读取最后一页 512个字节
			ReadPage(page+page_cnt, dat);
			if(!strncmp(boot_params.start.flags, pBP->start.flags, 10)) { // boot_params.start.flags = "bootpara";
				ret = 0;                                                  // 如果相等
				break;
			}
		}
	} else {                                            // 如果从NorFlash 启动	
		memcpy(dat, (void *)(NOR_PARAMS_OFFSET), 512);	// now mmu is not set, so use original address
		if(!strncmp(boot_params.start.flags, pBP->start.flags, 10))
			ret = 0;
	}
	
	DsNandFlash();
	
	if(!ret) {
		ParamItem *pPIS = &pBP->start, *pPID = &boot_params.start;
		
		for(; pPID<=&boot_params.user_params; pPIS++, pPID++)
			if(!strncmp(pPID->flags, pPIS->flags, sizeof(pPID->flags)))
				pPID->val = pPIS->val;
		strncpy(boot_params.string, pPIS->flags, boot_params.user_params.val+1);
		if(boot_params.user_params.val!=strlen(pPID->flags)) {
			memset(boot_params.string, 0, sizeof(boot_params.string));
			boot_params.user_params.val = 0;
		}
	} else {
		//printf("Fail to find boot params! Use Default parameters.\n");
		//don't printf anything before serial initialized!
	}
	
	return ret;
}

//保存在最后两个block,应确保程序(包括出现坏块时)不会覆盖到最后两块
int save_params(void)
{
U32 page, page_cnt;
U8 dat[0x20000];
int ret = 0;
	
	InitNandFlash(1);
	have_nandflash=1;
	if(have_nandflash) {         // 对于nand flash
		memset(dat, 0, sizeof(boot_params));
		memcpy(dat, &boot_params, sizeof(boot_params));

        // 一个BLOCK是32PAGE,保存在BOOT区的最后两个区
		page = (NandPart[1].offset>>9)-64;
	
		for(page_cnt=0; page_cnt<64; page_cnt++) {
			if(!(page_cnt%32))
				EraseBlock(page);
			if(!WritePage(page+page_cnt, dat))
				break;
		}
		if(page_cnt>=64)
			ret = -1;
		printf("Save boot params %s.\n", ret?"fail":"success");

	} else {                   // 对于一个nor flash
		memcpy(dat, (void *)0x04000000, NOR_PARAMS_OFFSET);
		memcpy(dat+NOR_PARAMS_OFFSET, &boot_params, sizeof(boot_params));
		ProgNorFlash(0, (U32)dat, sizeof(dat));	//28F128
	}
	
	DsNandFlash();
	
	return ret;
}

int set_params(void)
{
	int i, key, chg=0;
	ParamItem *pPID;
	
	printf("\nConfig parameters\n");
	
	do {
		pPID = &boot_params.start;
		for(i=0; pPID<=&boot_params.user_params; pPID++, i++)
			printf("[%d] : %s%-8s is 0x%08x (%d)\n",
						i, (i>9)?"":" ", pPID->flags, pPID->val, pPID->val);
		printf("[%d] : Exit\n", i);
		if(boot_params.user_params.val)
			printf("User parameters is : \"%s\"\n", boot_params.string);
		
		printf("\nplease select item:");
		key = Uart_GetIntNum();
		if(key>=0&&key<i) {
			chg = 1;
			printf("please enter value:");
			i = key;
			if((&boot_params.start + i)==&boot_params.user_params) {
				//确保输入的字节数不超过127!
				char cmd[128];
				memset(cmd, 0, sizeof(cmd));
				Uart_GetString(cmd);
				strncpy(boot_params.string, cmd, strlen(cmd)+1);
				boot_params.user_params.val = strlen(cmd);
			} else {
				key = Uart_GetIntNum();
				(&boot_params.start + i)->val = key;
			}
		} else
			break;
	} while(1);
	
	if(chg) {
		printf("Do you want to save parameters? press y or Y for save.\n");
		key = getch();
		if(key=='y'||key=='Y')
			save_params();
	}
	
	return 0;
}

⌨️ 快捷键说明

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