uboot分析第一阶段学习笔记


##############################################
  makefile文件
##############################################
分析makefile得到的第一个文件arch/arm/cpu/arm1176/start.s

 

 

mini6410_noUSB_config   \
mini6410_config : unconfig
 @mkdir -p $(obj)include $(obj)board/samsung/mini6410
 @mkdir -p $(obj)nand_spl/board/samsung/mini6410
 @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
 @if [ -z "$(findstring mini6410_noUSB_config,$@)" ]; then   \
  echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/mini6410/config.tmp;\
 else          \
  echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/mini6410/config.tmp;\
 fi
 /********************************************************/
 @$(MKCONFIG) mini6410 arm arm1176 mini6410 samsung s3c64xx
 /*********************************************************/
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk

注释语名中使用的@$(MKCONFIG) 为以下内容
MKCONFIG := $(SRCTREE)/mkconfig
相当于执行以下命令:
mkconfig mini6410 arm arm1176 mini6410 samsung s3c64xx
  $0       $1     $2     $3       $4      $5     $6


uboot依赖于谁:
GEN_UBOOT = \
  UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
  sed  -n -e 's/.*\($(SYM_PREFIX)__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
可以通过编译来查看具体参数的值:
编译结果如下:
UNDEF_SYM=`arm-linux-objdump -x board/samsung/mini6410/libmini6410.o api/libapi.o arch/arm/cpu/arm1176/libarm1176.o arch/arm/cpu/arm1176/s3c64xx/libs3c64xx.o arch/arm/lib/libarm.o common/libcommon.o disk/libdisk.o drivers/bios_emulator/libatibiosemu.o drivers/block/libblock.o drivers/dma/libdma.o drivers/fpga/libfpga.o drivers/gpio/libgpio.o drivers/hwmon/libhwmon.o drivers/i2c/libi2c.o drivers/input/libinput.o drivers/misc/libmisc.o drivers/mmc/libmmc.o drivers/mtd/libmtd.o drivers/mtd/nand/libnand.o drivers/mtd/onenand/libonenand.o drivers/mtd/spi/libspi_flash.o drivers/mtd/ubi/libubi.o drivers/net/libnet.o drivers/net/phy/libphy.o drivers/pci/libpci.o drivers/pcmcia/libpcmcia.o drivers/power/libpower.o drivers/rtc/librtc.o drivers/serial/libserial.o drivers/spi/libspi.o drivers/twserial/libtws.o drivers/usb/gadget/libusb_gadget.o drivers/usb/host/libusb_host.o drivers/usb/musb/libusb_musb.o drivers/usb/phy/libusb_phy.o drivers/video/libvideo.o drivers/watchdog/libwatchdog.o fs/cramfs/libcramfs.o fs/ext2/libext2fs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o fs/reiserfs/libreiserfs.o fs/ubifs/libubifs.o fs/yaffs2/libyaffs2.o lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o lib/lzo/liblzo.o net/libnet.o post/libpost.o | sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;

#这里就指定了u-boot.lds的首地址为0x57e00000(u-boot.lds 是不是换到了board/samsung/mini6410/U-boot-nand.lds?)
cd /opt/u-boot/u-boot-2010.12-for-MINI6410-master && arm-linux-ld -Bstatic -T u-boot.lds  -pie -Ttext 0x57e00000

#指定所用到类库
$UNDEF_SYM arch/arm/cpu/arm1176/start.o --start-group api/libapi.o arch/arm/cpu/arm1176/libarm1176.o arch/arm/cpu/arm1176/s3c64xx/libs3c64xx.o arch/arm/lib/libarm.o common/libcommon.o disk/libdisk.o drivers/bios_emulator/libatibiosemu.o drivers/block/libblock.o drivers/dma/libdma.o drivers/fpga/libfpga.o drivers/gpio/libgpio.o drivers/hwmon/libhwmon.o drivers/i2c/libi2c.o drivers/input/libinput.o drivers/misc/libmisc.o drivers/mmc/libmmc.o drivers/mtd/libmtd.o drivers/mtd/nand/libnand.o drivers/mtd/onenand/libonenand.o drivers/mtd/spi/libspi_flash.o drivers/mtd/ubi/libubi.o drivers/net/libnet.o drivers/net/phy/libphy.o drivers/pci/libpci.o drivers/pcmcia/libpcmcia.o drivers/power/libpower.o drivers/rtc/librtc.o drivers/serial/libserial.o drivers/spi/libspi.o drivers/twserial/libtws.o drivers/usb/gadget/libusb_gadget.o drivers/usb/host/libusb_host.o drivers/usb/musb/libusb_musb.o drivers/usb/phy/libusb_phy.o drivers/video/libvideo.o drivers/watchdog/libwatchdog.o fs/cramfs/libcramfs.o fs/ext2/libext2fs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o fs/reiserfs/libreiserfs.o fs/ubifs/libubifs.o fs/yaffs2/libyaffs2.o lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o lib/lzo/liblzo.o net/libnet.o post/libpost.o board/samsung/mini6410/libmini6410.o --end-group /opt/u-boot/u-boot-2010.12-for-MINI6410-master/arch/arm/lib/eabi_compat.o -L /opt/FriendlyARM/toolschain/4.5.1/lib/gcc/arm-none-linux-gnueabi/4.5.1 -lgcc

-Map u-boot.map -o u-boot

查看LDFLAGS的值为:
在uboot源码目录下查询: grep "LDFLAGS" * -nR 是在uboot根目录下的config.mk文件中
config.mk:207:LDFLAGS += -Bstatic -T $(obj)u-boot.lds $(PLATFORM_LDFLAGS)
config.mk:209:LDFLAGS += -Ttext $(TEXT_BASE)

TEXT_BASE的值放在board/samsung/mini6410/config.mk文件中可以看到说明


简单的单片机程序:
初始化:关看门狗
        初始化时钟
 初始化sdram
把程序从nand--->sdram中
设置sp

uboot的功能:
硬件相关初始化:关看门狗
  初始化时钟
  初始化SDRAM
  设置栈 使sp指向某块内存
  从flash中读出内核
启动内核

 

 


////////////////////////////////////////////////////////
                mkconfig文件
////////////////////////////////////////////////////////
[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"


#!/bin/sh -e

# Script to create header files and links to configure
# U-Boot for a specific board.
#
# Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]
#
# (C) 2002-2010 DENX Software Engineering, Wolfgang Denk <[email protected]>
#

APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
TARGETS=""

arch=""
cpu=""
board=""
vendor=""
soc=""
options=""

if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
 # Automatic mode
 line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
  echo "make: *** No rule to make target \`$2_config'.  Stop." >&2
  exit 1
 }

 set ${line}
 # add default board name if needed
 [ $# = 3 ] && set ${line} ${1}
fi

while [ $# -gt 0 ] ; do
 case "$1" in
 --) shift ; break ;;
 -a) shift ; APPEND=yes ;;
 -n) shift ; BOARD_NAME="${1%_config}" ; shift ;;
 -t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
 *)  break ;;
 esac
done
#如果命令个数小于4或大于7 将会退出
[ $# -lt 4 ] && exit 1
[ $# -gt 7 ] && exit 1

# Strip all options and/or _config suffixes
CONFIG_NAME="${1%_config}"
#mkconfig mini6410 arm arm1176 mini6410 samsung s3c64xx
#BOARD_NAME=第二个命令参数mini6410
[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"

arch="$2"
cpu="$3"
if [ "$4" = "-" ] ; then
 board=${BOARD_NAME}
else
 board="$4"
fi
[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
[ $# -gt 6 ] && [ "$7" != "-" ] && {
 # check if we have a board config name in the options field
 # the options field mave have a board config name and a list
 # of options, both separated by a colon (':'); the options are
 # separated by commas (',').
 #
 # Check for board name
 tmp="${7%:*}"
 if [ "$tmp" ] ; then
  CONFIG_NAME="$tmp"
 fi
 # Check if we only have a colon...
 if [ "${tmp}" != "$7" ] ; then
  options=${7#*:}
  TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"
 fi
}

if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
 echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
 exit 1
fi

#编译配置时输出文本
if [ "$options" ] ; then
 echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
 echo "Configuring for ${BOARD_NAME} board..."
fi

#
# Create link to architecture specific headers
#
if [ "$SRCTREE" != "$OBJTREE" ] ; then
 mkdir -p ${OBJTREE}/include
 mkdir -p ${OBJTREE}/include2
 cd ${OBJTREE}/include2
 rm -f asm
 ln -s ${SRCTREE}/arch/${arch}/include/asm asm
 LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/
 cd ../include
 rm -f asm
 ln -s ${SRCTREE}/arch/${arch}/include/asm asm
else
#以下几条命令就相当于执行ln -s asm-arm asm
#查看源码
#[root@localhost include]# ls -l asm
#lrwxrwxrwx. 1 root root 23 Aug 17 12:21 asm -> ../arch/arm/include/asm
#在编译的时候asm就指向对应的平台
 cd ./include
 rm -f asm
 ln -s ../arch/${arch}/include/asm asm
fi

rm -f asm/arch


#以下几条命令就相当于执行ln -s arch-s3c64xx asm/arch
#查看源码
#[root@localhost include]# ls asm/arch -l
#lrwxrwxrwx. 1 root root 12 Aug 17 12:21 asm/arch -> arch-s3c64xx
if [ -z "${soc}" ] ; then
 ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
 ln -s ${LNPREFIX}arch-${soc} asm/arch
fi

#arch=$2,同上相当于执行ln -s proc-armv asm/proc
if [ "${arch}" = "arm" ] ; then
 rm -f asm/proc
 ln -s ${LNPREFIX}proc-armv asm/proc
fi

# 创建一个配置文件
# Create include file for Make
#
#尖括号表示创建,两个尖括号表示追加
#查看config.mk文件
#[root@localhost include]# cat config.mk
#ARCH   = arm
#CPU    = arm1176
#BOARD  = mini6410
#VENDOR = samsung
#SOC    = s3c64xx
#CONFIG_NAND_U_BOOT = y
echo "ARCH   = ${arch}"  >  config.mk
echo "CPU    = ${cpu}"   >> config.mk
echo "BOARD  = ${board}" >> config.mk

[ "${vendor}" ] && echo "VENDOR = ${vendor}" >> config.mk

[ "${soc}"    ] && echo "SOC    = ${soc}"    >> config.mk

 


# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
    BOARDDIR=${board}
else
    BOARDDIR=${vendor}/${board}
fi

# 创建头文件config.h
# Create board specific header file
#
# 查看头文件的内容
#[root@localhost include]# cat config.h
#/* Automatically generated - do not edit */
#define CONFIG_BOARDDIR board/samsung/mini6410
#include <config_defaults.h>
#include <configs/mini6410.h>
#include <asm/config.h>
if [ "$APPEND" = "yes" ] # Append to existing config file
then
 echo >> config.h
else
 > config.h  # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h

for i in ${TARGETS} ; do
 i="`echo ${i} | sed '/=/ {s/=/\t/;q } ; { s/$/\t1/ }'`"
 echo "#define CONFIG_${i}" >>config.h ;
done

cat << EOF >> config.h
#define CONFIG_BOARDDIR board/$BOARDDIR
#include <config_defaults.h>
#include <configs/${CONFIG_NAME}.h>
#include <asm/config.h>
EOF

exit 0

 

#############################################################################
    start.o
#############################################################################
/*
 *  armboot - Startup Code for ARM1176 CPU-core
 *
 * Copyright (c) 2007 Samsung Electronics
 *
 * Copyright (C) 2008
 * Guennadi Liakhovetki, DENX Software Engineering, <[email protected]>
 *
 * 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
 *
 * 2007-09-21 - Restructured codes by jsgood ([email protected])
 * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
 * jsgood ([email protected])
 * Base codes by scsuh (sc.suh)
 */

#include <asm-offsets.h>
#include <config.h>
#include <version.h>
#ifdef CONFIG_ENABLE_MMU
#include <asm/proc/domain.h>
#endif

#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)
#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE
#endif

#if defined(CONFIG_MINI6410_LED)
#define ELFIN_GPIO_BASE_8BIT  0x7f000000
#define ELFIN_GPK_BASE_8BIT  0x8800
#define GPKCON0_OFFSET_8BIT  0x00
#define GPKCON1_OFFSET_8BIT  0x04
#define GPKDAT_OFFSET_8BIT  0x08
#define GPKPUD_OFFSET_8BIT  0x0C
#endif
/*
 *************************************************************************
 *
 * Jump vector table as in table 3.1 in [1]
 *
 *************************************************************************
 */

.globl _start
_start: b reset
#ifndef CONFIG_NAND_SPL
 ldr pc, _undefined_instruction
 ldr pc, _software_interrupt
 ldr pc, _prefetch_abort
 ldr pc, _data_abort
 ldr pc, _not_used
 ldr pc, _irq
 ldr pc, _fiq

_undefined_instruction:
 .word undefined_instruction
_software_interrupt:
 .word software_interrupt
_prefetch_abort:
 .word prefetch_abort
_data_abort:
 .word data_abort
_not_used:
 .word not_used
_irq:
 .word irq
_fiq:
 .word fiq
_pad:
 .word 0x12345678 /* now 16*4=64 */
#else
 . = _start + 64
#endif

.global _end_vect
_end_vect:
 .balignl 16,0xdeadbeef
/*
 *************************************************************************
 *
 * Startup Code (reset vector)
 *
 * do important init only if we don't start from memory!
 * setup Memory and board specific bits prior to relocation.
 * relocate armboot to ram
 * setup stack
 *
 *************************************************************************
 */

.globl _TEXT_BASE
_TEXT_BASE:
 .word CONFIG_SYS_TEXT_BASE

/*
 * Below variable is very important because we use MMU in U-Boot.
 * Without it, we cannot run code correctly before MMU is ON.
 * by scsuh.
 */
_TEXT_PHY_BASE:
 .word CONFIG_SYS_PHY_UBOOT_BASE

/*
 * These are defined in the board-specific linker script.
 * Subtracting _start from them lets the linker put their
 * relative position in the executable instead of leaving
 * them null.
 */

.globl _bss_start_ofs
_bss_start_ofs:
 .word __bss_start - _start

.globl _bss_end_ofs
_bss_end_ofs:
 .word _end - _start

/* IRQ stack memory (calculated at run-time) + 8 bytes */
.globl IRQ_STACK_START_IN
IRQ_STACK_START_IN:
 .word 0x0badc0de

/*
 * the actual reset code
 */

reset:
 /* 1 cpu设为管理模式
  * set the cpu to SVC32 mode
  */
 //将状态寄存器的内容读到通用寄存器
 mrs r0, cpsr
 //清除位指令
 bic r0, r0, #0x3f
 //修改r0低八位
 orr r0, r0, #0xd3
 //将通用寄存器读到状态寄存器
 msr cpsr, r0

/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */
 /*
  * we do sys-critical inits only at reboot,
  * not when booting from ram!
  */
cpu_init_crit:
 /*
  * When booting from NAND - it has definitely been a reset, so, no need
  * to flush caches and disable the MMU
  */
#ifndef CONFIG_NAND_SPL
 /* 关flush清caches
  * flush v4 I/D caches
  */
 mov r0, #0
 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

 /*
  * disable MMU stuff and caches
  */
 mrc p15, 0, r0, c1, c0, 0
 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache

 /* Prepare to disable the MMU */
 adr r2, mmu_disable_phys
 sub r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
 b mmu_disable

 .align 5
 /* Run in a single cache-line */
mmu_disable:
 mcr p15, 0, r0, c1, c0, 0
 nop
 nop
 mov pc, r2
mmu_disable_phys:

#ifdef CONFIG_DISABLE_TCM
 /*
  * Disable the TCMs
  */
 mrc p15, 0, r0, c0, c0, 2 /* Return TCM details */
 cmp r0, #0
 beq skip_tcmdisable
 mov r1, #0
 mov r2, #1
 tst r0, r2
 mcrne p15, 0, r1, c9, c1, 1 /* Disable Instruction TCM if present*/
 tst r0, r2, LSL #16
 mcrne p15, 0, r1, c9, c1, 0 /* Disable Data TCM if present*/
skip_tcmdisable:
#endif
#endif

#ifdef CONFIG_PERIPORT_REMAP
 /* Peri port setup */
 ldr r0, =CONFIG_PERIPORT_BASE
 orr r0, r0, #CONFIG_PERIPORT_SIZE
 mcr p15,0,r0,c15,c2,4
#endif

 /* 2 跳转到lowlevel_init.S文件
  * 关看门狗,关中断,初始化系统时钟,初始化内存sdram
  * Go setup Memory and board specific bits prior to relocation.
  */
 bl lowlevel_init  /* go setup pll,mux,memory */

/* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:
 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
#ifndef CONFIG_NAND_SPL
 ldr r0,=0x00000000
 bl board_init_f
/*------------------------------------------------------------------------------*/

/*
 * void relocate_code (addr_sp, gd, addr_moni)
 *
 * This "function" does not return, instead it continues in RAM
 * after relocating the monitor code.
 *
 */
 .globl relocate_code
relocate_code:
 mov r4, r0 /* save addr_sp */
 mov r5, r1 /* save addr of gd */
 mov r6, r2 /* save addr of destination */
 ldr r9, =0x00000000
 /*3设置栈*/
 /* Set up the stack          */
stack_setup:
 mov sp, r4

 adr r0, _start
 cmp r0, r6
 beq fixsym  /* skip relocation */
#if defined(CONFIG_MINI6410_LED)  
/* 4 将代码从flash复制到sdram中*/
/* if relocate the u-boot code, LED2 will on.*/
 mov r1, #ELFIN_GPIO_BASE_8BIT
 add r1, r1, #ELFIN_GPK_BASE_8BIT
/*  SPL will do it!
 ldr r2, =0x11111111
 str r2, [r1, #GPKCON0_OFFSET_8BIT]
 ldr r2, =0x0000AAAA
 str r2, [r1, #GPKPUD_OFFSET_8BIT]
*/
 ldr r2, [r1, #GPKDAT_OFFSET_8BIT]
 and r2, r2, #0xffffffbf
 str r2, [r1, #GPKDAT_OFFSET_8BIT]
#endif
 mov r1, r6   /* r1 <- scratch for copy_loop */
/* ldr r2, _TEXT_BASE  */
 ldr r3, _bss_start_ofs
 add r2, r0, r3  /* r2 <- source end address     */


copy_loop:
 ldmia r0!, {r9-r10}  /* copy from source address [r0]    */
 stmia r1!, {r9-r10}  /* copy to   target address [r1]    */
 cmp r0, r2   /* until source end address [r2]    */
 blo copy_loop

#ifndef CONFIG_PRELOADER
 /*
  * fix .rel.dyn relocations
  */
fixsym:
 ldr r0, _TEXT_BASE  /* r0 <- Text base */
 sub r9, r6, r0  /* r9 <- relocation offset */
 ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
 add r10, r10, r0  /* r10 <- sym table in FLASH */
 ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
 add r2, r2, r0  /* r2 <- rel dyn start in FLASH */
 ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
 add r3, r3, r0  /* r3 <- rel dyn end in FLASH */
fixloop:
 ldr r0, [r2]  /* r0 <- location to fix up, IN FLASH! */
 add r0, r0, r9  /* r0 <- location to fix up in RAM */
 ldr r1, [r2, #4]
 and r7, r1, #0xff
 cmp r7, #23   /* relative fixup? */
 beq fixrel
 cmp r7, #2   /* absolute fixup? */
 beq fixabs
 /* ignore unknown type of fixup */
 b fixnext
fixabs:
 /* absolute fix: set location to (offset) symbol value */
 mov r1, r1, LSR #4  /* r1 <- symbol index in .dynsym */
 add r1, r10, r1  /* r1 <- address of symbol in table */
 ldr r1, [r1, #4]  /* r1 <- symbol value */
 add r1, r1, r9  /* r1 <- relocated sym addr */
 b fixnext
fixrel:
 /* relative fix: increase location by offset */
 ldr r1, [r0]
 add r1, r1, r9
fixnext:
 str r1, [r0]
 add r2, r2, #8  /* each rel.dyn entry is 8 bytes */
 cmp r2, r3
 blo fixloop
#endif
#endif

#ifdef CONFIG_ENABLE_MMU
enable_mmu:
 /* enable domain access */
 ldr r5, =0x0000ffff
 mcr p15, 0, r5, c3, c0, 0 /* load domain access register */

 /* Set the TTB register */
 ldr r0, _mmu_table_base
 ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE
 ldr r2, =0xfff00000
 bic r0, r0, r2
 orr r1, r0, r1
 mcr p15, 0, r1, c2, c0, 0

 /* Enable the MMU */
 mrc p15, 0, r0, c1, c0, 0
 orr r0, r0, #1  /* Set CR_M to enable MMU */

 /* Prepare to enable the MMU */
 adr r1, skip_hw_init
 and r1, r1, #0x3fc
 ldr r2, _TEXT_BASE
 ldr r3, =0xfff00000
 and r2, r2, r3
 orr r2, r2, r1
 b mmu_enable

 .align 5
 /* Run in a single cache-line */
mmu_enable:

 mcr p15, 0, r0, c1, c0, 0
 nop
 nop
 mov pc, r2
skip_hw_init:
#endif

/*5 清bss段,即初始值为0的静态变量或是全局变量,全部初始值为0,所以清空该段*/
clear_bss:
#ifndef CONFIG_PRELOADER
 ldr r0, _bss_start_ofs
 ldr r1, _bss_end_ofs
/*  ldr r3, _TEXT_BASE  *//* Text base */
 mov r4, r6   /* reloc addr */
 add r0, r0, r4
 add r1, r1, r4
 mov r2, #0x00000000  /* clear       */

clbss_l:str r2, [r0]  /* clear loop...      */
 add r0, r0, #4
 cmp r0, r1
 bne clbss_l

 bl coloured_LED_init
 bl red_LED_on
#endif

/*
 * We are done. Do not return, instead branch to second part of board
 * initialization, now running from RAM.
 */
#ifdef CONFIG_NAND_SPL

/*6 检查boot启动状态,从相应位置启动*/
/*check boot status */
#define MEM_CFG_STAT 0x7E00F12C

 ldr r1, =MEM_CFG_STAT  /* address of reg  MEM_CFG_STAT*/
 ldr r0, [r1]
 mov  r1, #0x60  
 and r1, r0, r1   /*r1 = MEM_CFG_STAT & CFG_BOOT_LOC */

 cmp r1, #0x60  /*Internal ROM*/
 beq boot_from_irom
 cmp r1, #0x00  /*Stepping Stone area in NFCON*/
 beq boot_from_nand
 b reset

/*第二阶段从此处开始 rom启动*/
/*此处是跳转到nand_spl\board\samsung\Mini6410\Mmc_boot.c 中的mmc_boot_copy方法*/
boot_from_irom:
/*MINI6410 boot from Internal ROM-->MMC boot*/
#if defined(CONFIG_MINI6410_LED)
/* R/W, Pull-up disable register */
 mov r1, #ELFIN_GPIO_BASE_8BIT
 add r1, r1, #ELFIN_GPK_BASE_8BIT
 ldr r2, =0x11111111
 str r2, [r1, #GPKCON0_OFFSET_8BIT]
 ldr r2, =0x0000AAAA
 str r2, [r1, #GPKPUD_OFFSET_8BIT]
 ldr r2, =0x0000ff7f
 str r2, [r1, #GPKDAT_OFFSET_8BIT]
#endif
 b mmc_boot_copy

/*第二阶段从此处开始 nand启动*/
/*此处是跳转到nand_spl\Nand_boot.c 中的nand_boot方法*/
boot_from_nand:
/*MINI6410 boot from Nand Flash*/
#if defined(CONFIG_MINI6410_LED)
/* R/W, Pull-up disable register */
 mov r1, #ELFIN_GPIO_BASE_8BIT
 add r1, r1, #ELFIN_GPK_BASE_8BIT
 ldr r2, =0x11111111
 str r2, [r1, #GPKCON0_OFFSET_8BIT]
 ldr r2, =0x0000AAAA
 str r2, [r1, #GPKPUD_OFFSET_8BIT]
 ldr r2, =0x0000ffff
 str r2, [r1, #GPKDAT_OFFSET_8BIT]
#endif
 b nand_boot
#else
 ldr r0, _board_init_r_ofs
 adr r1, _start
 add lr, r0, r1
 add     lr, lr, r9
 /* setup parameters for board_init_r */
 mov r0, r5  /* gd_t */
 mov r1, r6  /* dest_addr */
 /* jump to it ... */
 mov pc, lr

_board_init_r_ofs:
 .word board_init_r - _start

_rel_dyn_start_ofs:
 .word __rel_dyn_start - _start
_rel_dyn_end_ofs:
 .word __rel_dyn_end - _start
_dynsym_start_ofs:
 .word __dynsym_start - _start
#endif

#ifdef CONFIG_ENABLE_MMU
_mmu_table_base:
 .word mmu_table
#endif

#ifndef CONFIG_NAND_SPL
/*
 * we assume that cache operation is done before. (eg. cleanup_before_linux())
 * actually, we don't need to do anything about cache if not use d-cache in
 * U-Boot. So, in this function we clean only MMU. by scsuh
 *
 * void theLastJump(void *kernel, int arch_num, uint boot_params);
 */
#ifdef CONFIG_ENABLE_MMU
 .globl theLastJump
theLastJump:
 mov r9, r0
 ldr r3, =0xfff00000
 ldr r4, _TEXT_PHY_BASE
 adr r5, phy_last_jump
 bic r5, r5, r3
 orr r5, r5, r4
 mov pc, r5
phy_last_jump:
 /*
  * disable MMU stuff
  */
 mrc p15, 0, r0, c1, c0, 0
 bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
 bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
 orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
 orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
 mcr p15, 0, r0, c1, c0, 0

 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

 mov r0, #0
 mov pc, r9
#endif

/*以上步骤完成硬件相关的初始化,第一阶段完成*/
/*第二阶段需要完成的工作
 * 从FLASH读出内核
 * 启动内核
 */
/*
 *************************************************************************
 *
 * Interrupt handling
 *
 *************************************************************************
 */
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72

#define S_OLD_R0 68
#define S_PSR  64
#define S_PC  60
#define S_LR  56
#define S_SP  52

#define S_IP  48
#define S_FP  44
#define S_R10  40
#define S_R9  36
#define S_R8  32
#define S_R7  28
#define S_R6  24
#define S_R5  20
#define S_R4  16
#define S_R3  12
#define S_R2  8
#define S_R1  4
#define S_R0  0

#define MODE_SVC 0x13
#define I_BIT  0x80

/*
 * use bad_save_user_regs for abort/prefetch/undef/swi ...
 */

 .macro bad_save_user_regs
 /* carve out a frame on current user stack */
 sub sp, sp, #S_FRAME_SIZE
 /* Save user registers (now in svc mode) r0-r12 */
 stmia sp, {r0 - r12}

 ldr r2, IRQ_STACK_START_IN
 /* get values for "aborted" pc and cpsr (into parm regs) */
 ldmia r2, {r2 - r3}
 /* grab pointer to old stack */
 add r0, sp, #S_FRAME_SIZE

 add r5, sp, #S_SP
 mov r1, lr
 /* save sp_SVC, lr_SVC, pc, cpsr */
 stmia r5, {r0 - r3}
 /* save current stack into r0 (param register) */
 mov r0, sp
 .endm

 .macro get_bad_stack
 ldr r13, IRQ_STACK_START_IN  @ setup our mode stack

 /* save caller lr in position 0 of saved stack */
 str lr, [r13]
 /* get the spsr */
 mrs lr, spsr
 /* save spsr in position 1 of saved stack */
 str lr, [r13, #4]

 /* prepare SVC-Mode */
 mov r13, #MODE_SVC
 @ msr spsr_c, r13
 /* switch modes, make sure moves will execute */
 msr spsr, r13
 /* capture return pc */
 mov lr, pc
 /* jump to next instruction & switch modes. */
 movs pc, lr
 .endm

 .macro get_bad_stack_swi
 /* space on current stack for scratch reg. */
 sub r13, r13, #4
 /* save R0's value. */
 str r0, [r13]
 ldr r13, IRQ_STACK_START_IN  @ setup our mode stack
 /* save caller lr in position 0 of saved stack */
 str lr, [r0]
 /* get the spsr */
 mrs r0, spsr
 /* save spsr in position 1 of saved stack */
 str lr, [r0, #4]
 /* restore r0 */
 ldr r0, [r13]
 /* pop stack entry */
 add r13, r13, #4
 .endm

/*
 * exception handlers
 */
 .align 5
undefined_instruction:
 get_bad_stack
 bad_save_user_regs
 bl do_undefined_instruction

 .align 5
software_interrupt:
 get_bad_stack_swi
 bad_save_user_regs
 bl do_software_interrupt

 .align 5
prefetch_abort:
 get_bad_stack
 bad_save_user_regs
 bl do_prefetch_abort

 .align 5
data_abort:
 get_bad_stack
 bad_save_user_regs
 bl do_data_abort

 .align 5
not_used:
 get_bad_stack
 bad_save_user_regs
 bl do_not_used

 .align 5
irq:
 get_bad_stack
 bad_save_user_regs
 bl do_irq

 .align 5
fiq:
 get_bad_stack
 bad_save_user_regs
 bl do_fiq
#endif /* CONFIG_NAND_SPL */

 


==========================================================================
/board/Samsung/Mini6410/lowlevel_init.S 的代码如下:

/*
 * Memory Setup stuff - taken from blob memsetup.S
 *
 * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw at its.tudelft.nl) and
 *         Jan-Derk Bakker (J.D.Bakker at its.tudelft.nl)
 *
 * Modified for the Samsung SMDK2410 by
 * (C) Copyright 2002
 * David Mueller, ELSOFT AG, <d.mueller at elsoft.ch>
 *
 * (C) Copyright 2008
 * Guennadi Liakhovetki, DENX Software Engineering, <lg at denx.de>
 *
 * (C) Copyright 2010
 * Alex Ling, <kasimling at gmail.com>
 *
 * 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
 */


#include <config.h>
#include <version.h>

#include <asm/arch/s3c6400.h>

#ifdef CONFIG_SERIAL1
#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET)
#elif defined(CONFIG_SERIAL2)
#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET)
#else
#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART2_OFFSET)
#endif

_TEXT_BASE:
 .word CONFIG_SYS_TEXT_BASE

 .globl lowlevel_init
lowlevel_init:
 mov r12, lr

 /*关闭看门狗*/
 /* Disable Watchdog */
 ldr r0, =0x7e000000  @0x7e004000
 orr r0, r0, #0x4000
 mov r1, #0
 str r1, [r0]

 /*关闭所有中断*/
 /* External interrupt pending clear */
 ldr r0, =(ELFIN_GPIO_BASE+EINTPEND_OFFSET) /*EINTPEND*/
 ldr r1, [r0]
 str r1, [r0]

 ldr r0, =ELFIN_VIC0_BASE_ADDR @0x71200000
 ldr r1, =ELFIN_VIC1_BASE_ADDR @0x71300000

 /* Disable all interrupts (VIC0 and VIC1) */
 mvn r3, #0x0
 str r3, [r0, #oINTMSK]
 str r3, [r1, #oINTMSK]

 /* Set all interrupts as IRQ */
 mov r3, #0x0
 str r3, [r0, #oINTMOD]
 str r3, [r1, #oINTMOD]

 /* Pending Interrupt Clear */
 mov r3, #0x0
 str r3, [r0, #oVECTADDR]
 str r3, [r1, #oVECTADDR]
 
 /*初始化系统时钟*/
 /* init system clock */
 bl system_clock_init

#ifndef CONFIG_NAND_SPL
 /* for UART */
 bl uart_asm_init
#endif

#ifdef CONFIG_BOOT_NAND
 /* simple init for NAND */
 bl nand_asm_init
#endif

 /* Memory subsystem address 0x7e00f120 */
 ldr r0, =ELFIN_MEM_SYS_CFG

 /* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */
 mov r1, #S3C64XX_MEM_SYS_CFG_NAND
 str r1, [r0]
#ifdef CONFIG_NAND_SPL
 bl mem_ctrl_asm_init
#endif
/* Wakeup support. Don't know if it's going to be used, untested. */
 ldr r0, =(ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET)
 ldr r1, [r0]
 bic r1, r1, #0xfffffff7
 cmp r1, #0x8
 beq wakeup_reset

1:
 mov lr, r12
 mov pc, lr

wakeup_reset:

 /* Clear wakeup status register */
 ldr r0, =(ELFIN_CLOCK_POWER_BASE + WAKEUP_STAT_OFFSET)
 ldr r1, [r0]
 str r1, [r0]

 /* Load return address and jump to kernel */
 ldr r0, =(ELFIN_CLOCK_POWER_BASE + INF_REG0_OFFSET)
 /* r1 = physical address of s3c6400_cpu_resume function */
 ldr r1, [r0]
 /* Jump to kernel (sleep-s3c6400.S) */
 mov pc, r1
 nop
 nop
/* 初始化系统时钟
 * system_clock_init: Initialize core clock and bus clock.
 * void system_clock_init(void)
 */
system_clock_init:
 ldr r0, =ELFIN_CLOCK_POWER_BASE /* 0x7e00f000 */

#ifdef CONFIG_SYNC_MODE
 ldr r1, [r0, #OTHERS_OFFSET]
 mov r2, #0x40
 orr r1, r1, r2
 str r1, [r0, #OTHERS_OFFSET]

 nop
 nop
 nop
 nop
 nop

 ldr r2, =0x80
 orr r1, r1, r2
 str r1, [r0, #OTHERS_OFFSET]

check_syncack:
 ldr r1, [r0, #OTHERS_OFFSET]
 ldr r2, =0xf00
 and r1, r1, r2
 cmp r1, #0xf00
 bne check_syncack
#else /* ASYNC Mode */
 nop
 nop
 nop
 nop
 nop

 /*
  * This was unconditional in original Samsung sources, but it doesn't
  * seem to make much sense on S3C6400.
  */
#if !defined(CONFIG_S3C6400) && !defined(CONFIG_S3C6410)
 ldr r1, [r0, #OTHERS_OFFSET]
 bic r1, r1, #0xC0
 orr r1, r1, #0x40
 str r1, [r0, #OTHERS_OFFSET]

wait_for_async:
 ldr r1, [r0, #OTHERS_OFFSET]
 and r1, r1, #0xf00
 cmp r1, #0x0
 bne wait_for_async
#endif

 ldr r1, [r0, #OTHERS_OFFSET]
 bic r1, r1, #0x40
 str r1, [r0, #OTHERS_OFFSET]
#endif

 mov r1, #0xff00
 orr r1, r1, #0xff
 str r1, [r0, #APLL_LOCK_OFFSET]
 str r1, [r0, #MPLL_LOCK_OFFSET]

 /* Set Clock Divider */
 ldr r1, [r0, #CLK_DIV0_OFFSET]
 bic r1, r1, #0x30000
 bic r1, r1, #0xff00
 bic r1, r1, #0xff
 ldr r2, =CLK_DIV_VAL
 orr r1, r1, r2
 str r1, [r0, #CLK_DIV0_OFFSET]

 ldr r1, =APLL_VAL
 str r1, [r0, #APLL_CON_OFFSET]
 ldr r1, =MPLL_VAL
 str r1, [r0, #MPLL_CON_OFFSET]

 /* FOUT of EPLL is 96MHz */
/*
 ldr r1, =0x200203
 str r1, [r0, #EPLL_CON0_OFFSET]
*/
 ldr r1, =0x0
 str r1, [r0, #EPLL_CON1_OFFSET]

 ldr r1, =0x80200103   /* FOUT of EPLL is 48MHz , enable it for MMC*/
 str r1, [r0, #EPLL_CON0_OFFSET]

 /* APLL, MPLL, EPLL select to Fout */
 ldr r1, [r0, #CLK_SRC_OFFSET]
 orr r1, r1, #0x7
 str r1, [r0, #CLK_SRC_OFFSET]

 /* wait at least 200us to stablize all clock */
 mov r1, #0x10000
1: subs r1, r1, #1
 bne 1b

 /* Synchronization for VIC port */
#if defined(CONFIG_SYNC_MODE)
 ldr r1, [r0, #OTHERS_OFFSET]
 orr r1, r1, #0x20
 str r1, [r0, #OTHERS_OFFSET]
#elif !defined(CONFIG_S3C6400) && !defined(CONFIG_S3C6410)
 /* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */
 ldr r1, [r0, #OTHERS_OFFSET]
 bic r1, r1, #0x20
 str r1, [r0, #OTHERS_OFFSET]
#endif
 mov pc, lr


#ifndef CONFIG_NAND_SPL
/*
 * uart_asm_init: Initialize UART's pins
 */
uart_asm_init:
 /* set GPIO to enable UART */
 ldr r0, =ELFIN_GPIO_BASE
 ldr r1, =0x220022
 str r1, [r0, #GPACON_OFFSET]
 mov pc, lr
#endif

#ifdef CONFIG_BOOT_NAND
/*
 * NAND Interface init for SMDK6400
 */
nand_asm_init:
 ldr r0, =ELFIN_NAND_BASE
 ldr r1, [r0, #NFCONF_OFFSET]
 orr r1, r1, #0x70
 orr r1, r1, #0x7700
 str r1, [r0, #NFCONF_OFFSET]

 ldr r1, [r0, #NFCONT_OFFSET]
 orr r1, r1, #0x07
 str r1, [r0, #NFCONT_OFFSET]

 mov pc, lr
#endif

#ifdef CONFIG_ENABLE_MMU
/* 初始化内存
 * MMU Table for MINI6410
 */

 /* form a first-level section entry */
.macro FL_SECTION_ENTRY base,ap,d,c,b
 .word (\base << 20) | (\ap << 10) | \
       (\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm

.section .mmudata, "a"
 .align 14
 /* the following alignment creates the mmu table at address 0x4000. */
 .globl mmu_table
mmu_table:
 .set __base, 0
 /* 1:1 mapping for debugging */
 .rept 0xA00
 FL_SECTION_ENTRY __base, 3, 0, 0, 0
 .set __base, __base + 1
 .endr

 /* access is not allowed. */
 .rept 0xC00 - 0xA00
 .word 0x00000000
 .endr

 /* 128MB for SDRAM 0xC0000000 -> 0x50000000 */
 .set __base, 0x500
 .rept 0xC80 - 0xC00
 FL_SECTION_ENTRY __base, 3, 0, 1, 1
 .set __base, __base + 1
 .endr

 /* access is not allowed. */
 .rept 0x1000 - 0xc80
 .word 0x00000000
 .endr
#endif

你可能感兴趣的:(uboot分析第一阶段学习笔记)