📄 nand.c
字号:
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 + -