邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛
分类: 嵌入式
2015-07-19 22:11:14
上一课设置了很多IP地址等等参数,这些参数能不能固定在程序里面呢?这些参数叫什么呢?
这些参数叫做 环境变量。环境变量怎么做的呢?
u-boot启动的时候:
(1)读存储在某个地址上的参数
(2)判断是否有效
(3)有效就利用,无效则使用默认参数(代码里面写死了的)
看板子启动信息:
U-Boot 2012.04.01 (Jul 16 2015 - 13:05:13)
CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: dm9000
SMDK2410 #
*** Warning - bad CRC, using default environment 这条信息就表示在初始化的时候,在flash上没有设置这个参数,导致出现“警告”信息,使用“默认环境参数”
搜索 “default environment”
在文件中:\common\Env_common.c
(1)"bootargs=" 表示传给内核的启动参数,在配置文件中进行定义
(2)"bootcmd=" u-boot启动时,就是执行这个环境变量定义的命令,进行启动内核的。也需要设置
(3)"bootdelay=" 表示u-boot启动时的倒数计时。可以设置,可以使用默认值
(4)有关网卡设置方面的参数:
"ethaddr="
"netmask="
"ipaddr="
"serverip="
点击(此处)折叠或打开
- const uchar default_environment[] = {
- #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=" MK_STR(CONFIG_BOOTDELAY) "\0"
- #endif
- #if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
- "baudrate=" MK_STR(CONFIG_BAUDRATE) "\0"
- #endif
- #ifdef CONFIG_LOADS_ECHO
- "loads_echo=" MK_STR(CONFIG_LOADS_ECHO) "\0"
- #endif
- #ifdef CONFIG_ETHADDR
- "ethaddr=" MK_STR(CONFIG_ETHADDR) "\0"
- #endif
- #ifdef CONFIG_ETH1ADDR
- "eth1addr=" MK_STR(CONFIG_ETH1ADDR) "\0"
- #endif
- #ifdef CONFIG_ETH2ADDR
- "eth2addr=" MK_STR(CONFIG_ETH2ADDR) "\0"
- #endif
- #ifdef CONFIG_ETH3ADDR
- "eth3addr=" MK_STR(CONFIG_ETH3ADDR) "\0"
- #endif
- #ifdef CONFIG_ETH4ADDR
- "eth4addr=" MK_STR(CONFIG_ETH4ADDR) "\0"
- #endif
- #ifdef CONFIG_ETH5ADDR
- "eth5addr=" MK_STR(CONFIG_ETH5ADDR) "\0"
- #endif
- #ifdef CONFIG_IPADDR
- "ipaddr=" MK_STR(CONFIG_IPADDR) "\0"
- #endif
- #ifdef CONFIG_SERVERIP
- "serverip=" MK_STR(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=" MK_STR(CONFIG_GATEWAYIP) "\0"
- #endif
- #ifdef CONFIG_NETMASK
- "netmask=" MK_STR(CONFIG_NETMASK) "\0"
- #endif
- #ifdef CONFIG_HOSTNAME
- "hostname=" MK_STR(CONFIG_HOSTNAME) "\0"
- #endif
- #ifdef CONFIG_BOOTFILE
- "bootfile=" CONFIG_BOOTFILE "\0"
- #endif
- #ifdef CONFIG_LOADADDR
- "loadaddr=" MK_STR(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=" MK_STR(CONFIG_PCI_BOOTDELAY) "\0"
- #endif
- #ifdef CONFIG_EXTRA_ENV_SETTINGS
- CONFIG_EXTRA_ENV_SETTINGS
- #endif
- "\0"
- };
在配置文件\include\configs\smdk2440.h中增加相应的定义:
(1)"bootargs="
console=ttySAC0 表示内核启动时打印信息从串口0打印出来
root=/dev/mtdblock3 表示文件系统在第3个block,由上图的代码布局图可以知道。
#define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
(2)"bootcmd="
nand read 30000000 0xabc 0x200000 表示从地址0xabc的地方读大小为0x200000(2Mbit)到内存 0x30000000 处。这里由于还没有对内核文件系统等进行分
区,所以先随便定义了一个地址0xabc,后面会确定这个值。
bootm 30000000 表示从0x30000000地址处启动内核。
#define CONFIG_BOOTCOMMAND "nand read 30000000 0xabc 0x200000; bootm 30000000"
(3)网卡方面的设置:
#if 0
// 这个是默认的设置
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 10.0.0.110
#define CONFIG_SERVERIP 10.0.0.1
#else
// 下面是自己添加的设置
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.50 (表示板子网卡的IP地址)
#define CONFIG_SERVERIP 192.168.1.100 (表示服务器的IP地址,就是windows下网卡的IP地址)
#define CONFIG_ETHADDR 00:0c:29:2f:4e:70
#endif
修改配置参数,进行裁剪。
u-boot支持各种命令:但是有些命令根本不需要,这里就需要进行裁剪,裁剪就需要修改配置文件。
SMDK2410 # help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
bootvx - Boot vxWorks from an ELF image
chpart - change active partition
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
date - get/set/reset date & time
dcache - enable or disable data cache
dhcp - boot image via network using DHCP/TFTP protocol
echo - echo args to console
editenv - edit environment variable
env - environment handling commands
erase - erase FLASH memory
exit - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls - list files in a directory (default /)
false - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print command description/usage
icache - enable or disable instruction cache
iminfo - print header information for application image
imls - list all images found in flash
imxtract- extract a part of a multi-image
itest - return true/false on integer compare
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing address)
mtdparts- define flash/nand partitions
mtest - simple RAM read/write test
mw - memory write (fill)
nand - NAND sub-system
nboot - boot from NAND device
nfs - boot image via network using NFS protocol
nm - memory modify (constant address)
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
reginfo - print register information
reset - Perform RESET of the CPU
run - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv - set environment variables
showvar - print local hushshell variables
sleep - delay execution for some time
source - run script from memory
test - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
true - do nothing, successfully
ubi - ubi commands
ubifsload- load file from an UBIFS filesystem
ubifsls - list files in a directory
ubifsmount- mount UBIFS volume
ubifsumount- unmount UBIFS volume
usb - USB sub-system
usbboot - boot from USB device
version - print monitor, compiler and linker version
SMDK2410 #
修改配置文件,进行裁剪:\includes\configs\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.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
- #ifndef __CONFIG_H
- #define __CONFIG_H
- /*
- * High Level Configuration Options
- * (easy to change)
- */
- #define CONFIG_ARM920T /* This is an ARM920T Core */
- #define CONFIG_S3C24X0 /* in a SAMSUNG S3C24x0-type SoC */
- //#define CONFIG_S3C2410 /* specifically a SAMSUNG S3C2410 SoC */
- #define CONFIG_S3C2440 /* specifically a SAMSUNG S3C2410 SoC */
- #define CONFIG_SMDK2410 /* on a SAMSUNG SMDK2410 Board */
- #define CONFIG_SYS_TEXT_BASE 0x33f00000
- #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
- /* input clock of PLL (the SMDK2410 has 12MHz input clock) */
- #define CONFIG_SYS_CLK_FREQ 12000000
- #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
- #define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */
- #define CONFIG_SETUP_MEMORY_TAGS
- #define CONFIG_INITRD_TAG
- /*
- * Hardware drivers
- */
- #if 0
- #define CONFIG_CS8900 /* we have a CS8900 on-board */
- #define CONFIG_CS8900_BASE 0x19000300
- #define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
- #else
- #define CONFIG_DRIVER_DM9000
- #define CONFIG_DM9000_BASE 0x20000000
- #define DM9000_IO CONFIG_DM9000_BASE
- #define DM9000_DATA (CONFIG_DM9000_BASE + 4)
- #endif
- /*
- * 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)
- ************************************************************/
- //#define CONFIG_USB_OHCI
- //#define CONFIG_USB_KEYBOARD
- //#define CONFIG_USB_STORAGE
- //#define CONFIG_DOS_PARTITION
- /************************************************************
- * RTC
- ************************************************************/
- //#define CONFIG_RTC_S3C24X0
- #define CONFIG_BAUDRATE 115200
- /*
- * BOOTP options
- */
- //#define CONFIG_BOOTP_BOOTFILESIZE
- //#define CONFIG_BOOTP_BOOTPATH
- //#define CONFIG_BOOTP_GATEWAY
- //#define CONFIG_BOOTP_HOSTNAME
- /*
- * Command line configuration.
- */
- #include <config_cmd_default.h>
- #define CONFIG_CMD_BSP
- #define CONFIG_CMD_CACHE
- //#define CONFIG_CMD_DATE
- //#define CONFIG_CMD_DHCP
- #define CONFIG_CMD_ELF
- #define CONFIG_CMD_NAND
- #define CONFIG_CMD_PING
- #define CONFIG_CMD_REGINFO
- //#define CONFIG_CMD_USB
- #define CONFIG_SYS_HUSH_PARSER
- #define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
- #define CONFIG_CMDLINE_EDITING
- /* autoboot */
- #define CONFIG_BOOTDELAY 5
- #define CONFIG_BOOT_RETRY_TIME -1
- #define CONFIG_RESET_TO_RETRY
- #define CONFIG_ZERO_BOOTDELAY_CHECK
- #if 0
- #define CONFIG_NETMASK 255.255.255.0
- #define CONFIG_IPADDR 10.0.0.110
- #define CONFIG_SERVERIP 10.0.0.1
- #else
- #define CONFIG_NETMASK 255.255.255.0
- #define CONFIG_IPADDR 192.168.1.50
- #define CONFIG_SERVERIP 192.168.1.100
- #define CONFIG_ETHADDR 00:0c:29:2f:4e:70
- #endif
- #if defined(CONFIG_CMD_KGDB)
- #define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
- /* what's this ? it's not used anywhere */
- #define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
- #endif
- /*
- * Miscellaneous configurable options
- */
- #define CONFIG_SYS_LONGHELP /* undef to save memory */
- #define CONFIG_SYS_PROMPT "SMDK2410 # "
- #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
- #define CONFIG_SYS_HZ 1000
- /* valid baudrates */
- #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
- /* support additional compression methods */
- #define CONFIG_BZIP2
- #define CONFIG_LZO
- #define CONFIG_LZMA
- #define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
- #define CONFIG_BOOTCOMMAND "nand read 30000000 0xabc 0x200000; bootm 30000000"
- /*-----------------------------------------------------------------------
- * Stack sizes
- *
- * The stack sizes are set up in start.S using the settings below
- */
- #define CONFIG_STACKSIZE (128*1024) /* regular stack */
- #ifdef CONFIG_USE_IRQ
- #define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
- #define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
- #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)
- #define CONFIG_ENV_IS_IN_FLASH
- #define CONFIG_ENV_SIZE 0x10000
- /* 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
- #ifdef CONFIG_S3C2410
- #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
- #define CONFIG_CMD_MTDPARTS
- #define CONFIG_MTD_DEVICE
- #define CONFIG_MTD_PARTITIONS
- //#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 */
重新编译,生成新的u-boot.bin,二进制文件小了很多了,不到256K。
book@book-desktop:/work/system/u-boot-2012.04.01$ ls -l u-boot.bin
-rwxr-xr-x 1 book book 203176 2015-07-18 17:41 u-boot.bin
在这里编译,将会遇到很多编译出错的问题,但是基本原则也是,找到该文件下的Makefile文件,看看如果包含该文件进内核,依赖于哪个宏,然后增加或者去掉该宏定义,来使能或者禁能改函数功能。主要是要有耐心解决一个一个的错误。
如何划分分区呢?划分好分区以后,就能将修改后的启动参数,启动命令等等保存到划分好的参数分区中,否则千万不要保存,因为你保存的地址都没有分配好。
参考以前内核启动时打印的参数,u-boot启动内核时打印的分区信息:
bootloader -> 256k;
params -> 128k;
kernels -> 2Mbits;
root -> 剩下的大小;
0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"
查找跟save参数命令相关的文件,在文件中: \common\env_nand.c
CONFIG_ENV_SIZE: 表示写入数据(环境变量)的分区大小;
CONFIG_ENV_OFFSET: 表示存储的偏移地址;
CONFIG_ENV_RANGE:表示擦除的大小,nand写之前需要擦除操作。注意:nand擦出一定要是单块的整数倍。
点击(此处)折叠或打开
- int saveenv(void)
- {
- int ret = 0;
- env_t env_new;
- ssize_t len;
- char *res;
- nand_erase_options_t nand_erase_options;
- memset(&nand_erase_options, 0, sizeof(nand_erase_options));
- nand_erase_options.length = CONFIG_ENV_RANGE;
- nand_erase_options.offset = CONFIG_ENV_OFFSET;
- if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
- return 1;
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
- puts("Erasing Nand...\n");
- if (nand_erase_opts(&nand_info[0], &nand_erase_options))
- return 1;
- puts("Writing to Nand... ");
- if (writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new)) {
- puts("FAILED!\n");
- return 1;
- }
- puts("done\n");
- return ret;
- }
修改配置文件,增加分区信息:
点击(此处)折叠或打开
- #if 0
- #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000)
- #define CONFIG_ENV_IS_IN_FLASH // 这个表示是存储在nor flash中
- #define CONFIG_ENV_SIZE 0x10000
- /* allow to overwrite serial and ethaddr */
- #define CONFIG_ENV_OVERWRITE
- #else
// 增加下面的代码
- #define CONFIG_ENV_IS_IN_NAND /* 这个表示是存储在nand flash中 */
- #define CONFIG_ENV_OFFSET 0x00040000 /* 表示环境变量存储的偏移地址 */
- #define CONFIG_ENV_SIZE 0x20000 /* 定义参数的大小,但是一定要是nand flash单块的整数倍,因为nand flash需要整块的擦除
- 1块大小 = 128K */
- #define CONFIG_ENV_RANGE CONFIG_ENV_SIZE
- #endif
到这里,重新编译,烧写,打印:
下面的设置,如果在上面的配置文件中已经设置这些默认参数,并编译u-boot.bin进开发板,就不需要重新手动设置了。这些参数在开发板上已经是这样了。
SMDK2410 # set ipaddr 192.168.1.50
SMDK2410 # set ethaddr 00:0c:29:2f:4e:70
SMDK2410 # set serverip 192.168.1.100
利用u-boot的tftp功能来更新烧写u-boot.bin文件:
1. 烧写新的bin文件
SMDK2410 # tftp 30000000 u-boot_new.bin
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2f:4e:70
could not establish link
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.50
Filename 'u-boot_new.bin'.
Load address: 0x30000000
Loading: T T T T T T ##############
done
Bytes transferred = 203636 (31b74 hex)
SMDK2410 # protect off all
Un-Protect Flash Bank # 1
2. 擦除0x40000(256K)的大小
SMDK2410 # erase 0 3ffff
....... done
Erased 7 sectors
3. 拷贝256k字节的大小到NOR中
SMDK2410 # cp.b 30000000 0 40000
Copy to Flash... 9....8....7....6....5....4....3....2....1....done
4. 重新NOR启动
SMDK2410 # reset
resetting ...
tftp 30000000 u-boot_new.bin; erase 0 3ffff; cp.b 30000000 0 40000
U-Boot 2012.04.01 (Jul 18 2015 - 18:23:26)
CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
*** Warning - bad CRC, using default environment // 警告信息依然存在????
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0 这里有了倒数的信息
SMDK2410 # print
baudrate=115200
// 这里有了设置的参数
bootargs=console=ttySAC0 root=/dev/mtdblock3
bootcmd=nand read 30000000 0xabc 0x200000; bootm 30000000
bootdelay=5
ethact=dm9000
// 这也是设置的
ethaddr=00:0c:29:2f:4e:70
ipaddr=192.168.1.50
netmask=255.255.255.0
serverip=192.168.1.100
stderr=serial
stdin=serial
stdout=serial
Environment size: 302/131068 bytes
SMDK2410 #
这里为什么还是出现:*** Warning - bad CRC, using default environment
这是因为flash上还是没有有效的参数,这个时候,如果输入save命令,把有效参数保存到flash上,再启动的话,应该就不会出现这个"警告" 信息了。
1. 保存参数
SMDK2410 # save
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x40000 -- 100% complete.
Writing to Nand... done
2. 重新启动
SMDK2410 # reset
resetting ...
U-Boot 2012.04.01 (Jul 18 2015 - 18:23:26)
CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
3. 这里警告信息不见了。
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0
SMDK2410 #
到这里u-boot基本上移植完整。可以直接tftp烧写。
// 1. 烧写内核文件到SDRAM中
SMDK2410 # tftp 30000000 uImage
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2f:4e:70
could not establish link
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.50
Filename 'uImage'.
Load address: 0x30000000
Loading: T T T T T T #################################################################
#############################################################
done
Bytes transferred = 1848720 (1c3590 hex)
// 2. 擦除nand上起始地址为60000处共:0x2000000(2Mbits)的空间
SMDK2410 # nand erase 60000 200000
NAND erase: device 0 offset 0x60000, size 0x200000
Erasing at 0x240000 -- 100% complete.
OK
// 3. 从SDRAM拷贝内核文件到nand起始地址为:0x60000处2M空间去
SMDK2410 # nand write 30000000 60000 200000
NAND write: device 0 offset 0x60000, size 0x200000
2097152 bytes written: OK
SMDK2410 #
问题:但是这里,每次烧写都要记下这些空间的起始地址,以及大小,比较麻烦,有没有更方便的方法呢??比如用有意义的单词来替代起始地址和空间大小。
回答:有。
继续修改代码,如何做到易用性呢???
比如这条命令:nand write 30000000 60000 200000
可以用名字来代替分区偏移量和长度:60000 200000, 可以命名为: “kernel”
直接变成如下命令:
nand write 30000000 kernel注意:分区的大小及地址偏移量,由用户决定,至于用什么名字,只是u-boot定义某个宏,做了一层修饰而已,它不会改变分区的偏移量(地址)及大小。
在文件:\common\mmd_mtdparts.c 中有关于mtdparts的命令
搜索决定将 \common\cmd_mtdparts.c 编译进内核的配置宏
book@book-desktop:/work/system/u-boot-2012.04.01$ vi common/Makefile
\common\Makefile
COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
COBJS-$(CONFIG_MP) += cmd_mp.o
COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
COBJS-$(CONFIG_CMD_NET) += cmd_net.o
COBJS-$(CONFIG_CMD_ONENAND) += cmd_onenand.o
COBJS-$(CONFIG_CMD_OTP) += cmd_otp.o
所以要在配置文件里定义这个宏:CONFIG_CMD_MTDPARTS
修改配置文件 /include/configs/smdk2440.h
// 添加下面的宏
#define CONFIG_CMD_MTDPARTS
需要手工初始化mtdparts:
在文件中:\arch\arm\lib\board.c 增加初始化函数:mtdparts_init();
点击(此处)折叠或打开
- /*
- ************************************************************************
- *
- * This is the next part if the initialization sequence: we are now
- * running from RAM and have a "normal" C environment, i. e. global
- * data can be written, BSS has been cleared, the stack size in not
- * that critical any more, etc.
- *
- ************************************************************************
- */
- void board_init_r(gd_t *id, ulong dest_addr)
- {
......
.........
- #endif
- sprintf((char *)memsz, "%ldk", (gd->ram_size / 1024) - pram);
- setenv("mem", (char *)memsz);
- }
- #endif
- mtdparts_init(); // 增加这句话
- /* main_loop() can return to retry autoboot, if so just run it again. */
- for (;;) {
- main_loop();
- }
- /* NOTREACHED - no way out of command loop except booting */
- }
参考文件:include\configs\TQM866M.h
添加:在配置文件 \include\configs\smdk2440.h中
include\configs\TQM866M.h 文件中有:
#define MTDIDS_DEFAULT "nor0=TQM8xxM-0"
#define MTDPARTS_DEFAULT "mtdparts=TQM8xxM-0:512k(u-boot)," \
"128k(dtb)," \
"1920k(kernel)," \
"5632(rootfs)," \
"4m(data)"
在 \include\configs\smdk2440.h 配置文件中添加:
#define MTDIDS_DEFAULT "nand0=jz2440-0" /* 表示哪一个设备,这里是nand */
#define MTDPARTS_DEFAULT "mtdparts=jz2440-0:256k(u-boot)," \
"128k(params)," \
"2m(kernel)," \
"-(rootfs)" /* "-" 表示剩余的部分 */
重新Make编译发现这样的错误:
........
/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t -lgcc -Map u-boot.map -o u-boot
common/libcommon.o: In function `get_mtd_info':
/work/system/u-boot-2012.04.01/common/cmd_mtdparts.c:306: undefined reference to `get_mtd_device_nm'
make: *** [u-boot] Error 1
book@book-desktop:/work/system/u-boot-2012.04.01$ vi drivers/mtd/Makefile
查找 get_mtd_device_nm 函数在哪里定义,发现在 \drivers\mtd\Mtdcore.c 中定义。
查找Makefile,看看这个文件 \drivers\mtd\Mtdcore.c 如果编译进内核,需要定义哪个宏?
book@book-desktop:/work/system/u-boot-2012.04.01$ vi drivers/mtd/Makefile
需要定义这个宏:CONFIG_MTD_DEVICE
LIB := $(obj)libmtd.o
COBJS-$(CONFIG_MTD_DEVICE) += mtdcore.o
所以在配置文件需要继续增加这个宏:CONFIG_MTD_DEVICE
5.1 重新编译,烧写进NOR,NOR启动打印信息
SMDK2410 # tftp 30000000 u-boot.bin
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2f:4e:70
could not establish link
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.50
Filename 'u-boot_new.bin'.
Load address: 0x30000000
Loading: T T ###############
done
Bytes transferred = 216868 (34f24 hex)
SMDK2410 # protect off all
Un-Protect Flash Bank # 1
SMDK2410 # erase 0 3ffff
....... done
Erased 7 sectors
SMDK2410 # cp.b 30000000 0 40000
Copy to Flash... 9....8....7....6....5....4....3....2....1....done
SMDK2410 # reset
resetting ...
U-Boot 2012.04.01 (Jul 18 2015 - 23:07:50)
CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0
SMDK2410 #
5.2 测试是否建立分区信息,输入命令: mtdparts
SMDK2410 # reset
resetting ...
U-Boot 2012.04.01 (Jul 18 2015 - 23:30:28)
CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: dm9000
mtdparts variable not set, see 'help mtdparts'
Hit any key to stop autoboot: 0
SMDK2410 # mtdpart
mtdparts variable not set, see 'help mtdparts'
no partitions defined
defaults:
mtdids : nand0=jz2440-0
mtdparts: mtdparts=jz2440-0:256k(u-boot),128k(params),1920k(kernel),-(rootfs)
SMDK2410 #
这里输入mtdpart会打印:mtdparts variable not set, see 'help mtdparts'
SMDK2410 # mtdparts
mtdparts variable not set, see 'help mtdparts'
no partitions defined
defaults:
mtdids : nand0=jz2440-0
mtdparts: mtdparts=jz2440-0:256k(u-boot),128k(params),2m(kernel),-(rootfs)
SMDK2410 # help mtdparts
mtdparts - define flash/nand partitions
Usage:
mtdparts
- list partition table
mtdparts delall
- delete all partitions
mtdparts del part-id
- delete partition (e.g. part-id = nand0,1)
mtdparts add[@ ] [ ] [ro]
- add partition
mtdparts default
- reset partition table to defaults
输入命令:mtdparts default
发现输入这个命令之后再输入mtdparts命令,就可以看到默认的分区表了。 这说明需要运行这个命令,可以在代码启动的第二阶段最后运行这个命令。
SMDK2410 # mtdparts default
SMDK2410 # mtdparts
device nand0 , # parts = 4
#: name size offset mask_flags
0: u-boot 0x00040000 0x00000000 0
1: params 0x00020000 0x00040000 0
2: kernel 0x00200000 0x00060000 0
3: rootfs 0x0fda0000 0x00260000 0
active partition: nand0,0 - (u-boot) 0x00040000 @ 0x00000000
defaults:
mtdids : nand0=jz2440-0
mtdparts: mtdparts=jz2440-0:256k(u-boot),128k(params),2m(kernel),-(rootfs)
SMDK2410 #
修改arch/arm/lib/board.c文件:
void board_init_r(gd_t *id, ulong dest_addr)
{
......................
run_command("mtdparts default", 0); // 增加这句话
//mtdparts_init(); // 去掉这句话
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop();
}
/* NOTREACHED - no way out of command loop except booting */
}
重新编译,下载,启动
SMDK2410 # mtdpart
device nand0 , # parts = 4
#: name size offset mask_flags
0: u-boot 0x00040000 0x00000000 0
1: params 0x00020000 0x00040000 0
2: kernel 0x001e0000 0x00060000 0
3: rootfs 0x0fdc0000 0x00240000 0
active partition: nand0,0 - (u-boot) 0x00040000 @ 0x00000000
defaults:
mtdids : nand0=jz2440-0
mtdparts: mtdparts=jz2440-0:256k(u-boot),128k(params),1920k(kernel),-(rootfs)
SMDK2410 #
5.3 测试易用性
以前的命令
nand erase.part 60000 200000
nand write 30000000 60000 200000
现在的命令,可以直接利用名字来替换数字了。
tftp 30000000 uImage //这句执行的前提是启动了tftp服务器
可以用下面新的命令:
nand erase.part kernel
nand write 30000000 kernel
测试:
SMDK2410 # tftp 30000000 uImage
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2f:4e:70
could not establish link
Using dm9000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.50
Filename 'uImage'.
Load address: 0x30000000
Loading: T T T T T T #################################################################
#############################################################
done
Bytes transferred = 1848720 (1c3590 hex)
SMDK2410 # nand erase.part kernel
NAND erase.part: device 0 offset 0x60000, size 0x1e0000 (擦除的地址正确,起始地址是: 0x60000)
Erasing at 0x220000 -- 100% complete.
OK
SMDK2410 # nand write 30000000 kernel
NAND write: device 0 offset 0x60000, size 0x1e0000
1966080 bytes written: OK
SMDK2410 # SMDK2410 # print
baudrate=115200
bootargs=console=ttySAC0 root=/dev/mtdblock3
bootcmd=nand read 30000000 0xabc 0x200000; bootm 30000000
bootdelay=5
ethact=dm9000
ethaddr=00:0c:29:2f:4e:70
fileaddr=30000000
filesize=1C3590
ipaddr=192.168.1.50
mtddevname=u-boot
mtddevnum=0
mtdids=nand0=jz2440-0
mtdparts=mtdparts=jz2440-0:256k(u-boot),128k(params),1920k(kernel),-(rootfs)
netmask=255.255.255.0
partition=nand0,0
serverip=192.168.1.100
stderr=serial
stdin=serial
stdout=serial
Environment size: 497/131068 bytes
SMDK2410 #
这里这个参数可以重新设置
bootcmd=nand read 30000000 0xabc 0x200000; bootm 30000000
5.4 修改启动命令
在配置文件中修改:
#define CONFIG_BOOTCOMMAND "nand read 30000000 0xabc 0x200000; bootm 30000000"
修改为:
#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel; bootm 30000000"
重新编译,下载。
或者直接修改 启动命令
1. 直接修改启动参数
SMDK2410 # set bootcmd 'nand read 30000000 kernel; bootm 30000000' (注意: 这里是单引号)
2. 保存参数,一定要记得!!!
SMDK2410 # save
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x40000 -- 100% complete.
Writing to Nand... done
3. 重启
SMDK2410 # reset
resetting ...
U-Boot 2012.04.01 (Jul 18 2015 - 23:45:00)
CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0
4. 打印参数
SMDK2410 # print
baudrate=115200
bootargs=console=ttySAC0 root=/dev/mtdblock3
bootcmd=nand read kernel; bootm 30000000 打印出来了设置的参数
bootdelay=5
ethact=dm9000
ethaddr=00:0c:29:2f:4e:70
fileaddr=30000000
filesize=1C3590
ipaddr=192.168.1.50
mtddevname=u-boot
mtddevnum=0
mtdids=nand0=jz2440-0
mtdparts=mtdparts=jz2440-0:256k(u-boot),128k(params),1920k(kernel),-(rootfs)
netmask=255.255.255.0
partition=nand0,0
serverip=192.168.1.100
stderr=serial
stdin=serial
stdout=serial
Environment size: 489/131068 bytes
5. 直接启动内核 (如果倒数的时候,然它一直往下走,则会执行 bootcmd 定义的命令)
SMDK2410 # reset
resetting ...
U-Boot 2012.04.01 (Jul 18 2015 - 23:45:00)
CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0
NAND read: device 0 offset 0x60000, size 0x1e0000
1966080 bytes read: OK
## Booting kernel from Legacy Image at 30000000 ...
Image Name: Linux-2.6.22.6
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1848656 Bytes = 1.8 MiB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux...................................................................................................................... done, booting the kernel.
Linux version 2.6.22.6 (book@book-desktop) (gcc version 3.4.5) #1 Thu Jan 27 22:22:51 CST 2011
.......
打印一堆信息,启动内核了。
...........
1. 环境参数在哪里如何定义,如何传递给内核?
2. 如何在NAND中划分分区信息,这里的信息只是为了在uboot中便于使用,并不能真正为NAND分区,真正的分区是在linux内核中实现的。
3. 环境参数基本包括:这些都是保存在NAND中的。
启动参数,启动命令,分区信息表,以太网地址,ip地址,服务器地址等等。