8. u-boot-2016.03移植之剪裁、修改默认参数、设置分区
从前面编译出来的u-boot.bin文件大小490多KB,其实其中有很多我们不用的代码,我们可以通过裁减uboot去掉我们没用的功能,以减少u-boot.bin文件的大小,同时也方便我们烧uboot。
8.1 修改//.h文件剪裁uboot
(1) 去掉usb支持,如下图所示:
(2) 去掉RTC支持,如下图所示:
(3) 去掉bootp选项,如下图所示:
(4) 去掉不需要的命令行配置,如下图所示:
(5) 去掉文件系统的支持,如下图所示:
(6) 在uboot顶层目录输入以下命令重新编译:
make distclean
make jz2440_defconfig
make
(7) 查看u-boot的大小,输入命令:ls u-boot.bin -l,此时的uboot大小有490多KB减少到250多KB,如下图所示:
8.2 设置uboot分区
我们可以从uboot中输入help命令来查找uboot有哪些命令,在这些命令中我们可以找到定义分区相关的命令,如下图所示:
然后,我们可以尝试从uboot中输入 命令观察有什么输出,输入命令后,uboot输出的结果如下图所示:
从uboot的顶层目录输入搜索命令:grep -nR " not , no ",搜索结果如下图所示:
进入cmd/.c文件中,发现 not , no 在函数中,该函数的部分代码如下:
int mtdparts_init(void)
{
/* get variables */
ids = getenv("mtdids");
parts = getenv("mtdparts");
current_partition = getenv("partition");
... ...
/* if mtdids varible is empty try to use defaults */
if (!ids) {
if (mtdids_default) {
debug("mtdids variable not defined, using defaultn");
ids = mtdids_default;
setenv("mtdids", (char *)ids);
} else {
printf("mtdids not defined, no default presentn");
return 1;
}
}
... ...
}
输入命令时,串口输出 not , using ,显然是ids = 0、 = 0 执行了 else 分支语句。在该文件中有如下定义:
从上面 的代码截图可知,、都是黑的,显然是没有定义。那么如定义呢?我们可以参考其他单板的定义。最后我们在//.h中修改添加如下代码:
/*
*mtdparts
*/
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define MTDIDS_DEFAULT "nand0=jz2440-0" /* 表示哪一个设备 */
#define MTDPARTS_DEFAULT "mtdparts=jz2440-0:256k(u-boot),"
"128k(params),"
"2m(kernel),"
"-(rootfs)"
然后让uboot启动时自行设置分区,所以需要在uboot进入死循环之前执行 命令。因此,在函数里添加代码:(" ",0);,如下图所示:
重新编译uboot,并烧写到开发板的NOR Flash,重启开发板从串口输入命令,输出结果如下:
从上图可知,uboot把NAND Flash成功的分成了4个分区。
8.3 修改默认参数
上图显示:CRC的参数错误,使用默认的环境变量。那么我们就从这个问题引入,在uboot中搜索:usinguboot,在/.c中可找到它是在函数里打印的,该函数的代码如下:
void set_default_env(const char *s)
{
int flags = 0;
if (sizeof(default_environment) > ENV_SIZE) {
puts("*** Error - default environment is too largenn");
return;
}
if (s) {
if (*s == '!') {
printf("*** Warning - %s, "
"using default environmentnn",
s + 1);
} else {
flags = H_INTERACTIVE;
puts(s);
}
} else {
puts("Using default environmentnn");
}
if (himport_r(&env_htab, (char *)default_environment,
sizeof(default_environment), '', flags, 0,
0, NULL) == 0)
error("Environment import failed: errno = %dn", errno);
gd->flags |= GD_FLG_ENV_READY;
}
从上面的代码可以找到,它是一个全局字符数组,保存的是默认环境变量参数,该数组如下:
const uchar default_environment[] = {
#ifdef CONFIG_ENV_CALLBACK_LIST_DEFAULT
ENV_CALLBACK_VAR "=" CONFIG_ENV_CALLBACK_LIST_DEFAULT ""
#endif
#ifdef CONFIG_ENV_FLAGS_LIST_DEFAULT
ENV_FLAGS_VAR "=" CONFIG_ENV_FLAGS_LIST_DEFAULT ""
#endif
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS ""
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND ""
#endif
#ifdef CONFIG_RAMBOOTCOMMAND
"ramboot=" CONFIG_RAMBOOTCOMMAND ""
#endif
#ifdef CONFIG_NFSBOOTCOMMAND
"nfsboot=" CONFIG_NFSBOOTCOMMAND ""
#endif
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
"bootdelay=" __stringify(CONFIG_BOOTDELAY) ""
#endif
#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
"baudrate=" __stringify(CONFIG_BAUDRATE) ""
#endif
#ifdef CONFIG_LOADS_ECHO
"loads_echo=" __stringify(CONFIG_LOADS_ECHO) ""
#endif
#ifdef CONFIG_ETHPRIME
"ethprime=" CONFIG_ETHPRIME ""
#endif
#ifdef CONFIG_IPADDR
"ipaddr=" __stringify(CONFIG_IPADDR) ""
#endif
#ifdef CONFIG_SERVERIP
"serverip=" __stringify(CONFIG_SERVERIP) ""
#endif
#ifdef CONFIG_SYS_AUTOLOAD
"autoload=" CONFIG_SYS_AUTOLOAD ""
#endif
#ifdef CONFIG_PREBOOT
"preboot=" CONFIG_PREBOOT ""
#endif
#ifdef CONFIG_ROOTPATH
"rootpath=" CONFIG_ROOTPATH ""
#endif
#ifdef CONFIG_GATEWAYIP
"gatewayip=" __stringify(CONFIG_GATEWAYIP) ""
#endif
#ifdef CONFIG_NETMASK
"netmask=" __stringify(CONFIG_NETMASK) ""
#endif
#ifdef CONFIG_HOSTNAME
"hostname=" __stringify(CONFIG_HOSTNAME) ""
#endif
#ifdef CONFIG_BOOTFILE
"bootfile=" CONFIG_BOOTFILE ""
#endif
#ifdef CONFIG_LOADADDR
"loadaddr=" __stringify(CONFIG_LOADADDR) ""
#endif
#ifdef CONFIG_CLOCKS_IN_MHZ
"clocks_in_mhz=1"
#endif
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
"pcidelay=" __stringify(CONFIG_PCI_BOOTDELAY)""
#endif
#ifdef CONFIG_ENV_VARS_UBOOT_CONFIG
"arch=" CONFIG_SYS_ARCH ""
"cpu=" CONFIG_SYS_CPU ""
"board=" CONFIG_SYS_BOARD ""
"board_name=" CONFIG_SYS_BOARD ""
#ifdef CONFIG_SYS_VENDOR
"vendor=" CONFIG_SYS_VENDOR ""
#endif
#ifdef CONFIG_SYS_SOC
"soc=" CONFIG_SYS_SOC ""
#endif
#endif
#ifdef CONFIG_EXTRA_ENV_SETTINGS
CONFIG_EXTRA_ENV_SETTINGS
#endif
""
#ifdef DEFAULT_ENV_INSTANCE_EMBEDDED
}
#endif
};
从上面的代码可知:① 是传给内核的启动参数,可以设置文件系统的相关分区等;② 是uboot用来启动内核的参数;③ 、、、分别是开发板的IP地址、服务器IP地址、网关、掩码;④ 忽然发现,上面默认的环境变量里竟然没有设置默认MAC地址的环境变量 ,那么我们可以的设置添加环境变量,代码如下:
#ifdef CONFIG_ETHADDR
"ethaddr=" __stringify(CONFIG_ETHADDR) ""
#endif
我们只需要修改相关宏就可以修改默认环境变量参数了,总的修改如下:(在//.h修改)
#define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel;bootm 30000000"
#define CONFIG_ETHADDR 00:0c:29:4d:e4:f4 /*定义MAC地址*/
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.0.200
#define CONFIG_SERVERIP 192.168.0.100
#define CONFIG_GATEWAYIP 192.168.0.1
重新编译,烧写启动新uboot时就会默认使用上面的环境变量uboot,不需要每次启动都去修改变量了。启动开发板后,串口输入print命令,串口的打印信息如下:
8.4 修改支持保存环境变量
之前我们设置好参数之后,每次都不敢save,就是怕破坏FLASH;在.h配置文件中,找到如下环境变量的相关定义,如下图所示:
那么我们重新定义这些宏,该怎么定义呢?在uboot命令行使用help命令查看save相关的信息,如下图所示:
然后我们在uboot源码中搜索字符串:grep -nR "" 找到了类似这样的语句:/.c:181:int (void) 我们去目录下看看,看看.c的编译依赖哪个宏?找到了下面这句:obj-$(D) += .o,说明编译.c依赖的是这个宏的定义。 那么我们就定义这个宏D,所以我们将上面环境变量的宏重新定义如下:
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET 0x00040000
#define CONFIG_ENV_SIZE 0x20000
#define CONFIG_ENV_RANGE CONFIG_ENV_SIZE
重新编译uboot,烧写到开发板,测试如下:
从上图可知,环境变量参数被保存到NAND Flash的第二个分区了。
限时特惠:本站持续每日更新海量各大内部创业课程,一年会员仅需要98元,全站资源免费下载
点击查看详情
站长微信:Jiucxh