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) 2007Samsung 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_BASECONFIG_SYS_UBOOT_BASE
#endif

#if defined(CONFIG_MINI6410_LED)
#define ELFIN_GPIO_BASE_8BIT0x7f000000
#define ELFIN_GPK_BASE_8BIT0x8800
#define GPKCON0_OFFSET_8BIT0x00
#define GPKCON1_OFFSET_8BIT0x04
#define GPKDAT_OFFSET_8BIT0x08
#define GPKPUD_OFFSET_8BIT0x0C
#endif
/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/

.globl _start
_start: breset
#ifndef CONFIG_NAND_SPL
ldrpc, _undefined_instruction
ldrpc, _software_interrupt
ldrpc, _prefetch_abort
ldrpc, _data_abort
ldrpc, _not_used
ldrpc, _irq
ldrpc, _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:
.wordCONFIG_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:
.wordCONFIG_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:
.word0x0badc0de

/*
* the actual reset code
*/

reset:
/* 1 cpu设为管理模式
* set the cpu to SVC32 mode
*/
//将状态寄存器的内容读到通用寄存器
mrsr0, cpsr
//清除位指令
bicr0, r0, #0x3f
//修改r0低八位
orrr0, r0, #0xd3
//将通用寄存器读到状态寄存器
msrcpsr, 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
*/
movr0, #0
mcrp15, 0, r0, c7, c7, 0/* flush v3/v4 cache */
mcrp15, 0, r0, c8, c7, 0/* flush v4 TLB */

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

/* Prepare to disable the MMU */
adrr2, mmu_disable_phys
subr2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
bmmu_disable

.align 5
/* Run in a single cache-line */
mmu_disable:
mcrp15, 0, r0, c1, c0, 0
nop
nop
movpc, r2
mmu_disable_phys:

#ifdef CONFIG_DISABLE_TCM
/*
* Disable the TCMs
*/
mrcp15, 0, r0, c0, c0, 2/* Return TCM details */
cmpr0, #0
beqskip_tcmdisable
movr1, #0
movr2, #1
tstr0, r2
mcrnep15, 0, r1, c9, c1, 1/* Disable Instruction TCM if present*/
tstr0, r2, LSL #16
mcrnep15, 0, r1, c9, c1, 0/* Disable Data TCM if present*/
skip_tcmdisable:
#endif
#endif

#ifdef CONFIG_PERIPORT_REMAP
/* Peri port setup */
ldrr0, =CONFIG_PERIPORT_BASE
orrr0, r0, #CONFIG_PERIPORT_SIZE
mcrp15,0,r0,c15,c2,4
#endif

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

/* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:
ldrsp, =(CONFIG_SYS_INIT_SP_ADDR)
bicsp, sp, #7 /* 8-byte alignment for ABI compliance */
#ifndef CONFIG_NAND_SPL
ldrr0,=0x00000000
blboard_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.
*
*/
.globlrelocate_code
relocate_code:
movr4, r0/* save addr_sp */
movr5, r1/* save addr of gd */
movr6, r2/* save addr of destination */
ldrr9, =0x00000000
/*3设置栈*/
/* Set up the stack */
stack_setup:
movsp, r4

adrr0, _start
cmpr0, r6
beqfixsym/* skip relocation */
#if defined(CONFIG_MINI6410_LED)
/* 4 将代码从flash复制到sdram中*/
/* if relocate the u-boot code, LED2 will on.*/
movr1, #ELFIN_GPIO_BASE_8BIT
addr1, r1, #ELFIN_GPK_BASE_8BIT
/*SPL will do it!
ldrr2, =0x11111111
strr2, [r1, #GPKCON0_OFFSET_8BIT]
ldrr2, =0x0000AAAA
strr2, [r1, #GPKPUD_OFFSET_8BIT]
*/
ldrr2, [r1, #GPKDAT_OFFSET_8BIT]
andr2, r2, #0xffffffbf
strr2, [r1, #GPKDAT_OFFSET_8BIT]
#endif
movr1, r6/* r1 <- scratch for copy_loop */
/*ldrr2, _TEXT_BASE*/
ldrr3, _bss_start_ofs
addr2, r0, r3/* r2 <- source end address */


copy_loop:
ldmiar0!, {r9-r10}/* copy from source address [r0] */
stmiar1!, {r9-r10}/* copy to target address [r1] */
cmpr0, r2/* until source end address [r2] */
blocopy_loop

#ifndef CONFIG_PRELOADER
/*
* fix .rel.dyn relocations
*/
fixsym:
ldrr0, _TEXT_BASE/* r0 <- Text base */
subr9, r6, r0/* r9 <- relocation offset */
ldrr10, _dynsym_start_ofs/* r10 <- sym table ofs */
addr10, r10, r0/* r10 <- sym table in FLASH */
ldrr2, _rel_dyn_start_ofs/* r2 <- rel dyn start ofs */
addr2, r2, r0/* r2 <- rel dyn start in FLASH */
ldrr3, _rel_dyn_end_ofs/* r3 <- rel dyn end ofs */
addr3, r3, r0/* r3 <- rel dyn end in FLASH */
fixloop:
ldrr0, [r2]/* r0 <- location to fix up, IN FLASH! */
addr0, r0, r9/* r0 <- location to fix up in RAM */
ldrr1, [r2, #4]
andr7, r1, #0xff
cmpr7, #23/* relative fixup? */
beqfixrel
cmpr7, #2/* absolute fixup? */
beqfixabs
/* ignore unknown type of fixup */
bfixnext
fixabs:
/* absolute fix: set location to (offset) symbol value */
movr1, r1, LSR #4/* r1 <- symbol index in .dynsym */
addr1, r10, r1/* r1 <- address of symbol in table */
ldrr1, [r1, #4]/* r1 <- symbol value */
addr1, r1, r9/* r1 <- relocated sym addr */
bfixnext
fixrel:
/* relative fix: increase location by offset */
ldrr1, [r0]
addr1, r1, r9
fixnext:
strr1, [r0]
addr2, r2, #8/* each rel.dyn entry is 8 bytes */
cmpr2, r3
blofixloop
#endif
#endif

#ifdef CONFIG_ENABLE_MMU
enable_mmu:
/* enable domain access */
ldrr5, =0x0000ffff
mcrp15, 0, r5, c3, c0, 0/* load domain access register */

/* Set the TTB register */
ldrr0, _mmu_table_base
ldrr1, =CONFIG_SYS_PHY_UBOOT_BASE
ldrr2, =0xfff00000
bicr0, r0, r2
orrr1, r0, r1
mcrp15, 0, r1, c2, c0, 0

/* Enable the MMU */
mrcp15, 0, r0, c1, c0, 0
orrr0, r0, #1/* Set CR_M to enable MMU */

/* Prepare to enable the MMU */
adrr1, skip_hw_init
andr1, r1, #0x3fc
ldrr2, _TEXT_BASE
ldrr3, =0xfff00000
andr2, r2, r3
orrr2, r2, r1
bmmu_enable

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

mcrp15, 0, r0, c1, c0, 0
nop
nop
movpc, r2
skip_hw_init:
#endif

/*5 清bss段,即初始值为0的静态变量或是全局变量,全部初始值为0,所以清空该段*/
clear_bss:
#ifndef CONFIG_PRELOADER
ldrr0, _bss_start_ofs
ldrr1, _bss_end_ofs
/* ldrr3, _TEXT_BASE*//* Text base */
movr4, r6/* reloc addr */
addr0, r0, r4
addr1, r1, r4
movr2, #0x00000000/* clear */

clbss_l:strr2, [r0]/* clear loop... */
addr0, r0, #4
cmpr0, r1
bneclbss_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

ldrr1, =MEM_CFG_STAT/* address of reg MEM_CFG_STAT*/
ldrr0, [r1]
mov r1, #0x60
andr1, r0, r1/*r1 = MEM_CFG_STAT & CFG_BOOT_LOC */

cmpr1, #0x60/*Internal ROM*/
beqboot_from_irom
cmpr1, #0x00/*Stepping Stone area in NFCON*/
beqboot_from_nand
breset

/*第二阶段从此处开始 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 */
movr1, #ELFIN_GPIO_BASE_8BIT
addr1, r1, #ELFIN_GPK_BASE_8BIT
ldrr2, =0x11111111
strr2, [r1, #GPKCON0_OFFSET_8BIT]
ldrr2, =0x0000AAAA
strr2, [r1, #GPKPUD_OFFSET_8BIT]
ldrr2, =0x0000ff7f
strr2, [r1, #GPKDAT_OFFSET_8BIT]
#endif
bmmc_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 */
movr1, #ELFIN_GPIO_BASE_8BIT
addr1, r1, #ELFIN_GPK_BASE_8BIT
ldrr2, =0x11111111
strr2, [r1, #GPKCON0_OFFSET_8BIT]
ldrr2, =0x0000AAAA
strr2, [r1, #GPKPUD_OFFSET_8BIT]
ldrr2, =0x0000ffff
strr2, [r1, #GPKDAT_OFFSET_8BIT]
#endif
bnand_boot
#else
ldrr0, _board_init_r_ofs
adrr1, _start
addlr, r0, r1
add lr, lr, r9
/* setup parameters for board_init_r */
movr0, r5/* gd_t */
movr1, r6/* dest_addr */
/* jump to it ... */
movpc, 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
*
* voidtheLastJump(void *kernel, int arch_num, uint boot_params);
*/
#ifdef CONFIG_ENABLE_MMU
.globl theLastJump
theLastJump:
movr9, r0
ldrr3, =0xfff00000
ldrr4, _TEXT_PHY_BASE
adrr5, phy_last_jump
bicr5, r5, r3
orrr5, r5, r4
movpc, r5
phy_last_jump:
/*
* disable MMU stuff
*/
mrcp15, 0, r0, c1, c0, 0
bicr0, r0, #0x00002300/* clear bits 13, 9:8 (--V- --RS) */
bicr0, r0, #0x00000087/* clear bits 7, 2:0 (B--- -CAM) */
orrr0, r0, #0x00000002/* set bit 2 (A) Align */
orrr0, r0, #0x00001000/* set bit 12 (I) I-Cache */
mcrp15, 0, r0, c1, c0, 0

mcrp15, 0, r0, c8, c7, 0/* flush v4 TLB */

movr0, #0
movpc, r9
#endif

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

#define S_OLD_R068
#define S_PSR64
#define S_PC60
#define S_LR56
#define S_SP52

#define S_IP48
#define S_FP44
#define S_R1040
#define S_R936
#define S_R832
#define S_R728
#define S_R624
#define S_R520
#define S_R416
#define S_R312
#define S_R28
#define S_R14
#define S_R00

#define MODE_SVC 0x13
#define I_BIT 0x80

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

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

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

addr5, sp, #S_SP
movr1, lr
/* save sp_SVC, lr_SVC, pc, cpsr */
stmiar5, {r0 - r3}
/* save current stack into r0 (param register) */
movr0, sp
.endm

.macro get_bad_stack
ldrr13, IRQ_STACK_START_IN@ setup our mode stack

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

/* prepare SVC-Mode */
movr13, #MODE_SVC
@ msrspsr_c, r13
/* switch modes, make sure moves will execute */
msrspsr, r13
/* capture return pc */
movlr, pc
/* jump to next instruction & switch modes. */
movspc, lr
.endm

.macro get_bad_stack_swi
/* space on current stack for scratch reg. */
subr13, r13, #4
/* save R0's value. */
strr0, [r13]
ldrr13, IRQ_STACK_START_IN@ setup our mode stack
/* save caller lr in position 0 of saved stack */
strlr, [r0]
/* get the spsr */
mrsr0, spsr
/* save spsr in position 1 of saved stack */
strlr, [r0, #4]
/* restore r0 */
ldrr0, [r13]
/* pop stack entry */
addr13, r13, #4
.endm

/*
* exception handlers
*/
.align5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bldo_undefined_instruction

.align5
software_interrupt:
get_bad_stack_swi
bad_save_user_regs
bldo_software_interrupt

.align5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bldo_prefetch_abort

.align5
data_abort:
get_bad_stack
bad_save_user_regs
bldo_data_abort

.align5
not_used:
get_bad_stack
bad_save_user_regs
bldo_not_used

.align5
irq:
get_bad_stack
bad_save_user_regs
bldo_irq

.align5
fiq:
get_bad_stack
bad_save_user_regs
bldo_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:
.wordCONFIG_SYS_TEXT_BASE

.globl lowlevel_init
lowlevel_init:
movr12, lr

/*关闭看门狗*/
/* Disable Watchdog */
ldrr0, =0x7e000000@0x7e004000
orrr0, r0, #0x4000
movr1, #0
strr1, [r0]

/*关闭所有中断*/
/* External interrupt pending clear */
ldrr0, =(ELFIN_GPIO_BASE+EINTPEND_OFFSET)/*EINTPEND*/
ldrr1, [r0]
strr1, [r0]

ldrr0, =ELFIN_VIC0_BASE_ADDR@0x71200000
ldrr1, =ELFIN_VIC1_BASE_ADDR@0x71300000

/* Disable all interrupts (VIC0 and VIC1) */
mvnr3, #0x0
strr3, [r0, #oINTMSK]
strr3, [r1, #oINTMSK]

/* Set all interrupts as IRQ */
movr3, #0x0
strr3, [r0, #oINTMOD]
strr3, [r1, #oINTMOD]

/* Pending Interrupt Clear */
movr3, #0x0
strr3, [r0, #oVECTADDR]
strr3, [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 */
ldrr0, =ELFIN_MEM_SYS_CFG

/* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */
movr1, #S3C64XX_MEM_SYS_CFG_NAND
strr1, [r0]
#ifdef CONFIG_NAND_SPL
blmem_ctrl_asm_init
#endif
/* Wakeup support. Don't know if it's going to be used, untested. */
ldrr0, =(ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET)
ldrr1, [r0]
bicr1, r1, #0xfffffff7
cmpr1, #0x8
beqwakeup_reset

1:
movlr, r12
movpc, lr

wakeup_reset:

/* Clear wakeup status register */
ldrr0, =(ELFIN_CLOCK_POWER_BASE + WAKEUP_STAT_OFFSET)
ldrr1, [r0]
strr1, [r0]

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

#ifdef CONFIG_SYNC_MODE
ldrr1, [r0, #OTHERS_OFFSET]
movr2, #0x40
orrr1, r1, r2
strr1, [r0, #OTHERS_OFFSET]

nop
nop
nop
nop
nop

ldrr2, =0x80
orrr1, r1, r2
strr1, [r0, #OTHERS_OFFSET]

check_syncack:
ldrr1, [r0, #OTHERS_OFFSET]
ldrr2, =0xf00
andr1, r1, r2
cmpr1, #0xf00
bnecheck_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)
ldrr1, [r0, #OTHERS_OFFSET]
bicr1, r1, #0xC0
orrr1, r1, #0x40
strr1, [r0, #OTHERS_OFFSET]

wait_for_async:
ldrr1, [r0, #OTHERS_OFFSET]
andr1, r1, #0xf00
cmpr1, #0x0
bnewait_for_async
#endif

ldrr1, [r0, #OTHERS_OFFSET]
bicr1, r1, #0x40
strr1, [r0, #OTHERS_OFFSET]
#endif

movr1, #0xff00
orrr1, r1, #0xff
strr1, [r0, #APLL_LOCK_OFFSET]
strr1, [r0, #MPLL_LOCK_OFFSET]

/* Set Clock Divider */
ldrr1, [r0, #CLK_DIV0_OFFSET]
bicr1, r1, #0x30000
bicr1, r1, #0xff00
bicr1, r1, #0xff
ldrr2, =CLK_DIV_VAL
orrr1, r1, r2
strr1, [r0, #CLK_DIV0_OFFSET]

ldrr1, =APLL_VAL
strr1, [r0, #APLL_CON_OFFSET]
ldrr1, =MPLL_VAL
strr1, [r0, #MPLL_CON_OFFSET]

/* FOUT of EPLL is 96MHz */
/*
ldrr1, =0x200203
strr1, [r0, #EPLL_CON0_OFFSET]
*/
ldrr1, =0x0
strr1, [r0, #EPLL_CON1_OFFSET]

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

/* APLL, MPLL, EPLL select to Fout */
ldrr1, [r0, #CLK_SRC_OFFSET]
orrr1, r1, #0x7
strr1, [r0, #CLK_SRC_OFFSET]

/* wait at least 200us to stablize all clock */
movr1, #0x10000
1:subsr1, r1, #1
bne1b

/* Synchronization for VIC port */
#if defined(CONFIG_SYNC_MODE)
ldrr1, [r0, #OTHERS_OFFSET]
orrr1, r1, #0x20
strr1, [r0, #OTHERS_OFFSET]
#elif !defined(CONFIG_S3C6400) && !defined(CONFIG_S3C6410)
/* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */
ldrr1, [r0, #OTHERS_OFFSET]
bicr1, r1, #0x20
strr1, [r0, #OTHERS_OFFSET]
#endif
movpc, lr


#ifndef CONFIG_NAND_SPL
/*
* uart_asm_init: Initialize UART's pins
*/
uart_asm_init:
/* set GPIO to enable UART */
ldrr0, =ELFIN_GPIO_BASE
ldrr1, =0x220022
strr1, [r0, #GPACON_OFFSET]
movpc, lr
#endif

#ifdef CONFIG_BOOT_NAND
/*
* NAND Interface init for SMDK6400
*/
nand_asm_init:
ldrr0, =ELFIN_NAND_BASE
ldrr1, [r0, #NFCONF_OFFSET]
orrr1, r1, #0x70
orrr1, r1, #0x7700
strr1, [r0, #NFCONF_OFFSET]

ldrr1, [r0, #NFCONT_OFFSET]
orrr1, r1, #0x07
strr1, [r0, #NFCONT_OFFSET]

movpc, 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

你可能感兴趣的:(学习笔记)