移植u-boot-2015.07-rc3之uboot裁剪及启动参数修改(九)

时间:2022-04-19 17:14:35

可以看到,现在make编译出来的u-boot.bin有512kb大小,造成u-boot这么巨大的原因是新版本的u-boot默认情况下支持非常多的命令,以至于很多不必要的.o文件都被链接进u-boot.bin文件中了。今天就来把u-boot中我用不到的命令都裁剪掉并设置默认的参数,如ipaddr、serverip等。

         大家移植到这里肯定是明白很多移植u-boot的套路技巧了,比如想要添加某个命令xxx的支持,那么就先在u-boot源码中看看有没有一个叫cmd_xxx.c的文件,有那就代表在源码上是支持的,那么接下来就是通过修改cmd_xxx.c对应的Makefile文件以支持生成cmd_xxx.o文件。一般地,在Makefile中想要生成某个.o文件都会有一个相对应的宏来决定是否生成某个.o文件,而这个宏都是在smdk2440.h这个头文件中定义的。

         反过来,我们想要取消某个命令也是通过删除smdk2440.h中的宏来完成的,在裁剪的过程中,原则上是先注释能确定的宏,不太敢肯定的宏先保留。在进一步裁剪时就可以跟着感觉来了,但是每裁剪一次都要对u-boot中需要的功能进行完整性测试,就这样一点一点的裁,直到裁剪的大小你满意为止。另外呢,在早期1.1.x的u-boot中,这些老版本的u-boot编译出来也就200k左右的样子,我们可以下载一个老版本的u-boot参考它的smdk2410.h进行裁剪。

         u-boot裁剪后smdk2440.h在本节末尾会全部贴出。

         在之前的移植中,我们一直没有移植环境变量相关的内容,而现在的u-boot使用环境变量保存命令saveenv后会直接重启u-boot,说明现在的saveenv命令是不可用的,猜测saveenv命令对应的有个cmd_saveenv.c文件,但是你搜索却搜索不到。那么猜测saveenv命令有一个saveenv()函数来实现,所以搜索saveenv:

root@ubuntu:/home/uboot/u-boot-2015.07-rc3# grep "saveenv" * -nR                                                                                                                                                                      

在搜索的结果中可以看到:

common/env_nand.c:180:int saveenv(void)

common/env_flash.c:106:int saveenv(void)

common/env_flash.c:224:int saveenv(void)

 

根据上面搜索的结果,可以猜测这个命令在env_nand.c和env_flash.c中都有支持,而事实上也是如此。环境参数既可以保存在NorFlash(env_flash.c)中,也可以保存在NandFlash(env_nand.c)中,而到底是保存在什么上面这就要看哪个文件被编译成了.o文件,所以查看相应的Makefile:

common/Makefile中:                                                                                                                                                                                                                                                

49 obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o

 50 obj-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o

 51 obj-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o

 52 obj-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o

明显的,可以在smdk2440.h中找到CONFIG_ENV_IS_IN_FLASH,而找不到CONFIG_ENV_IS_IN_NAND。而我们肯定是想要把环境变量保存在NandFlash中的,所以在smdk2440.h中添加宏CONFIG_ENV_IS_IN_NAND,关掉宏CONFIG_ENV_IS_IN_FLASH

smdk2440.h中:

172 #define CONFIG_ENV_ADDR                 (CONFIG_SYS_FLASH_BASE + 0x070000)

173 #if 0

174 #define CONFIG_ENV_IS_IN_FLASH

175 #endif

176 #define CONFIG_ENV_SIZE                 0x10000

177

178 #define CONFIG_ENV_IS_IN_NAND                                                                                                                                                                                                                

make编译,这时编译出错:

root@ubuntu:/home/uboot/u-boot-2015.07-rc3# make                                                                                                                                                                                                

scripts/kconfig/conf --silentoldconfig Kconfig

  CHK     include/config.h

  GEN     include/autoconf.mk

In file included from ./include/common.h:1015:

include/environment.h:78:5: error: #error "Need to define CONFIG_ENV_OFFSET when using CONFIG_ENV_IS_IN_NAND"

make[1]: *** [include/autoconf.mk] Error 1

make: *** No rule to make target `include/config/auto.conf', needed by `include/config/uboot.release'.  Stop.

root@ubuntu:/home/uboot/u-boot-2015.07-rc3#

看来是需要定义其他的宏,那么我们进入common/env_nand.c中的saveenv()函数去分析一下代码,根据代码可以确定saveenv()函数的实现还需要使用到其他三个宏:CONFIG_ENV_RANGE、CONFIG_ENV_OFFSET、CONFIG_ENV_SIZE,并对这三个宏的定义如下:

smdk2440.h中:

172 #define CONFIG_ENV_ADDR                 (CONFIG_SYS_FLASH_BASE + 0x070000)

173 #if 0

174 #define CONFIG_ENV_IS_IN_FLASH

175 #endif

176

177 #define CONFIG_ENV_IS_IN_NAND

178 #define CONFIG_ENV_SIZE                 0x20000                 /*128k*/

179 #define CONFIG_ENV_RANGE                        CONFIG_ENV_SIZE

180 #define CONFIG_ENV_OFFSET             0x00100000      /*  after 1M  *    /

181

182 /* allow to overwrite serial and ethaddr */

183 #define CONFIG_ENV_OVERWRITE

 

其中,CONFIG_ENV_SIZE表示保存环境变量的NandFlash空间的大小,CONFIG_ENV_OFFSET表示保存参数的NandFlash空间的首地址,这两个参数的值都是根据mtdparts分区来确定的,在mtdparts分区中,params分区就是拿来保存参数的。

 

对smdk2440.h修改完成后,make编译、下载、nor启动:

在控制台输入:

SMDK2410 # set machid 7cf

SMDK2410 # saveenv

Saving Environment to NAND...

Erasing NAND...

Erasing at 0x100000 -- 100% complete.

Writing to NAND... OK

SMDK2410 #reset

重启后是不是就没有看到那句恶心的警告了呢?!

SMDK2410 # print            

baudrate=115200

bootdelay=5

ethact=dm9000

ipaddr=10.0.0.110

machid=7cf    //这里看到我们刚才设置的环境参数就说明环境参数已经移植成功了

mtddevname=u-boot

mtddevnum=0

mtdids=nand0=MINI2440_XT

mtdparts=mtdparts=MINI2440_XT:1m(u-boot),128k(params),4m(kernel),-(rootfs)

netmask=255.255.255.0

partition=nand0,0

serverip=10.0.0.1                                                                                                                                                                                                                                                                

stderr=serial

stdin=serial

stdout=serial

 

Environment size: 331/131068 bytes

SMDK2410 #

同样的,上面我我设置CONFIG_ENV_OFFSET时是以nor启动的mtdparts分区来设置的,如果是spl方式启动的mtdparts应该把CONFIG_ENV_OFFSET的值设置为0x00120000,其他两个宏不变。

接下来完成今天最后的一道工作,修改u-boot默认参数。

在没有使用saveenv命令前我们一直看到这句警告:

*** Warning - bad CRC, using defaultenvironment

在使用saveenv命令后这句警告就消失了。因为在uboot上电后,首先会去读环境参数,然后判断参数是否有效,如果有效的话就使用,无效就使用默认参数并打印警告信息。

现在来搜索一下这句警告信息:

root@ubuntu:/home/uboot/u-boot-2015.07-rc3# grep "using default environment" * -nR                                                                                                                                

common/env_common.c:110:                                     "using default environment\n\n",

打开common/env_common.c文件,可以看到警告信息出现在set_default_env函数中,追踪default_environment可以看到所有默认的环境参数都定义在这个default_environment数组中,并且很多数组中的元素都是由宏开关限制的,其中的有些默认参数是我们必须设置的:

CONFIG_BOOTARGS:传给内核的启动参数,需要定义。

CONFIG_BOOTCOMMAND:uboot启动后根据这个命令来启动内核,需要设置。

所以在smdk2440.h中添加这两个宏:

smdk2440.h中:                                                                                                                                                                                                                                                                

107 /* autoboot */

108 #define CONFIG_BOOTDELAY        2

109 #define CONFIG_BOOTARGS "console=ttySAC0,115200 root=/dev/mtdblock3  rootfstype    =jffs2"

110 #define CONFIG_BOOTCOMMAND      "nand read 30000000 kernel;bootm 30000000"

111

112 #define CONFIG_BOOT_RETRY_TIME  -1

 

 

其中:

"console=ttySAC0,115200 root=/dev/mtdblock3  rootfstype=jffs2"

表示:串口0输出,波特率115200Hz,文件系统位于/dev/mtdblock3的位置,文件系统类型为jffs2.NandFlash的划分如下:

        mtdblock0      bootloader

        mtdblock1      params

        mtdblock2      kernel

        mtdblock3      rootfs

所以在spl启动的u-boot中,CONFIG_BOOTARGS应定义为:

#define CONFIG_BOOTARGS "console=ttySAC0,115200 root=/dev/mtdblock4  rootfstype    =jffs2"

 

"nand read 30000000 kernel;bootm 30000000"

表示:把kernel的数据读取到0x30000000处,并从0x30000000处启动内核。

CONFIG_BOOTDELAY表示uboot启动后的倒计时

 

编译下载,nor启动。定义CONFIG_BOOTDELAY后u-boot会自动延时,超过延时后根据CONFIG_BOOTCOMMAND启动Linux kernel,但是现在NandFlash中并没有kernel,所以现在我们下载一个kernel到NandFlash,测试u-boot是否能正常引导kernel。

SMDK2410 # tftp 30000000 uImage_xt

dm9000 i/o: 0x20000000, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: ff:ff:ff:ff:ff:ff

WARNING: Bad MAC address (uninitialized EEPROM?)

could not establish link

Using dm9000 device

TFTP from server 192.168.1.100; our IP address is 192.168.1.110

Filename 'uImage_xt'.

Load address: 0x30000000

Loading: #################################################################

         #################################################################

         ###########################

         1.2 MiB/s

done

Bytes transferred = 2298280 (2311a8 hex)

SMDK2410 # nand erase.part kernel

 

NAND erase.part: device 0 offset 0x120000, size 0x400000

Erasing at 0x500000 -- 100% complete.

OK

SMDK2410 # nand write 30000000 kernel

 

NAND write: device 0 offset 0x120000, size 0x400000

 4194304 bytes written: OK

SMDK2410 # set machid 7cf     设置机器ID

SMDK2410 # boot

 

NAND read: device 0 offset 0x120000, size 0x400000

 4194304 bytes read: OK

## Booting kernel from Legacy Image at 30000000 ...

   Image Name:   Linux-3.4.2

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    2298216 Bytes = 2.2 MiB

   Load Address: 30008000

   Entry Point:  30008000

   Verifying Checksum ... OK

   Loading Kernel Image ... OK

Using machid 0x7cf from environment

 

Starting kernel ...

 

Uncompressing Linux... done, booting the kernel.

Booting Linux on physical CPU 0

Linux version 3.4.2 (root@ubuntu) (gcc version 4.3.2 (Sourcery G++ Lite 2008q3-72) ) #13 Wed Jun 3 10:56:18 EDT 2015

CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177

CPU: VIVT data cache, VIVT instruction cache

Machine: MINI2440

Memory policy: ECC disabled, Data cache writeback

CPU S3C2440A (id 0x32440001)

S3C24XX Clocks, Copyright 2004 Simtec Electronics

S3C244X: core 400.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz                                                                                                                                                                

现在的u-boot已经能正常引导kernel了。

最后,在smdk2440.h中做进一步修改:

smdk2440.h中:                                                                                                                                                                                                                                                                                

114 #define CONFIG_ZERO_BOOTDELAY_CHECK

115

116 #define CONFIG_NETMASK          255.255.255.0

117 #define CONFIG_IPADDR           192.168.1.110

118 #define CONFIG_SERVERIP         192.168.1.100

119

120 #if defined(CONFIG_CMD_KGDB)

121 #define CONFIG_KGDB_BAUDRATE    115200  /* speed to run kgdb serial port */

122 #endif

123

124 /*

125  * Miscellaneous configurable options

126  */

127 #define CONFIG_SYS_LONGHELP             /* undef to save memory */

128 #define CONFIG_SYS_PROMPT       "XT_MINI2440 # "

 

以后控制台的提示就是XT_MINI2440 #而不是SMDK2410 #了。


make编译,下载,nor启动。完美引导kernel。

明天进行u-boot移植的最后一个主题,yaffs文件系统烧写支持。


完整smdk2440.h文件:

/*
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 * Gary Jennejohn <garyj@denx.de>
 * David Mueller <d.mueller@elsoft.ch>
 *
 * Configuation settings for the SAMSUNG SMDK2410 board.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#ifndef __CONFIG_H
#define __CONFIG_H

/*
 * High Level Configuration Options
 * (easy to change)
 */
#define CONFIG_S3C24X0		/* This is a SAMSUNG S3C24x0-type SoC */
/*#define CONFIG_S3C2410*/		/* specifically a SAMSUNG S3C2410 SoC */
/*#define CONFIG_SMDK2410*/		/* on a SAMSUNG SMDK2410 Board */
#define CONFIG_S3C2440
#define CONFIG_SMDK2440
#define CONFIG_SYS_TEXT_BASE	0x33f00000      /*  34000000-33f00000 = 1M*/

 #define CONFIG_UBOOT_LENGTH     0x80000     /*512k*/
 #define CONFIG_UBOOT_NAND_ADDR  0x0   /*start of u-boot.bin in NAND*/


/*#define CONFIG_SYS_GENERIC_BOARD*/

#define CONFIG_SYS_ARM_CACHE_WRITETHROUGH

/* input clock of PLL (the SMDK2410 has 12MHz input clock) */
#define CONFIG_SYS_CLK_FREQ	12000000

#define CONFIG_CMDLINE_TAG	/* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG

/*
 * Hardware drivers
 */

#define CONFIG_DRIVER_DM9000
#define CONFIG_DM9000_BASE              0x20000000
#define DM9000_IO                      		 CONFIG_DM9000_BASE
#define DM9000_DATA                     	(CONFIG_DM9000_BASE+4)


/*
 * select serial console configuration
 */
#define CONFIG_S3C24X0_SERIAL
#define CONFIG_SERIAL1		1	/* we use SERIAL 1 on SMDK2410 */

/************************************************************
 * USB support (currently only works with D-cache off)
 ************************************************************/
 #if 0
#define CONFIG_USB_OHCI
#define CONFIG_USB_OHCI_S3C24XX
#define CONFIG_USB_KEYBOARD
#define CONFIG_USB_STORAGE
#define CONFIG_DOS_PARTITION
#endif

/************************************************************
 * RTC
 ************************************************************/
 #if 0
#define CONFIG_RTC_S3C24X0
#endif

#define CONFIG_BAUDRATE		115200

/*
 * BOOTP options
 */
 #if 0
#define CONFIG_BOOTP_BOOTFILESIZE
#define CONFIG_BOOTP_BOOTPATH
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME
#endif
/*
 * Command line configuration.
 */
#define CONFIG_CMD_BSP
#define CONFIG_CMD_CACHE
#if 0
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#endif
#define CONFIG_CMD_ELF
#define CONFIG_CMD_NAND
#define CONFIG_CMD_PING
#define CONFIG_CMD_REGINFO
#if 0
#define CONFIG_CMD_USB
#endif

#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_CMDLINE_EDITING

/* autoboot */
#define CONFIG_BOOTDELAY	2
#define CONFIG_BOOTARGS	"console=ttySAC0,115200 root=/dev/mtdblock3  rootfstype=jffs2"
#define	CONFIG_BOOTCOMMAND	"nand read 30000000 kernel;bootm 30000000"

#define CONFIG_BOOT_RETRY_TIME	-1
#define CONFIG_RESET_TO_RETRY
#define CONFIG_ZERO_BOOTDELAY_CHECK

#define CONFIG_NETMASK		255.255.255.0
#define CONFIG_IPADDR		192.168.1.110
#define CONFIG_SERVERIP		192.168.1.100


#if defined(CONFIG_CMD_KGDB)
#define CONFIG_KGDB_BAUDRATE	115200	/* speed to run kgdb serial port */
#endif

/*
 * Miscellaneous configurable options
 */
#define CONFIG_SYS_LONGHELP		/* undef to save memory */
#define CONFIG_SYS_PROMPT	"XT_MINI2440 # "
#define CONFIG_SYS_CBSIZE	256
/* Print Buffer Size */
#define CONFIG_SYS_PBSIZE	(CONFIG_SYS_CBSIZE + \
				sizeof(CONFIG_SYS_PROMPT)+16)
#define CONFIG_SYS_MAXARGS	16
#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE

#define CONFIG_DISPLAY_CPUINFO				/* Display cpu info */

#define CONFIG_SYS_MEMTEST_START	0x30000000	/* memtest works on */
#define CONFIG_SYS_MEMTEST_END		0x33F00000	/* 63 MB in DRAM */

#define CONFIG_SYS_LOAD_ADDR		0x30800000

/* support additional compression methods */
#if 1
#define CONFIG_BZIP2
#define CONFIG_LZO
#define CONFIG_LZMA
#endif

/*-----------------------------------------------------------------------
 * Physical Memory Map
 */
#define CONFIG_NR_DRAM_BANKS	1          /* we have 1 bank of DRAM */
#define PHYS_SDRAM_1		0x30000000 /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE	0x04000000 /* 64 MB */

#define PHYS_FLASH_1		0x00000000 /* Flash Bank #0 */

#define CONFIG_SYS_FLASH_BASE	PHYS_FLASH_1

/*-----------------------------------------------------------------------
 * FLASH and environment organization
 */

#define CONFIG_SYS_FLASH_CFI
#define CONFIG_FLASH_CFI_DRIVER
#define CONFIG_FLASH_CFI_LEGACY
#define CONFIG_SYS_FLASH_LEGACY_512Kx16
#define CONFIG_FLASH_SHOW_PROGRESS	45

#define CONFIG_SYS_MAX_FLASH_BANKS	1
#define CONFIG_SYS_FLASH_BANKS_LIST     { CONFIG_SYS_FLASH_BASE }
#define CONFIG_SYS_MAX_FLASH_SECT	(128)

#define CONFIG_ENV_ADDR			(CONFIG_SYS_FLASH_BASE + 0x070000)
#if 0
#define CONFIG_ENV_IS_IN_FLASH
#endif

#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_SIZE			0x20000			/*128k*/
#define CONFIG_ENV_RANGE			CONFIG_ENV_SIZE
#define CONFIG_ENV_OFFSET			0x00100000      /*  after 1M  */

/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE

/*
 * Size of malloc() pool
 * BZIP2 / LZO / LZMA need a lot of RAM
 */
#define CONFIG_SYS_MALLOC_LEN	(4 * 1024 * 1024)

#define CONFIG_SYS_MONITOR_LEN	(448 * 1024)
#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_FLASH_BASE

/*
 * NAND configuration
 */
#ifdef CONFIG_CMD_NAND

#define CONFIG_CMD_NAND_YAFFS
#if 0
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
#else
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_S3C2440_NAND_HWECC
#endif

#define CONFIG_SYS_MAX_NAND_DEVICE	1
#define CONFIG_SYS_NAND_BASE		0x4E000000
#endif

/*
 * File system
 */
 #if 0
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#endif

#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS

#define MTDIDS_DEFAULT          "nand0=MINI2440_XT"

#define MTDPARTS_DEFAULT        "mtdparts=MINI2440_XT:1m(u-boot),"      \
                                              "128k(params),"            \
                                                "4m(kernel),"        \
                                                "-(rootfs)"           

#if 0
#define CONFIG_YAFFS2
#define CONFIG_RBTREE
#endif

/* additions for new relocation code, must be added to all boards */
#define CONFIG_SYS_SDRAM_BASE	PHYS_SDRAM_1
#define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_SDRAM_BASE + 0x1000 - \
				GENERATED_GBL_DATA_SIZE)

#define CONFIG_BOARD_EARLY_INIT_F

#endif /* __CONFIG_H */