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 <wd@denx.de>
#
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, <lg@denx.de>
*
* 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 (jsgood.yang@samsung.com)
* 2007-09-21 - Added MoviNAND and OneNAND boot codes by
* jsgood (jsgood.yang@samsung.com)
* 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
uboot分析第一阶段学习笔记相关推荐
- 嵌入式之uboot源码分析-启动第一阶段学习笔记
注: 以下的内容来自朱老师物联网大讲堂uboot部分课件 Uboot启动第一阶段start.S执行步骤 1.头文件包含 <config.h>(x210的各种宏定义) <version ...
- 大数据第一阶段学习笔记
开始:2022年11月6日 以下内容仅为个人笔记整理.(第一阶段的内容并不完全.硬件上有点问题,暂时无法解决,空着的部分后续补上.) 第0章 大数据介绍 大数据可以从事的职位有: 大数据工程师 数据分 ...
- 20135320赵瀚青LINUX内核分析第一周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.概述 第一周的学习内容主 ...
- linux第一阶段学习笔记基础
linux学习 day01 1.计算机基础 运维人员的职责: 7*24是服务器稳定运行 数据不能丢失损坏 提升用户体验 常见的服务器种类 DELL DELL 1U 2U 2010 1850/1950 ...
- Linux内核分析——第一周学习笔记
20135313吴子怡.北京电子科技学院 chapter 1 知识点梳理 第一节 存储程序计算机工作模型 1.冯诺依曼体系结构:即具有存储程序的计算机体系结构.目前大多数拥有计算和存储功能的设备(智能 ...
- 嵌入式之uboot源码分析-启动第二阶段学习笔记(下篇)
接上部分---->嵌入式之uboot源码分析-启动第二阶段学习笔记(上篇) 注:如下内容来自朱老师物联网大讲堂uboot课件 3.2.14 CFG_NO_FLASH (1)虽然NandFlash ...
- uboot学习之三-----uboot启动第一阶段--start.S之一
uboot分为两个阶段:start.S是uboot的第一阶段. 一:引入start.S u-boot.s找到start.S的入口 ①首先在C语言中整个项目的入口就是main函数(这是C语言规定的),所 ...
- U-Boot 启动过程和源码分析(第一阶段)
参考:http://blog.csdn.net/hare_lee/article/details/6916325 ******************************************* ...
- 机电传动控制课程第一周学习笔记
机电传动课程第一周学习笔记 本周的学习内容主要是第一章绪论和第二章机电传动系统的动力学基础,结合课程学习和预习复习回顾内容如下: 1.绪论:学习了机电传动控制目的与任务.发展历程和我们该如何学习这门课 ...
最新文章
- ubuntu php session 删除,session_unset()和session_destroy()用法分析
- python网站开发linux_使用Python编写Linux系统守护进程实例
- 关于数据库的备份和某个表的数据备份的相关步骤介绍
- linux ls的所有参数,Linux ls命令参数详解
- 在数据采集器中用TensorFlow进行实时机器学习
- Hive报错:Exception in thread main java.lang.Incom。。。。 Class com.google.common.collect.ImmutableSotil
- 在多任务(RTOS)环境中使用看门狗
- C# Socket编程 通过线程方式的异步
- 拓端tecdat|R语言使用自组织映射神经网络(SOM)进行客户细分
- win10电脑显示无法自动修复此计算机,win10系统无法自动修复此计算机的操作步骤...
- python爬取五百丁ppt模板(有图+有代码)
- 苹果安装app的另一种方式(通过itms-services协议,不通过AppStore,直接安装IOS应用程序)
- java openoffic linux_Linux操作系统下安装Openoffice3.2
- 金星DEM数据介绍与下载教程
- 【iOS】调起地图进行导航(系统地图、高德、百度)
- 阿里云OSS图片文件和html文件无法直接打开,只能下载
- EasyPoi word导出教程
- uni-app 今天也要努力写项目NO.1
- 获奖团队访谈录|“AI+无线通信”赛道三等奖团队
- 基于OpenGL的地形建模技术的研究与实现
热门文章
- 企业网上下单订货管理软件源码搭建功能介绍|移讯云订货通订单管理系统
- 前端培训丁鹿学堂:vue3之计算数据和watch监听深入
- 【ArcGIS微课1000例】0039:ArcGIS注记转CAD注记的方法
- 阿里云服务(四)—云数据库RDS
- 2020李宏毅学习笔记——8. Convolution Netural Network
- 计算机图像处理要学什么软件有哪些,电脑中常用的图像处理软件有哪些
- 控制面板快捷键win10_Win10系统启动变慢怎么办,Win10系统启动变慢解决方法
- 本地搭建乌云漏洞平台
- xilinx apu ,rpu特点 及通信
- EduCoder-Web程序设计基础-html5—表格高级样式的设置-第2关:设置表格的外边框样式