完善以及裁剪U-boot
U-boot移植到这步就马上接近尾声了,这一节我们对U-boot做一些最后的完善。首先看一下开机时候打印出的信息。
解决打印出的WARING和ERROR信息
几个错误和警告信息都是用同样的套路,先看第一个 “WARNING: Caches not enabled” ,找一下在哪里打印的
- initr_caches(\common\board_r.c)
- enable_caches();(\arch\arm\lib\cache.c)
- puts(“WARNING: Caches not enabled\n”);
- enable_caches();(\arch\arm\lib\cache.c)
但是我们看一下
\arch\arm\cpu\arm920t\start.S,第143行
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 1 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
在这里面已经是启用了I/Dcache,上面的注释是错的,所以就没有必要再修改,我们直接把打印信息注释掉就好了。
\arch\arm\lib\cache.c,第35行
__weak void enable_caches(void)
{
//puts("WARNING: Caches not enabled\n");
}
接是using default environment,出现这个是因为上电以后U-boot会去我们指定的地方读取环境变量,但是我们现在没有设置,所以会出现这个警告,现在我们看一下代码中在哪打印的,然后就可以找到存放环境变量的数组default_environment。从上一个个往下看,宏CONFIG_BOOTARGS表示U-boot传递给Linux内核的参数,在 \include\configs\smdk2440.h里找个地方定义
#define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
表示信息都从串口传递,系统从第三个块运行。
#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel 0x200000;bootm 30000000"
表示u-boot上电一段时间后自动执行的命令,CONFIG_BOOTDELAY代表的就是这段时间的长度。CONFIG_BAUDRATE代表串口波特率。
这版少了网卡的MAC地址,直接在数组里面添加一项
#ifdef CONFIG_ETHADDR
"ethaddr=" __stringify(CONFIG_ETHADDR) "\0"
#endif
然后在头文件里修改一下网络相关的配置
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.9.172
#define CONFIG_SERVERIP 192.168.9.16
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b
设置完这些以后只要我们把网卡的MAC地址也保存在环境变量里,就顺带的把dm9000 address not set问题也一起解决了。
但是看到这里我们没有找到相关的save指令,现在我们重启一下开发板,输入?save
看一下save是怎么用的。
接着我们在源码里搜索一下saveenv
发现有好多同样的指令,但是最后都是通过宏定义来决定要编译哪个文件。可以看到在common目录下有一个env_nand.c,把环境变量保存在Nand Flash就是通过这个文件,现在我们打开common目录下的Makefile文件,看看怎样才能把这个文件编译进去。
这里可以看到要定义一个CONFIG_ENV_IS_IN_NAND。现在已经让u-boot知道环境变量要存在Nand Flash,但是不知道要存在哪个地址,区域有多大。接下来有两种方法,一种是定义完
CONFIG_ENV_IS_IN_NAND这宏以后直接拿过去编译,另一种是分析一下源代码。我们选择第二种
\common\env_nand.c,第184行
int saveenv(void)
{
int ret = 0;
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
int env_idx = 0;
static const struct env_location location[] = {
{
.name = "NAND",
.erase_opts = {
.length = CONFIG_ENV_RANGE,
.offset = CONFIG_ENV_OFFSET,
},
},
#ifdef CONFIG_ENV_OFFSET_REDUND
{
.name = "redundant NAND",
.erase_opts = {
.length = CONFIG_ENV_RANGE,
.offset = CONFIG_ENV_OFFSET_REDUND,
},
},
#endif
};
if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
return 1;
ret = env_export(env_new);
if (ret)
return ret;
#ifdef CONFIG_ENV_OFFSET_REDUND
env_new->flags = ++env_flags; /* increase the serial */
env_idx = (gd->env_valid == 1);
#endif
ret = erase_and_write_env(&location[env_idx], (u_char *)env_new);
#ifdef CONFIG_ENV_OFFSET_REDUND
if (!ret) {
/* preset other copy for next write */
gd->env_valid = gd->env_valid == 2 ? 1 : 2;
return ret;
}
env_idx = (env_idx + 1) & 1;
ret = erase_and_write_env(&location[env_idx], (u_char *)env_new);
if (!ret)
printf("Warning: primary env write failed,"
" redundancy is lost!\n");
#endif
return ret;
}
在这里我们可以看到CONFIG_ENV_OFFSET环境变量的偏移值,也就是存放的地址,然后是长度CONFIG_ENV_RANGE,而这个宏又依赖于CONFIG_ENV_SIZE,所以我们修改头文件如下:
\include\configs\smdk2440.h,第150行
#if 0
#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000)
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE 0x10000
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
#else
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET 0x00040000
#define CONFIG_ENV_RANGE 0x00020000
#endif
接着我们重新编译烧录上电,设置好网卡的MAC地址以后执行一下save
命令,然后reset
重新上电,可以看到现在都没有错误和警告信息了。
裁剪U-boot
不知道从什么版本开始裁剪U-boot就不能全靠修改 \include\configs\smdk2440.h 里面的宏定义,还要修改\configs\smdk244_config文件,不然会报出一大堆错误。
这边贴出我的修改,大哥按照自己的需求添加或者删减对应的功能。
\include\configs\smdk2440.h
/************************************************************
* USB support (currently only works with D-cache off)
************************************************************/
#if 0
#define CONFIG_USB_OHCI
#define CONFIG_USB_OHCI_S3C24XX
#define CONFIG_DOS_PARTITION
#endif
/************************************************************
* RTC
************************************************************/
#if 0
#define CONFIG_RTC_S3C24X0
#endif
#if 0
#define CONFIG_CMD_DATE
#endif
/* support additional compression methods */
#if 0
#define CONFIG_BZIP2
#define CONFIG_LZO
#define CONFIG_LZMA
#endif
#if 0
#define CONFIG_CMD_UBIFS
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define CONFIG_YAFFS2
#define CONFIG_RBTREE
#endif
\configs\smdk244_config
CONFIG_ARM=y
CONFIG_TARGET_SMDK2440=y
CONFIG_BOOTDELAY=5
# CONFIG_SYS_STDIO_DEREGISTER is not set
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="SMDK2440 # "
#CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
#CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
#CONFIG_CMD_EXT2=y
#CONFIG_CMD_FAT=y
#CONFIG_CMD_UBI=y
#CONFIG_USB=y
#CONFIG_USB_STORAGE=y
#CONFIG_USB_KEYBOARD=y
然后分别输入指令,最后u-boot只有200多K的大小
make distclean
make smdk2440_config
make
给U-boot添加分区
这个分区不是说是真正的分区,只是我们人为的指定多少地址到多少地址为什么分区,简单来说就是给地址块命名。
用指令grep -rn "mtdpart" *
看一下其他板子是怎么使用mtd的,然后仿照他修改头文件
\include\configs\smdk2440.h,第133行
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define MTDIDS_DEFAULT "nand0=s3c2440"
#define MTDPARTS_DEFAULT "mtdparts=s3c2440:256k(u-boot),"\
"128k(params),"\
"2m(kernel),"\
"-(rootfs)"
然后再在\common\board_r.c文件中的init_sequence_r数组下添加mtd的初始化函数:
\common\board_r.c,第970行
#if defined(CONFIG_SPARC)
prom_init,
#endif
mtdparts_init,
run_main_loop,
然后重新编译,烧写重新上电,执行mtdpart
命令就可以看到分区情况了。
然后就可以通过分区名称下载和启动内核了
nand erase.part kernel
nand write 30000000 kernel
补丁yizhi_7
链接:https://pan.baidu.com/s/1v85_5VApVgmMG9IXrwgCiQ
提取码:bb6y
注意:这边的补丁文件只是相对于上一节的u-boot,直接下载下来的u-boot打这个补丁是没有用的