Makefile mkconfig arm_config.mk config.mk
mkconfig详解
#!/bin/sh -e
#获得参数,开发板名字
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*) break ;;
esac
done
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
#${BOARD_NAME}即为开发板名称smdk6410
[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1
echo "Configuring for ${BOARD_NAME} board..."
#创建平台/开发板头文件链接
if [ "$SRCTREE" != "$OBJTREE" ] ; then
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
ln -s ${SRCTREE}/include/asm-$2 asm
LNPREFIX="../../include2/asm/"
cd ../include
rm -rf asm-$2
rm -f asm
mkdir asm-$2
ln -s asm-$2 asm
else
cd ./include
rm -f asm
ln -s asm-$2 asm
fi
rm -f asm-$2/arch
if [ "$3" = "s3c64xx" ] ; then
rm -f regs.h
ln -s $6.h regs.h
rm -f asm-$2/arch
ln -s arch-$3 asm-$2/arch
fi
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi
#创建include/config.mk配置文件
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
#创建头文件include/config.h
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
fi
echo "" >>config.h
echo "#include <configs/$1.h>" >>config.h
#头文件内容
exit 0
makefile详解
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 6
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) #1.1.6版本
VERSION_FILE = $(obj)include/version_autogenerated.h #版本文件
#HOSTARCH 使用主机的环境(硬件)
HOSTARCH := $(shell uname -m | \
sed -e s/i.86/i386/ \
-e s/sun4u/sparc64/ \
-e s/arm.*/arm/ \
-e s/sa110/arm/ \
-e s/powerpc/ppc/ \
-e s/macppc/ppc/)
#HOSTOS 主机的操作系统
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
export HOSTARCH HOSTOS #将这两个变量设置为环境变量
VENDOR= #开发商
#方法1
ifdef O #如果变量‘O’已经被定义过
ifeq ("$(origin O)", "command line") #如果是在命令行定义的变量‘O’,$(origin O)就是得到‘O’的定义来源
BUILD_DIR := $(O)
endif #变量‘O’为目标文件存放目录
endif
#方法2
ifneq ($(BUILD_DIR),) #如果变量BUILD_DIR不为空,即变量被定义过,将它的值赋给saved-output
saved-output := $(BUILD_DIR)
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})#在shell中判断${BUILD_DIR}目录是否存在,如果不存在就建目录
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
#在shell如果打开${BUILD_DIR}目录就调用PWD显示当前路径,将该路径赋值给 BUILD_DIR
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))#如果$(BUILD_DIR)为空,输出错误信息
endif
#OBJTREE LNDIR生成文件目录 SRCTREE TOPDIR源码目录
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
#方法3 如果$(BUILD_DIR)为空,将$(CURDIR)赋给OBJTREE,非空就将$(BUILD_DIR)赋给OBJTREE
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
#MKCONFIG指向源码所在目录下的mkconfig配置文件
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
ifneq ($(OBJTREE),$(SRCTREE)) #如果目标文件存放目录不是U-BOOT顶层目录,定义一个标志变量
REMOTE_BUILD := 1
export REMOTE_BUILD
endif
ifneq ($(OBJTREE),$(SRCTREE))#如果目标文件存放目录不是U-BOOT顶层目录,定义obj src
obj := $(OBJTREE)/
src := $(SRCTREE)/
else #如果目标文件存放目录是U-BOOT顶层目录,定义obj src为空
obj :=
src :=
endif
export obj src
ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk))#判断config.mk文件是否存在,如果存在就执行下去,如果不存在就要执行者make xxx.config来生成该文件
#执行config.mk,加载ARCH BAORD CPU配置
include $(OBJTREE)/include/config.mk
export ARCH CPU BOARD VENDOR SOC
#根据硬件结构指定交叉编译器
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
endif
export CROSS_COMPILE
#加载其他设置,include顶层目录下的config.mk配置文件(定义了交叉编译器 定义了编译选项 定义了编译规则)
include $(TOPDIR)/config.mk
#start.o必须放在第一位,u-boot执行的第一段代码为start.S
OBJS = cpu/$(CPU)/start.o
#加前缀函数 就是在$(OBJS)变量的前面加上$(obj),相当于获得准确的路径
OBJS := $(addprefix $(obj),$(OBJS))
#一下为编译u-boot需要的库文件
LIBS = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS += rtc/librtc.a
LIBS += dtt/libdtt.a
LIBS += drivers/libdrivers.a
LIBS += drivers/nand/libnand.a
LIBS += drivers/nand_legacy/libnand_legacy.a
LIBS += drivers/onenand/libonenand.a
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
LIBS += $(BOARDLIBS)
LIBS := $(addprefix $(obj),$(LIBS))
#.PHONY定义一个伪目标,$(LIBS)该目标是一个永远不会存在的文件(like make clean规则中的clean文件),不会建立该文件
.PHONY : $(LIBS)
#添加GCC库文件
PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
#伪目标用于执行tools examples post post/cpu下的makefile
SUBDIRS = tools \
examples \
post \
post/cpu
.PHONY : $(SUBDIRS)
ifeq ($(CONFIG_NAND_U_BOOT),y)
NAND_SPL = nand_spl
U_BOOT_NAND = $(obj)u-boot-nand.bin
endif
__OBJS := $(subst $(obj),,$(OBJS))
__LIBS := $(subst $(obj),,$(LIBS))
#这里为最终要生成的各种镜像文件
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
all: $(ALL)
$(obj)u-boot.hex: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
$(obj)u-boot.srec: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
$(obj)u-boot.bin: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
$(OBJDUMP) -d $< > $<.dis
$(obj)u-boot.img: $(obj)u-boot.bin
./tools/mkimage -A $(ARCH) -T firmware -C none \
-a $(TEXT_BASE) -e 0 \
-n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
-d $< $@
$(obj)u-boot.dis: $(obj)u-boot
$(OBJDUMP) -d $< > $@
#此处生成的是uboot的ELF文件镜像
$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
#依赖目标$(OBJS),也就是cpu/start.o
$(OBJS):
$(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))
#依赖目标$(LIBS),每个子目录下的*.a,通过执行相应子目录下的make来完成
$(LIBS):
$(MAKE) -C $(dir $(subst $(obj),,$@))
$(SUBDIRS):
$(MAKE) -C $@ all
$(NAND_SPL): version
$(MAKE) -C nand_spl/board/$(BOARDDIR) all
$(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin
cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
#生程版本文件
version:
@echo -n "#define U_BOOT_VERSION \"U-Boot " > $(VERSION_FILE); \
echo -n "$(U_BOOT_VERSION)" >> $(VERSION_FILE); \
echo -n $(shell $(CONFIG_SHELL) $(TOPDIR)/tools/setlocalversion \
$(TOPDIR)) >> $(VERSION_FILE); \
echo "\"" >> $(VERSION_FILE)
gdbtools:
$(MAKE) -C tools/gdb all || exit 1
updater:
$(MAKE) -C tools/updater all || exit 1
env:
$(MAKE) -C tools/env all || exit 1
depend dep:
for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done
tags ctags:
ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) include \
lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
fs/cramfs fs/fat fs/fdos fs/jffs2 \
net disk rtc dtt drivers drivers/sk98lin common \
\( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
etags:
etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) include \
lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
fs/cramfs fs/fat fs/fdos fs/jffs2 \
net disk rtc dtt drivers drivers/sk98lin common \
\( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
$(obj)System.map: $(obj)u-boot
@$(NM) $< | \
grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
sort > $(obj)System.map
#########################################################################
else
all $(obj)u-boot.hex $(obj)u-boot.srec $(obj)u-boot.bin \
$(obj)u-boot.img $(obj)u-boot.dis $(obj)u-boot \
$(SUBDIRS) version gdbtools updater env depend \
dep tags ctags etags $(obj)System.map:
@echo "System not configured - see README" >&2
@ exit 1
endif
.PHONY : CHANGELOG
CHANGELOG:
git log --no-merges U-Boot-1_1_5.. | \
unexpand -a | sed -e 's/\s\s*$$//' > $@
#unconfig清楚生成的配置文件
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board*/config.tmp
#make smdk6410_config相当与执行./mkconfig smdk6410(开发板名) arm(arch架构) s3c64xx(cpu) smdk6410(开发板) samsung(开发商) s3c6410(soc)
smdk6410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s3c64xx smdk6410 samsung s3c6410
clean:
find $(OBJTREE) -type f \
\( -name 'core' -o -name '*.bak' -o -name '*~' \
-o -name '*~' -o -name '.depend*' \
-o -name '*.o' -o -name '*.a' \) -print \
| xargs rm -f
rm -f u-boot*
rm -f $(obj)examples/hello_world $(obj)examples/timer \
$(obj)examples/eepro100_eeprom $(obj)examples/sched \
$(obj)examples/mem_to_mem_idma2intr $(obj)examples/82559_eeprom \
$(obj)examples/smc91111_eeprom $(obj)examples/interrupt \
$(obj)examples/test_burst
rm -f $(obj)tools/img2srec $(obj)tools/mkimage $(obj)tools/envcrc \
$(obj)tools/gen_eth_addr
rm -f $(obj)tools/mpc86x_clk $(obj)tools/ncb
rm -f $(obj)tools/easylogo/easylogo $(obj)tools/bmp_logo
rm -f $(obj)tools/gdb/astest $(obj)tools/gdb/gdbcont $(obj)tools/gdb/gdbsend
rm -f $(obj)tools/env/fw_printenv $(obj)tools/env/fw_setenv
rm -f $(obj)board/cray/L1/bootscript.c $(obj)board/cray/L1/bootscript.image
rm -f $(obj)board/netstar/eeprom $(obj)board/netstar/crcek $(obj)board/netstar/crcit
rm -f $(obj)board/netstar/*.srec $(obj)board/netstar/*.bin
rm -f $(obj)board/trab/trab_fkt $(obj)board/voiceblue/eeprom
rm -f $(obj)board/integratorap/u-boot.lds $(obj)board/integratorcp/u-boot.lds
rm -f $(obj)include/bmp_logo.h
rm -f $(obj)nand_spl/u-boot-spl $(obj)nand_spl/u-boot-spl.map
clobber: clean
find $(OBJTREE) -type f \( -name .depend \
-o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \
-print0 \
| xargs -0 rm -f
rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS $(obj)include/version_autogenerated.h
rm -fr $(obj)*.*~
rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
rm -f $(obj)tools/crc32.c $(obj)tools/environment.c $(obj)tools/env/crc32.c
rm -f $(obj)tools/inca-swap-bytes $(obj)cpu/mpc824x/bedbug_603e.c
rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
[ ! -d $(OBJTREE)/nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
ifeq ($(OBJTREE),$(SRCTREE))
mrproper \
distclean: clobber unconfig
else
mrproper \
distclean: clobber unconfig
rm -rf $(OBJTREE)/*
endif
backup:
F=`basename $(TOPDIR)` ; cd .. ; \
gtar --force-local -zcvf `date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F
#########################################################################
u-boot第一阶段代码分析
/board/samsung/sdmk6410/u-boot.lds得知U-boot首先执行/cpu/s3c64xx/start.S
start.S
1.reset将CPU的模式设置为管理模式(svc)
uboot初始化中,为何要设置CPU为SVC模式而不是设置为其他模式?
arm的七种工作模式中管理模式(svc)能访问的硬件资源最多(对CPU初始化硬件最合适),另外从u-boot跳转到kernel时也要求CPU处于管理模式
2.cpu_init_crit初始化CPU的关键寄存器
关闭MMU和catch
为什么要关闭catch和MMU呢?catch和MMU是做什么用的?
Catch是cpu内部的一个2级缓存,她的作用是将常用的数据和指令放在cpu内部,MMU是用来做虚实地址转换用的,我们的目的是设置控制的寄存器,寄存器都是实地址,如果既要开启MMU又要做虚实地址转换的话,中间还多一步,先要把实地址转换成虚地址,然后再做设置,但对uboot而言就是起到一个简单的初始化的作用和引导操作系统,如果开启MMU的话,很麻烦,也没必要,所以关闭MMU.
说道catch就必须提到一个关键字Volatile,以后在设置寄存器时会经常遇到,他的本质是告诉编译器不要对我的代码进行优化,优化的过程是将常用的代码取出来放到catch中,它没有从实际的物理地址去取,它直接从cpu的缓存中去取,但常用的代码就是为了感知一些常用变量的变化,如果正在取数据的时候发生跳变,那么就感觉不到变量的变化了,所以在这种情况下要用 Volatile关键字告诉编译器不要做优化,每次从实际的物理地址中去取指令,这就是为什么关闭catch关闭MMU。但在C语言中是不会关闭 catch和MMU的,会打开,如果编写者要感知外界变化,或变化太快,从catch中取数据会有误差,就加一个关键字Volatile。
重映射SFR(特殊功能寄存器的地址)
关闭看门狗 关中断
3.跳转到lowlevel_init(/board/samsung/sdmk6410/lowlevel_init.S)设置系统时钟
4.复制第二阶段代码到SDRAM中(使能mmu)
5.设置栈,即确定内存的使用情况
6.跳转到第二阶段的C程序代码入口(/lib_arm/board.c)
注意:/include/configs/smdk6410.h定义了开发板的配置信息(前缀为CONFIG_和CFG_宏)
u-boot.lds 文件说明
OUTPUT_FORMAT("elf32littlearm", "elf32littlearm", "elf32littlearm");指定输出可执行文件是 elf 格式,32 位 ARM 指令,小端
OUTPUT_ARCH(arm);指定输出可执行文件的平台为 ARM
ENTRY(_start);指定输出可执行文件的起始代码段为_start.
SECTIONS
{
. = 0x00000000 ; 从 0x0 位置开始
. = ALIGN(4) ; 代码以 4 字节对齐
.text : ;指定代码段
{
cpu/arm920t/start.o (.text) ; 代码的第一个代码部分
*(.text) ;其它代码部分
}
. = ALIGN(4)
.rodata : { *(.rodata) } ;指定只读数据段
. = ALIGN(4);
.data : { *(.data) } ;指定读/写数据段
. = ALIGN(4);
.got : { *(.got) } ;指定 got 段, got 段式是 uboot 自定义的一个段, 非标准段
__u_boot_cmd_start = . ;把__u_boot_cmd_start 赋值为当前位置, 即起始位置
.u_boot_cmd : { *(.u_boot_cmd) } ;指定 u_boot_cmd 段, uboot 把所有的 uboot 命令放在该段.
__u_boot_cmd_end = .;把__u_boot_cmd_end 赋值为当前位置,即结束位置
. = ALIGN(4);
__bss_start = .; 把__bss_start 赋值为当前位置,即 bss 段的开始位置
.bss : { *(.bss) }; 指定 bss 段
_end = .; 把_end 赋值为当前位置,即 bss 段的结束位置
}
idea6410开发板u-boot1.1.6移植dm9000a驱动
首先,从http://ftp.denx.de/pub/u-boot/下载u-boot-2010.06.tar.bz2,解压后用u-boot-2010.06/driver/net中的dm9000x.c和dm9000x.h替换友坚u-boot driver目录下的dm9000x.c和dm9000x.h,并将u-boot-2010.06/include/目录下的dm9000.h拷贝到友坚u-boot include目录下。
其次,修改/include/configs/smdk6410.h,将
#ifdef CONFIG_DRIVER_SMC911X
#undef CONFIG_DRIVER_CS8900
#define CONFIG_DRIVER_SMC911X_BASE 0x18800300
#else
#define CONFIG_DRIVER_CS8900 0
#define CS8900_BASE 0x18800300
#define CS8900_BUS16 1
#endif替换为
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0X18000300
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
#define CONFIG_DM9000_NO_SROM 1
#define CONFIG_NET_MULTI 1
#define CONFIG_SYS_HZ 1000
再次,修改/board/samsung/smdk6410/smdk6410.c文件,将文件中的CS8900字符全部替换为dm9000
然后,在/net/eth.c中添加
extern int dm9000_initialize(bd_t*);
在函数int eth_initialize(bd_t *bis)
{
#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
miiphy_init();
#endif
#if defined(CONFIG_DRIVER_DM9000)
dm9000_initialize(bis);
#endif
}
最后,按照手册编译生成u-boot-nand.bin文件
方法二:
前两天在6410开发板上玩了玩u-boot,开发板是友坚的6410开发板,配套的光盘中给的是很古老的u-boot 1.1.6,而且没有网络支持。从网上下了个最新的uboot-2010.06版本,看了下发现它并不支持6410的SD卡启动模式,本来是想移植下,使得新版本也支持SD卡启动,但现在时间很紧张,没那么多时间慢慢玩了,于是就想把dm9000弄上去。
本来以为dm9000这类的大白菜,uboot肯定是一切ok了,但google了下,发现有人说低版本的uboot带的dm9000x.c驱动是不支持dm9000a的,只支持比较老的dm9000x。于是看linux 2.6.32内核代码,发现有dm9000驱动,对比了下,也没觉得有多大差别,为了省事,又看了下uboot2010.06版本里面的dm9000驱动。看注释,发现它已经支持dm9000ae了。于是直接拷贝过来,替换原先的dm9000x.c。
在include/configs/smdk6410.h中添加
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0X18000300
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
#define CONFIG_DM9000_NO_SROM 1
注销其他网卡芯片的支持,比如//#define CONFIG_DRIVER_SMC911X 1 /* we have a SMC9115 on-board */
再添加:
#define CONFIG_NET_MULTI 1
修改board/smdk6410.c
本来里面好像是cs8900的,所以里面有这么一些与cs8900相关的代码:
#define CS8900_Tacs (0x0) // 0clk address set-up
#define CS8900_Tcos (0x4) // 4clk chip selection set-up
#define CS8900_Tacc (0xE) // 14clk access cycle
#define CS8900_Tcoh (0x1) // 1clk chip selection hold
#define CS8900_Tah (0x4) // 4clk address holding time
#define CS8900_Tacp (0x6) // 6clk page mode access cycle
#define CS8900_PMC (0x0) // normal(1data)page mode configuration
static void cs8900_pre_init(void)
{
SROM_BW_REG &= ~(0xf << 4);
SROM_BW_REG |= (1<<7) | (1<<6) | (1<<4);
SROM_BC1_REG = ((CS8900_Tacs<<28)+(CS8900_Tcos<<24)+(CS8900_Tacc<<16)+(CS8900_Tcoh<<12)+(CS8900_Tah<<8)+(CS8900_Tacp<<4)+(CS8900_PMC));
}
int board_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
cs8900_pre_init();//改为dm9000_pre_init
gd->bd->bi_arch_number = MACH_TYPE;
gd->bd->bi_boot_params = (PHYS_SDRAM_1+0x100);
#if 0
icache_enable();
dcache_enable();
#endif
return 0;
}
把所有cs8900改为dm9000,代码是不需要改的,对照s3c6410手册,这块memory访问的配置是没问题。这个开发板是用的是16bit的模式,所以确认cs8900_pre_init确实是把总线初始化为16bit模式的。
在net/eth.c中添加
extern int dm9000_initialize(bd_t*);
int eth_initialize(bd_t *bis)
{
char enetvar[32], env_enetaddr[6];
int i, eth_number = 0;
char *tmp, *end;
eth_devices = NULL;
eth_current = NULL;
#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
miiphy_init();
#endif
#if defined(CONFIG_DRIVER_DM9000)
dm9000_initialize(bis);//这是我添加的
#endif
#if defined(CONFIG_DB64360) || defined(CONFIG_CPCI750)
mv6436x_eth_initialize(bis);
#endif
编译测试。顺便说下,这个工作看起来是简单的,但仍然碰到一些问题,花了两天时间才搞定。特别开始的时候忘记定义#define CONFIG_DM9000_NO_SROM 1
结果导致每次mac地址都不对,后来看了下代码,才发现如果没有定义CONFIG_DM9000_NO_SROM,则uboot会从eeprom中读mac地址,dm9000是支持eeprom接口的,但友坚开发板上并没有用这个功能,所以需要设置CONFIG_DM9000_NO_SROM。
还遇到个恶心的问题,就是ping不通,一会说checksum bad,一会又是无任何提示的,直接给出”host is not active“。这个问题足足浪费我一天时间,最后发现是防火墙问题,把系统防火墙关闭就正常。不过我在另一台台式机上测试,防火墙开了也没啥影响,就是在我这台笔记本上不行。
bluehacker
实验过程
ubuntu9.04配置tftp
1:在新立得软件包管理器中安装 xinetd, tftpd, tftp.
2:在/etc/xinetd.d/下增加一个文件,名为tftp,内容如下:
service tftp
{
disable = no
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftproot
}
3:进入目录/etc/init.d/中,重新启动xinetd
sudo ./xinetd restart
4:到根目录创建文件夹 /tftproot,并将权限设置为777
sudo mkdir /tftproot
sudo chmod 777 /tftproot
5:将生成的内核镜像zImage拷贝到/tftproot目录下
6:主机ip地址192.168.1.20
设置u-boot启动参数
#setenv bootcmd tftp 0xc0008000 zImage\;bootm 0xc0008000
#setenv bootargs "root=/dev/nfs nfsroot=192.168.1.10:/home/yangze/nfs_share ip=192.168.1.20:192.168.1.10:192.168.1.1:255.255.255.0:www.urbetter.com:eth0:off console=ttySAC0,115200"
#saveenv
实验结果
OK
U-Boot 1.1.6 (Jun 9 2011 - 15:14:49) for SMDK6410
****************************************
** UT-S3C6410 Nand boot v1.0 **
** ShenZhen Urbetter Technology **
** Http://www.urbetter.com **
****************************************
CPU: S3C6410@532MHz
Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)
Board: SMDK6410
DRAM: 128 MB
Flash: 0 kB
NAND: 256 MB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot: 0
dm9000 i/o: 0x18000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: c7e32ff8M
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.10; our IP address is 192.168.1.20
Filename 'zImage'.
Load address: 0xc0008000
Loading: checksum bad
T #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##################
done
Bytes transferred = 2088756 (1fdf34 hex)
Boot with zImage
Starting kernel ...
Uncompressing Linux........................................................................................................................................ done, booting the kernel.
Linux version 2.6.28.6 (yangze@ubuntu) (gcc version 4.2.2) #60 Tue Dec 14 16:29:29 CST 2010
CPU: ARMv6-compatible processor [410fb766] revision 6 (ARMv7), cr=00c5387f
CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
Machine: SMDK6410
TFTP内核镜像文件到sdram,NFS根文件系统,linux启动完成
这个网上有DM9000A的驱动,只要替换对应的driver/dm9000.c 和driver/dm9000.h即可,但是发现只有在使用ping命令(发送数据包)的时候,对应的网卡才会激活,而一旦ping结束后,那么网卡就会自动断掉,查看代码发现在do_ping时会做eth_init,而结束后会做eth_close动作
所以在start_armboot函数中加入初始化动作:eth_init(gd->bd); 并注释掉eth_close动作即可。
http://blog.sina.com.cn/u/1241837852
友坚恒天已经正式推出了exynos 4412开发板~