[置顶] 友坚U-boot-1.1.6学习及移植dm9000a驱动

1.  u-boot的源码顶层目录说明

目    录                特    性                解 释 说 明
board                平台依赖              /board/samsung/smdk6410

cpu                    平台依赖             /cpu/s3c64xx/s3c6410

lib_arm              平台依赖             存放对ARM体系结构通用的文件,
                                                      主要用于实现ARM平台通用的函数

include              通用                    头文件和开发板配置文件,
                                                      所有开发板的配置文件都在configs目录下

common            通用                   通用的多功能函数实现
lib_generic        通用                   通用库函数的实现
net                      通用                   存放网络的程序
fs                        通用                   存放文件系统的程序
post                   通用                    存放上电自检程序
drivers               通用                    通用的设备驱动程序,主要有以太网接口的驱动
disk                   通用                     硬盘接口程序
rtc                      通用                    RTC的驱动程序
dtt                      通用                    数字温度测量器或者传感器的驱动
examples          应用例程             一些独立运行的应用程序的例子,例如helloworld
tools                  工具                   存放制作S-Record或者u-boot格式的映像等工具

2.  顶层目录中的几个重要文件

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("elf32­littlearm", "elf32­littlearm", "elf32­littlearm");指定输出可执行文件是 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开发板~

[置顶] 友坚U-boot-1.1.6学习及移植dm9000a驱动_第1张图片

你可能感兴趣的:(shell,File,cmd,Build,include,编译器)