📄 runnandprog.c
字号:
#define LINUX_PAGE_SHIFT 12
#define LINUX_PAGE_SIZE (1<<LINUX_PAGE_SHIFT)
#define COMMAND_LINE_SIZE 1024
struct param_struct {
union {
struct {
unsigned long page_size; /* 0 */
unsigned long nr_pages; /* 4 */
unsigned long ramdisk_size; /* 8 */
unsigned long flags; /* 12 */
#define FLAG_READONLY 1
#define FLAG_RDLOAD 4
#define FLAG_RDPROMPT 8
unsigned long rootdev; /* 16 */
unsigned long video_num_cols; /* 20 */
unsigned long video_num_rows; /* 24 */
unsigned long video_x; /* 28 */
unsigned long video_y; /* 32 */
unsigned long memc_control_reg; /* 36 */
unsigned char sounddefault; /* 40 */
unsigned char adfsdrives; /* 41 */
unsigned char bytes_per_char_h; /* 42 */
unsigned char bytes_per_char_v; /* 43 */
unsigned long pages_in_bank[4]; /* 44 */
unsigned long pages_in_vram; /* 60 */
unsigned long initrd_start; /* 64 */
unsigned long initrd_size; /* 68 */
unsigned long rd_start; /* 72 */
unsigned long system_rev; /* 76 */
unsigned long system_serial_low; /* 80 */
unsigned long system_serial_high; /* 84 */
unsigned long mem_fclk_21285; /* 88 */
} s;
char unused[256];
} u1;
union {
char paths[8][128];
struct {
unsigned long magic;
char n[1024 - sizeof(unsigned long)];
} s;
} u2;
char commandline[COMMAND_LINE_SIZE];
};
/*************************************************************/
static __inline void cpu_arm920_cache_clean_invalidate_all(void)
{
__asm{
mov r1, #0
mov r1, #7 << 5 /* 8 segments */
cache_clean_loop1:
orr r3, r1, #63UL << 26 /* 64 entries */
cache_clean_loop2:
mcr p15, 0, r3, c7, c14, 2 /* clean & invalidate D index */
subs r3, r3, #1 << 26
bcs cache_clean_loop2 /* entries 64 to 0 */
subs r1, r1, #1 << 5
bcs cache_clean_loop1 /* segments 7 to 0 */
mcr p15, 0, r1, c7, c5, 0 /* invalidate I cache */
mcr p15, 0, r1, c7, c10, 4 /* drain WB */
}
}
void cache_clean_invalidate(void)
{
cpu_arm920_cache_clean_invalidate_all();
}
static __inline void cpu_arm920_tlb_invalidate_all(void)
{
__asm{
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 /* drain WB */
mcr p15, 0, r0, c8, c7, 0 /* invalidate I & D TLBs */
}
}
void tlb_invalidate(void)
{
cpu_arm920_tlb_invalidate_all();
}
void call_linux(U32 a0, U32 a1, U32 a2)
{
void (*goto_start)(U32, U32);
cache_clean_invalidate();
tlb_invalidate();
__asm{
// mov r0, a0//%0
// mov r1, a1//%1
// mov r2, a2//%2
mov ip, #0
mcr p15, 0, ip, c13, c0, 0 /* zero PID */
mcr p15, 0, ip, c7, c7, 0 /* invalidate I,D caches */
mcr p15, 0, ip, c7, c10, 4 /* drain write buffer */
mcr p15, 0, ip, c8, c7, 0 /* invalidate I,D TLBs */
mrc p15, 0, ip, c1, c0, 0 /* get control register */
bic ip, ip, #0x0001 /* disable MMU */
mcr p15, 0, ip, c1, c0, 0 /* write control register */
//mov pc, r2
//nop
//nop
/* no outpus */
//: "r" (a0), "r" (a1), "r" (a2)
}
SetClockDivider(1, 1);
SetSysFclk(FCLK_200M); //start kernel, use 200M
Delay(1000);
// disable_irq();
goto_start = (void (*)(U32, U32))a2;
(*goto_start)(a0, a1);
}
static void LoadRun(void)
{
U32 i, ram_addr, buf = 0x30400000;
struct param_struct *params = (struct param_struct *)0x30000100;
int size;
char *linux_params = "root=/dev/mtdblock2 load_ramdisk=0 init=/linuxrc console=ttyS0 mem=64M devfs=mount";
StartPage = NandPart[1].offset>>9;
size = NandPart[1].size;
ram_addr = buf;
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;
}
DsNandFlash();
for(i=0; i<(sizeof(struct param_struct)>>2); i++)
((U32 *)params)[i] = 0;
params->u1.s.page_size = LINUX_PAGE_SIZE;
params->u1.s.nr_pages = (0x04000000 >> LINUX_PAGE_SHIFT);
for(i=0; linux_params[i]; i++)
params->commandline[i] = linux_params[i];
puts("Set boot params = ");
puts(linux_params);
putch('\n');
call_linux(0, 193, buf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -