八、移植u-boot-2016.03到Jz2440之剪裁、修改默认参数、设置分区

8. u-boot-2016.03移植之剪裁、修改默认参数、设置分区

从前面编译出来的u-boot.bin文件大小490多KB,其实其中有很多我们不用的代码,我们可以通过裁减uboot去掉我们没用的功能,以减少u-boot.bin文件的大小,同时也方便我们烧uboot。

8.1 修改include/configs/jz2440.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中输入mtdparts 命令观察有什么输出,输入命令后,uboot输出的结果如下图所示:
在这里插入图片描述
从uboot的顶层目录输入搜索命令:grep -nR "mtdids not defined, no default present",搜索结果如下图所示:
在这里插入图片描述
进入cmd/mtdparts.c文件中,发现mtdids not defined, no default presentmtdparts_init函数中,该函数的部分代码如下:

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 default\n");
			ids = mtdids_default;
			setenv("mtdids", (char *)ids);
		} else {
    
    
			printf("mtdids not defined, no default present\n");
			return 1;
		}
	}
        ... ...
}

输入mtdparts命令时,串口输出mtdids variable not defined, using default,显然是ids = 0mtdids_default = 0 执行了 else 分支语句。在该文件中有如下定义:
在这里插入图片描述
从上面source insight的代码截图可知,MTDIDS_DEFAULTMTDPARTS_DEFAULT都是黑的,显然是没有定义。那么如定义呢?我们可以参考其他单板的定义。最后我们在include/configs/jz2440.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进入main_loop死循环之前执行mtdparts default命令。因此,在run_main_loop函数里添加代码:run_command("mtdparts default",0);,如下图所示:
在这里插入图片描述
重新编译uboot,并烧写到开发板的NOR Flash,重启开发板从串口输入mtdparts命令,输出结果如下:
在这里插入图片描述
从上图可知,uboot把NAND Flash成功的分成了4个分区。

8.3 修改默认参数

在这里插入图片描述
上图显示:CRC的参数错误,使用默认的环境变量。那么我们就从这个问题引入,在uboot中搜索:using default environment,在common/env_common.c中可找到它是在set_default_env函数里打印的,该函数的代码如下:

void set_default_env(const char *s)
{
    
    
    int flags = 0;

    if (sizeof(default_environment) > ENV_SIZE) {
    
    
        puts("*** Error - default environment is too large\n\n");
        return;
    }

    if (s) {
    
    
        if (*s == '!') {
    
    
            printf("*** Warning - %s, "
                "using default environment\n\n",
                s + 1);
        } else {
    
    
            flags = H_INTERACTIVE;
            puts(s);
        }
    } else {
    
    
        puts("Using default environment\n\n");
    }

    if (himport_r(&env_htab, (char *)default_environment,
            sizeof(default_environment), '\0', flags, 0,
            0, NULL) == 0)
        error("Environment import failed: errno = %d\n", errno);

    gd->flags |= GD_FLG_ENV_READY;
}

从上面的代码可以找到default_environment,它是一个全局字符数组,保存的是默认环境变量参数,该数组如下:

const uchar default_environment[] = {
    
    
#ifdef	CONFIG_ENV_CALLBACK_LIST_DEFAULT
	ENV_CALLBACK_VAR "=" CONFIG_ENV_CALLBACK_LIST_DEFAULT "\0"
#endif
#ifdef	CONFIG_ENV_FLAGS_LIST_DEFAULT
	ENV_FLAGS_VAR "=" CONFIG_ENV_FLAGS_LIST_DEFAULT "\0"
#endif
#ifdef	CONFIG_BOOTARGS
	"bootargs="	CONFIG_BOOTARGS			"\0"
#endif
#ifdef	CONFIG_BOOTCOMMAND
	"bootcmd="	CONFIG_BOOTCOMMAND		"\0"
#endif
#ifdef	CONFIG_RAMBOOTCOMMAND
	"ramboot="	CONFIG_RAMBOOTCOMMAND		"\0"
#endif
#ifdef	CONFIG_NFSBOOTCOMMAND
	"nfsboot="	CONFIG_NFSBOOTCOMMAND		"\0"
#endif
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
	"bootdelay="	__stringify(CONFIG_BOOTDELAY)	"\0"
#endif
#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
	"baudrate="	__stringify(CONFIG_BAUDRATE)	"\0"
#endif
#ifdef	CONFIG_LOADS_ECHO
	"loads_echo="	__stringify(CONFIG_LOADS_ECHO)	"\0"
#endif
#ifdef	CONFIG_ETHPRIME
	"ethprime="	CONFIG_ETHPRIME			"\0"
#endif
#ifdef	CONFIG_IPADDR
	"ipaddr="	__stringify(CONFIG_IPADDR)	"\0"
#endif
#ifdef	CONFIG_SERVERIP
	"serverip="	__stringify(CONFIG_SERVERIP)	"\0"
#endif
#ifdef	CONFIG_SYS_AUTOLOAD
	"autoload="	CONFIG_SYS_AUTOLOAD		"\0"
#endif
#ifdef	CONFIG_PREBOOT
	"preboot="	CONFIG_PREBOOT			"\0"
#endif
#ifdef	CONFIG_ROOTPATH
	"rootpath="	CONFIG_ROOTPATH			"\0"
#endif
#ifdef	CONFIG_GATEWAYIP
	"gatewayip="	__stringify(CONFIG_GATEWAYIP)	"\0"
#endif
#ifdef	CONFIG_NETMASK
	"netmask="	__stringify(CONFIG_NETMASK)	"\0"
#endif
#ifdef	CONFIG_HOSTNAME
	"hostname="	__stringify(CONFIG_HOSTNAME)	"\0"
#endif
#ifdef	CONFIG_BOOTFILE
	"bootfile="	CONFIG_BOOTFILE			"\0"
#endif
#ifdef	CONFIG_LOADADDR
	"loadaddr="	__stringify(CONFIG_LOADADDR)	"\0"
#endif
#ifdef	CONFIG_CLOCKS_IN_MHZ
	"clocks_in_mhz=1\0"
#endif
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
	"pcidelay="	__stringify(CONFIG_PCI_BOOTDELAY)"\0"
#endif
#ifdef	CONFIG_ENV_VARS_UBOOT_CONFIG
	"arch="		CONFIG_SYS_ARCH			"\0"
	"cpu="		CONFIG_SYS_CPU			"\0"
	"board="	CONFIG_SYS_BOARD		"\0"
	"board_name="	CONFIG_SYS_BOARD		"\0"
#ifdef CONFIG_SYS_VENDOR
	"vendor="	CONFIG_SYS_VENDOR		"\0"
#endif
#ifdef CONFIG_SYS_SOC
	"soc="		CONFIG_SYS_SOC			"\0"
#endif
#endif
#ifdef	CONFIG_EXTRA_ENV_SETTINGS
	CONFIG_EXTRA_ENV_SETTINGS
#endif
	"\0"
#ifdef DEFAULT_ENV_INSTANCE_EMBEDDED
	}
#endif
};

从上面的代码可知:① bootargs是传给内核的启动参数,可以设置文件系统的相关分区等;② bootcmd是uboot用来启动内核的参数;③ ipaddrserveripgatewayipnetmask分别是开发板的IP地址、服务器IP地址、网关、掩码;④ 忽然发现,上面默认的环境变量里竟然没有设置默认MAC地址的环境变量 ethaddr,那么我们可以ipaddr的设置添加ethaddr环境变量,代码如下:

#ifdef  CONFIG_ETHADDR
        "ethaddr="  __stringify(CONFIG_ETHADDR)     "\0"
#endif

我们只需要修改相关宏就可以修改默认环境变量参数了,总的修改如下:(在include/configs/jz2440.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时就会默认使用上面的环境变量,不需要每次启动都去修改变量了。启动开发板后,串口输入print命令,串口的打印信息如下:
在这里插入图片描述

扫描二维码关注公众号,回复: 12662669 查看本文章

8.4 修改支持保存环境变量

之前我们设置好参数之后,每次都不敢save,就是怕破坏FLASH;在jz2440.h配置文件中,找到如下环境变量的相关定义,如下图所示:
在这里插入图片描述
那么我们重新定义这些宏,该怎么定义呢?在uboot命令行使用help命令查看save相关的信息,如下图所示:
在这里插入图片描述
然后我们在uboot源码中搜索字符串:grep -nR “saveenv”
找到了类似这样的语句:common/env_nand.c:181:int saveenv(void)
我们去common目录下看看Makefile,看看env_nand.c的编译依赖哪个宏?找到了下面这句:obj-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o,说明编译env_nand.c依赖的是CONFIG_ENV_IS_IN_NAND这个宏的定义。
那么我们就定义这个宏CONFIG_ENV_IS_IN_NAND,所以我们将上面环境变量的宏重新定义如下:

#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的第二个分区了。

猜你喜欢

转载自blog.csdn.net/qq_35031421/article/details/104488624