三星uboot1.1.6源码分析——start.s(1)

来源:互联网 发布:linux查看登录用户清单 编辑:程序博客网 时间:2024/05/18 00:18

虽然,分析start.s的文件在网上已经很多,但还是在这里对自己的分析做个记录,方便以后查看。

现在开始:

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

#include <regs.h>


#ifndef CONFIG_ENABLE_MMU   我们定义了#define CONFIG_ENABLE_MMU,所以这些用不到
#ifndef CFG_PHY_UBOOT_BASE
#define CFG_PHY_UBOOT_BASE CFG_UBOOT_BASE
#endif
#endif
上面这些宏的定义都在Smdk6410.h (include\configs)文件中,如下所示:

/* base address for uboot */
#ifdef CONFIG_ENABLE_MMU
#define CFG_UBOOT_BASE 0xc7e00000
#else
#define CFG_UBOOT_BASE 0x57e00000
#endif
#define CFG_PHY_UBOOT_BASE MEMORY_BASE_ADDRESS + 0x7e00000

#define MEMORY_BASE_ADDRESS0x50000000

所以上面的CFG_PHY_UBOOT_BASE为0x57e00000

          CFG_UBOOT_BASE为0xc7e00000


/*
 *************************************************************************
 *
 * Jump vector table as in table 3.1 in [1]
 *
 *************************************************************************
 */
.globl _start           在链接文件有如下内容:

---------------------------------------------------------------

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;


. = ALIGN(4);
.text      :
{
  cpu/s3c64xx/start.o(.text)

---------------------------------------------------------------
_start: b reset
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 */
.global _end_vect
_end_vect:


.balignl 16,0xdeadbeef
/*

--------------------------------------------------------------------------------------------------------------

上面这些就都不说了,网上有很多这上面的资料,讲的都很详细,忘记了再查。不过这些undefined_instruction、data_abort等在本文件的后面都有定义,我在前面把他们粘贴在下面,方便查看,如下所示:

/*
 * 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


#ifdef CONFIG_USE_IRQ  我们没有定义:#undef CONFIG_USE_IRQ/* we don't need IRQ/FIQ stuff */


.align  5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs


.align  5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs


#else  我们使用这一部分


.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

--------------------------------------------------------------------------------

1、其中get_bad_stack也在同一个文件中,如下所示:

.macro get_bad_stack
ldrr13, _armboot_start@ setup our mode stack (enter in banked mode)

其中有如下定义:

.globl _armboot_start
_armboot_start:
.word _start
subr13, r13, #(CFG_MALLOC_LEN)@ move past malloc pool
subr13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack


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


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

这个宏的功能应该是得到对应异常的堆栈指针。

2、其中bad_save_user_regs也在同一个文件中,如下所示:

/*
 * use bad_save_user_regs for abort/prefetch/undef/swi ...
 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
 */

下面这一段汇编代码还是很好理解的,最困难的可能就是stmia和ldmia这两个指令了,不过我在另外一篇我转载的博客中有很好的从实例中分析了这两个指令的用法。一看就能明了。

.macro  bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE@ carve out a frame on current user stack

其中有定义:#define S_FRAME_SIZE72
stmia sp, {r0 - r12}@ Save user registers (now in svc mode) r0-r12


ldr r2, _armboot_start
sub r2, r2, #(CFG_MALLOC_LEN)
sub r2, r2, #(CFG_GBL_DATA_SIZE+8)@ set base 2 words into abort stack
ldmia r2, {r2 - r3}@ get values for "aborted" pc and cpsr (into parm regs)
add r0, sp, #S_FRAME_SIZE@ grab pointer to old stack


add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r3}@ save sp_SVC, lr_SVC, pc, cpsr
mov r0, sp@ save current stack into r0 (param register)
.endm
其实这个宏的主要作用就是保存下面这些寄存器的内容,如下所示:

#define S_OLD_R068
#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


.macro  irq_save_user_regs  和上面的作用差不多
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12}@ Calling r0-r12
add r8, sp, #S_PC@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
stmdb r8, {sp, lr}^@ Calling SP, LR
str lr, [r8, #0]@ Save calling PC
mrs r6, spsr
str r6, [r8, #4]@ Save CPSR
str r0, [r8, #8]@ Save OLD_R0
mov r0, sp
.endm

3、

再来说说do_software_interrupt、do_data_abort等等类似与这些又在那里定义的呢?

它们都定义在:Interrupts.c (cpu\s3c64xx)文件中,如下所示:

void do_undefined_instruction(struct pt_regs *pt_regs)
{
printf("undefined instruction\n");
show_regs(pt_regs);
bad_mode();
}


void do_software_interrupt(struct pt_regs *pt_regs)
{
printf("software interrupt\n");
show_regs(pt_regs);
bad_mode();
}


void do_prefetch_abort(struct pt_regs *pt_regs)
{
printf("prefetch abort\n");
show_regs(pt_regs);
bad_mode();
}


void do_data_abort(struct pt_regs *pt_regs)
{
printf("data abort\n");
show_regs(pt_regs);
bad_mode();
}


void do_not_used(struct pt_regs *pt_regs)
{
printf("not used\n");
show_regs(pt_regs);
bad_mode();
}


void do_fiq(struct pt_regs *pt_regs)
{
printf("fast interrupt request\n");
show_regs(pt_regs);
bad_mode();
}


void do_irq(struct pt_regs *pt_regs)
{
printf("interrupt request\n");
show_regs(pt_regs);
bad_mode();
}

-------------------------------------------

其中又有

void bad_mode(void)
{
panic("Resetting CPU ...\n");
reset_cpu(0);
}

/* * reset the cpu by setting up the watchdog timer and let him time out */
void reset_cpu(ulong ignored)
{
printf("reset... \n\n\n");


#if defined(CONFIG_S3C6400)
SW_RST_REG = 0x6400;
#elif defined(CONFIG_S3C6410)
SW_RST_REG = 0x6410;
#elif defined(CONFIG_S3C6430)
SW_RST_REG = 0x6410;
#endif


/* loop forever and wait for reset to happen */
while (1)
{
if (serial_tstc())
{
serial_getc();
break;
}
}
/*NOTREACHED*/
}

---------------------------------------------------------------

好了这篇就说到这里了,下篇继续。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 ps没有魔棒工具怎么办 洗完鞋子发黄了怎么办 牛拜单车不退押金怎么办 总裁太爱我怎么办小说 小班走丢了怎么办ppt 走丢了怎么办 教案 ppt 小鸽子一大一小怎么办 烤八寸蛋糕胚表面上色严重怎么办 小班安全教案下雨打雷怎么办 幼儿园小班社会教案下雨打雷怎么办 两个月宝宝吃手怎么办 胳膊上长了个猴子怎么办 刚刚出壳的小鸡怎么办 南宁电动车牌被偷了怎么办 南宁电车车牌被偷了怎么办 电车车牌被偷了怎么办 上海电动车车牌被偷了怎么办 太子摩托车离合回的慢怎么办 指甲小月牙太少怎么办 牛仔裤用84泡了怎么办 蓝色的衣服晒红怎么办 厨房用的剪刀开合很紧怎么办 理发的剪刀钝了怎么办 小孩眼睛肿了怎么办才能消肿 柿子和螃蟹后要怎么办 柿子和螃蟹吃了怎么办 吃了没熟的虾怎么办 邻居小孩怕我家小狗怎么办 心里有一道坎过不去了怎么办 刚买的小狗怕人怎么办 一年级孩子字写不好怎么办 小狗三天没吃了怎么办 捡到一只流浪猫怎么办 仓鼠四肢红肿圈状怎么办 泰迪的鼻子干燥怎么办 小狗眼睛有白色浓稠物怎么办 流浪狗生了小狗怎么办 学生字写得很差怎么办 猫身上粘老鼠胶怎么办 抄东西抄的手疼怎么办 皮质物品被油性笔划了怎么办