U-boot v1.0 所提供的2410对于我们那个系统是不适合的,因为我们的bootloader与Linux的内核,文件是放在一块Flash上的,而前者是分开存放的。因此要改造。下面是我记得的要改造的东西,如果你试过不行,那大概是我记的不太全,不过我相信你可以可以找出来那些要改的,否则,就算有这文章你也改不成功。嘿嘿。
这个文件是有关你的嵌入式系统Flash情况,我们的系统与u-boot提供的完全不一样(我们是Intel的128Mbit Flash,原版的我忘记),放心,类似的他也提供了,在其他的同类目录下有一个就是Intel Flash的文件,直接靠过来覆盖,然后要改些参数,在Flash.c头部,一看就懂。
在配置文件中可以说很多地方都需要改,看你的系统要怎么设置,下面是我改过的部分
/***********************************************************
* Command definition
***********************************************************/
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
/*CFG_CMD_NAND |*/ \
/*CFG_CMD_EEPROM |*/ \
/*CFG_CMD_I2C |*/ \
/*CFG_CMD_USB |*/ \
CFG_CMD_NET | \
CFG_CMD_PING | \
CFG_CMD_REGINFO | \
CFG_CMD_DATE | \
CFG_CMD_ELF)
defineONFIG_ETHADDR 08:04:22:26:2a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.0.101
#define CONFIG_SERVERIP 192.168.0.8
#define CONFIG_GATEWAYIP 192.168.0.253
#define CFG_MEMTEST_START 0x30000000 /* memtest works on */
#define CFG_MEMTEST_END 0x33F00000 /* 63 MB in DRAM */
#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
#define CFG_LOAD_ADDR 0x30008000 /* default load address */
/*#define CONFIG_BOOTCOMMAND "cp 1040000 30008000 100000;" \
"cp 1140000 30800000 200000;" \
// "set_param 30000100"
#define CONFIG_BOOTARGS "initrd=0x30800000,0x200000 root=/dev/ram init=/linuxrc console=ttyS0"
可以我发现这部分的要改的花了我很多时间,不改的话表现为Linux 解压完内核后启动就死掉,查了很久,在与另外一个bootloader Vivi对照启动过程中发现可能就缺少了这部分,于是加上去,马上可以正常启动。而且我在uboot加多了一个命令set_param,这个命令其实是初始化linux的启动参数空间,而且令其启动。
#define SZ_4K 0x00001000
#define SZ_64M 0x04000000
#define DRAM_SIZE SZ_64M
//#define LINUX_KERNEL_OFFSET 0x8000
#define LINUX_PARAM_OFFSET 0x100
#define LINUX_PAGE_SIZE SZ_4K
#define LINUX_PAGE_SHIFT 12
//#define LINUX_ZIMAGE_MAGIC 0x016f2818
#define COMMAND_LINE_SIZE 1024
/* This is the old deprecated way to pass parameters to the kernel */
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];
};
/*
* cpu_arm920_tlb_invalidate_all()
*
* Invalidate all TLB entries
*/
static inline void cpu_arm920_tlb_invalidate_all(void)
{
__asm__(
"mov r0, #0\n"
"mcr p15, 0, r0, c7, c10, 4\n" /* drain WB */
"mcr p15, 0, r0, c8, c7, 0\n" /* invalidate I & D TLBs */
);
}
void tlb_invalidate(void)
{
cpu_arm920_tlb_invalidate_all();
}
static inline void cpu_arm920_cache_clean_invalidate_all(void)
{
__asm__(
" mov r1, #0\n"
" mov r1, #7 << 5\n" /* 8 segments */
"1: orr r3, r1, #63 << 26\n" /* 64 entries */
"2: mcr p15, 0, r3, c7, c14, 2\n" /* clean & invalidate D index*/
" subs r3, r3, #1 << 26\n"
" bcs 2b\n" /* entries 64 to 0 */
" subs r1, r1, #1 << 5\n"
" bcs 1b\n" /* segments 7 to 0 */
" mcr p15, 0, r1, c7, c5, 0\n" /* invalidate I cache */
" mcr p15, 0, r1, c7, c10, 4\n" /* drain WB */
);
}
void cache_clean_invalidate(void)
{
cpu_arm920_cache_clean_invalidate_all();
}
void call_linux(long a0, long a1, long a2)
{
cache_clean_invalidate();
tlb_invalidate();
__asm__(
"mov r0, %0\n"
"mov r1, %1\n"
"mov r2, %2\n"
"mov ip, #0\n"
"mcr p15, 0, ip, c13, c0, 0\n" /* zero PID */
"mcr p15, 0, ip, c7, c7, 0\n" /* invalidate I,D caches */
"mcr p15, 0, ip, c7, c10, 4\n" /* drain write buffer */
"mcr p15, 0, ip, c8, c7, 0\n" /* invalidate I,D TLBs */
"mrc p15, 0, ip, c1, c0, 0\n" /* get control register */
"bic ip, ip, #0x0001\n" /* disable MMU */
"mcr p15, 0, ip, c1, c0, 0\n" /* write control register */
"mov pc, r2\n"
"nop\n"
"nop\n"
: /* no outpus */
: "r" (a0), "r" (a1), "r" (a2)
);
}
/*
* pram_base: base address of linux paramter
*/
static void setup_linux_param(ulong param_base)
{
struct param_struct *params = (struct param_struct *)param_base;
char linux_cmd[]="initrd=0x30800000,0x200000 root=/dev/ram init=/linuxrc console=ttyS0";
// printf("Setup linux parameters at 0x%08lx\n", param_base);
memset(params, 0, sizeof(struct param_struct));
params->u1.s.page_size = LINUX_PAGE_SIZE;
params->u1.s.nr_pages = (DRAM_SIZE >> LINUX_PAGE_SHIFT);
// params->u1.s.ramdisk_size = 0x200000;
// params->u1.s.rootdev = rootdev;
// params->u1.s.flags = 0;
/* params->u1.s.initrd_start = ?;
params->u1.s.initrd_size = ?;
params->u1.s.rd_start = ?;
*/
#if 0
params->u1.s.page_size = LINUX_PAGE_SIZE;
params->u1.s.nr_pages = (dram_size >> LINUX_PAGE_SHIFT);
params->u1.s.ramdisk_size = 0;
params->u1.s.rootdev = rootdev;
params->u1.s.flags = 0;
/* TODO */
/* If use ramdisk */
#endif
/* set linux command line */
memcpy(params->commandline, linux_cmd, strlen(linux_cmd) + 1);
//printf("linux command line is: \"%s\"\n", linux_cmd);
call_linux(0,193 , 0x30008000);
}
int
do_set_param (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
unsigned long addr;
addr = simple_strtoul(argv[1], NULL, 16);
setup_linux_param(addr);
return 0;
}
U_BOOT_CMD(
set_param, CFG_MAXARGS, 1, do_set_param,
"set_param - setup the linux boot paramters,wrote by Pazu \n",
NULL
);