port u-boot for S3C2410

U-boot v1.0 所提供的2410对于我们那个系统是不适合的,因为我们的bootloader与Linux的内核,文件是放在一块Flash上的,而前者是分开存放的。因此要改造。下面是我记得的要改造的东西,如果你试过不行,那大概是我记的不太全,不过我相信你可以可以找出来那些要改的,否则,就算有这文章你也改不成功。嘿嘿。

u-boot/board/smdk2410/flash.c

这个文件是有关你的嵌入式系统Flash情况,我们的系统与u-boot提供的完全不一样(我们是Intel的128Mbit Flash,原版的我忘记),放心,类似的他也提供了,在其他的同类目录下有一个就是Intel Flash的文件,直接靠过来覆盖,然后要改些参数,在Flash.c头部,一看就懂。

u-boot/include/configs

在配置文件中可以说很多地方都需要改,看你的系统要怎么设置,下面是我改过的部分



/***********************************************************
 * 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"

uboot/common

可以我发现这部分的要改的花了我很多时间,不改的话表现为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
);

Home / Index 雁过留声