分类: 嵌入式
2009-11-04 12:26:41
U-Boot在S3C2440开发板上的移植
转载:http://deshunfan.blog.163.com/blog/static/3424410120097792959702/
1 . 添加一个跟目标版最接近的板子的配置目录,拷贝一份,我们选择smdk2410
(和我们2440板子配置最接近的是2410)
cd board
cp smdk2410 Rain2440 –R
然后进入自己板子主目录下,修改相应文件
cd Rain2440
mv smdk2410 Rain2440.c
vim Makefile
修改COBJS为COBJS := Rain2440.o flash.o
2 . 添加配置文件
cd inlcude/configs
cp smdk2410.h Rain2440.h
3 . 修改顶层的Makefile,添加如下两行
(以下两行参照2410的格式来写,用来指定我们的体系结构是arm,CPU是920T)
Rain2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t Rain2440 NULL s3c24x0
二、修改相应的源代码
1 . 修改board/Rain2440/lowlevel_init.S,初始化内存,修改刷新频率
(2440和2410板子的刷新频率不同)
#define REFCNT 1269 /* period=7.8us, HCLK=100Mhz, (2048+1-7.8*100) */
2 . 修改board/Rain2440/Rain2440.c中的int board_init (void)函数,参考文件夹中my2440.c中的内容(用来提升主频,并分频)
3 . 修改cpu/arm920t/s3c24x0/speed.c文件,修改内容参考文件夹中的speed.c (修改时钟频率)
4 . 修改include/s3c24x0.h中的结构体,这是2440的时钟控制寄存器,首地址同2410,即0x4c000000。
typedef struct {
S3C24X0_REG32 LOCKTIME;
S3C24X0_REG32 MPLLCON;
S3C24X0_REG32 UPLLCON;
S3C24X0_REG32 CLKCON;
S3C24X0_REG32 CLKSLOW;
S3C24X0_REG32 CLKDIVN;
S3C24X0_REG32 CAMDIVN; /*比2410新增加的寄存器*/
} /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;
5 . 然后执行下面两条命令得到u-boot.bin文件
make Rain2440_config
make
三、完善BootLoader
1 . 添加ping命令和nand命令
1.1 在/include/configs/Rain2440.h中添加
#define CONFIG_COMMANDS \
((CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
CFG_CMD_PING | \ (支持ping命令)
CFG_CMD_NAND | \ (支持nand命令)
/*CFG_CMD_EEPROM |*/ \
/*CFG_CMD_I2C |*/ \
/*CFG_CMD_USB |*/ \
CFG_CMD_REGINFO | \
CFG_CMD_DATE) & \
/*CFG_CMD_ELF) */ \
~CFG_CMD_LOADB & \
~CFG_CMD_LOADS)
在文件末添加三个宏定义 (若不加,编译出错,提示没有下面的宏定义,那就加上)
#define CFG_NAND_BASE
#define CFG_MAX_NAND_DEVICE 1
#define NAND_MAX_CHIPS 1
1.2 在文件中修改以下宏定义
#define CONFIG_BOOTDELAY 5 (倒计时秒数)
#define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock2 console=ttySAC0 rootfstype=jffs2" (启动参数)
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.17
#define CONFIG_SERVERIP 192.168.1.1
1.3 自己编写board_nand_init函数(原程序只留了此函数的接口,具体实现由用户完成),在这我们已经写好,即文件夹中的nand_flash.c文件,我们把它放到cpu/arm920t/s3c24x0/下,同时修改Makefile (让它被编译)
COBJS = i2c.o interrupts.o serial.o speed.o \
usb_ohci.o nand_flash.o
1.4 在include/s3c24x0.h中添加结构体S3C2440,里面都是S3C2440板子Nand Flash的控制寄存器,首地址同2410,即0x4e000000
/* NAND FLASH (see S3C2440 manual chapter 6) */
typedef struct {
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCONT;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG32 NFDATA;
S3C24X0_REG32 NFMECCD0;
S3C24X0_REG32 NFMECCD1;
S3C24X0_REG32 NFSECCD;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSBLK;
S3C24X0_REG32 NFEBLK;
} /*__attribute__((__packed__))*/ S3C2440_NAND;
1.5 在include/s3c2410.h中添加一个函数,如下
static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)
{
return (S3C2440_NAND * const)S3C2410_NAND_BASE;
}
2 . 修改bootm命令的实现函数,令BootLoader能引导kernel
只需要在include/configs/Rain2440.h中添加如下两行宏定义即可
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_CMDLINE_TAG
★ 在此,我将对BootLoader的stage2阶段进行分析
◆ 当BootLoader进入stage2阶段时,运行Lib_arm/Board.c文件中的start_armboot函数,开始CPU的初始化、开发板的初始化、中断初始化、环境变量初始化、波特率及串口通信的设置等。然后初始化Flash设备,初始化系统内存分配函数,初始化NAND设备,初始化显示设备,初始化相关网络设备,填写IP、MAC地址等,最后进入命令死循环,即main_loop函数,接收用户从串口输入的命令,然后进行相应的工作。
◆ 进入main_loop函数中。里面调用readline函数,用来从串口接收用户输入的命令,然后把接收到的用户输入的字符串存放到全局变量console_buffer数组中。
接着调用run_command函数,来对用户输入的命令进行处理。
◆ 进入run_command函数中。里面调用parse_line函数,用来分解用户输入的命令,将解析出来的字符串放在argv数组中,然后调用find_cmd函数来查找用户输入的命令是否存在,若存在就执行cmd_tbl_t结构体中的cmd函数成员来执行命令。
U-Boot对命令的存储是这样做的,定义一个cmd_tbl_t结构体,其中有6个成员变量,第一个是命令名,第三个是命令的实现函数。U-Boot将这些结构体依次存放在二进制文件中数据段后面的.u_boot_cmd段中,这一过程是通过下面宏来实现的:
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
◆ 因此,要想在U-Boot中添加用户自己的命令的,我们只需要在common目录下建立一个Cmd_(自己命令).c文件,里面添加自己命令的实现函数以及相应的U_BOOT_CMD宏即可。函数及宏的格式参照U-Boot标准命令的实现。
◆ 接下来我将添加一个自己的命令,格式为led 参数1 参数2,参数1表示LED灯的序列号,参数2表示亮灯还是灭灯,1代表亮灯,0表示灭灯。具体步骤如下。
3 . 添加led命令
3.1 在common目录下添加cmd_led.c文件,修改Makefile
cd common
cp cmd_bootm cmd_led.c
vim Makefile
cmd_load.o cmd_log.o cmd_led.o\
3.2 修改cmd_led.c文件,实现命令。在这我们已经写好,即文件中的cmd_led.c文件,我们将它传到common目录下。
此时编译出来的U-Boot已经具有led命令了。
3.3 完善led命令,使led命令被条件编译
◆ 在include/configs/Rain2440.h中添加下面宏
#define CONFIG_COMMANDS \
((CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
CFG_CMD_LED | \
◆ 在common/cmd_led.c中添加下面的条件编译
#if (CONFIG_COMMANDS & CFG_CMD_LED)
int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{ … }
#endif /* (CONFIG_COMMANDS & CFG_CMD_LED) */
◆ 在include/cmd_confdefs.h中定义下面的宏
#define CFG_CMD_LED 0x8000000000000000ULL /* LED support */
4 . 添加命令行历史纪录功能
只需要在include/configs/Rain2440.h中添加下面一条宏命令即可
#define CONFIG_CMDLINE_EDITING 1 /* add command line history */
5. 增加BootLoader自动引导kernel的功能
打开include/configs/Rain2440.h中的下面的宏
/*#define CONFIG_BOOTCOMMAND "tftp; bootm" */
并修改为
define CONFIG_BOOTCOMMAND “nand read.jffs2 0x32000000 0x80000 0x180000; bootm 0x32000000”