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

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

8.1 修改//.h文件剪裁uboot

(1) 去掉usb支持,如下图所示:

uboot_uboot刷固件_uboot的主要功能

(2) 去掉RTC支持,如下图所示:

uboot刷固件_uboot_uboot的主要功能

(3) 去掉bootp选项,如下图所示:

uboot刷固件_uboot的主要功能_uboot

(4) 去掉不需要的命令行配置,如下图所示:

uboot刷固件_uboot_uboot的主要功能

(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 分支语句。在该文件中有如下定义:

uboot的主要功能_uboot刷固件_uboot

从上面 的代码截图可知,、都是黑的,显然是没有定义。那么如定义呢?我们可以参考其他单板的定义。最后我们在//.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刷固件_uboot的主要功能_uboot

重新编译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_uboot的主要功能_uboot刷固件

那么我们重新定义这些宏,该怎么定义呢?在uboot命令行使用help命令查看save相关的信息,如下图所示:

uboot_uboot刷固件_uboot的主要功能

然后我们在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,烧写到开发板,测试如下:

uboot的主要功能_uboot_uboot刷固件

从上图可知,环境变量参数被保存到NAND Flash的第二个分区了。


限时特惠:
本站持续每日更新海量各大内部创业课程,一年会员仅需要98元,全站资源免费下载
点击查看详情

站长微信:Jiucxh

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注