虽然,分析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*/
}

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

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

三星uboot1.1.6源码分析——start.s(1)相关推荐

  1. 三星uboot1.1.6源码分析——start.s(4)——从NAND复制源码到RAM(3)

    通过上两篇博客终于把从NAND复制源码到RAM的c语言写的部分说完了,现在回到start.s中,接着分析余下的代码. ----------------------------------------- ...

  2. 三星U-Boot-1.1.6源码分析lowlevel_init.S (board\samsung\smdk6410)

    http://www.linuxidc.com/Linux/2012-06/62898.htm 最近在看uboot的源码,做些笔记. lowlevel_init.S (board\samsung\sm ...

  3. 嵌入式之uboot源码分析-启动第二阶段学习笔记(下篇)

    接上部分---->嵌入式之uboot源码分析-启动第二阶段学习笔记(上篇) 注:如下内容来自朱老师物联网大讲堂uboot课件 3.2.14 CFG_NO_FLASH (1)虽然NandFlash ...

  4. uCOS2源码分析1-BSP部分-第4季第2部分视频课程-朱有鹏-专题视频课程

    uCOS2源码分析1-BSP部分-第4季第2部分视频课程-988人已学习 课程介绍         本课程是<朱有鹏老师单片机完全学习系列课程>第4季第2个课程,本课程我们开始分析uCOS ...

  5. Java设计模式——工厂模式讲解以及在JDK中源码分析

    需求:便于手机种类的扩展 手机的种类很多(比如HuaWeiPhone.XiaoMiPhone等) 手机的制作有prepare,production, assemble, box 完成手机店订购功能. ...

  6. uCOS2源码分析3-RTOS核心代码视频课程-第4季第4部分-朱有鹏-专题视频课程

    uCOS2源码分析3-RTOS核心代码视频课程-第4季第4部分-1077人已学习 课程介绍         本课程是<朱有鹏老师单片机完全学习系列课程>第4季第4个课程,本课程我们重点分析 ...

  7. 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

    目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...

  8. SpringBoot-web开发(四): SpringMVC的拓展、接管(源码分析)

    [SpringBoot-web系列]前文: SpringBoot-web开发(一): 静态资源的导入(源码分析) SpringBoot-web开发(二): 页面和图标定制(源码分析) SpringBo ...

  9. SpringBoot-web开发(二): 页面和图标定制(源码分析)

    [SpringBoot-web系列]前文: SpringBoot-web开发(一): 静态资源的导入(源码分析) 目录 一.首页 1. 源码分析 2. 访问首页测试 二.动态页面 1. 动态资源目录t ...

最新文章

  1. Mysql INSERT INTO .. ON DUPLICATE KEY更新多行记录
  2. 3-3 面向对象 本章总结
  3. Yii框架 ajax案例
  4. 医保费用监控指标体系建立(四)医疗机构指标分析
  5. SIGIR 2021|重新思考Attention在CTR预估中作用
  6. MapReduce入门
  7. 关于买伞时直径的选择
  8. 新建Acquisition contract出错的问题
  9. c# 分类 机器学习_C#也能做机器学习?基于.NET的AI智能应用市场还是一片“处女地”...
  10. microsoft visual c++ 编译c语言,Microsoft Visual C++ 程序的部署方法
  11. linux java sqlldr_oracle在linux如何安装sqlldr
  12. python入门到应用实践_Python 3.x入门到应用实践
  13. [转载] 如何使用 Python 生成酷炫的二维码?
  14. oracle外部表迁移,海量数据迁移之外部表并行抽取
  15. 需求调研报告模板_培训需求调研报告不会写,遇到问题咋解决?
  16. 12款在线批量缩短新浪短链接的生成器和接口api
  17. uniapp本机号码一键登录
  18. Zookeeper Leader选举算法及选举过程
  19. linux磁盘列阵和文件系统
  20. 用html和css画太极图,利用css画一个太极图(阴阳八卦)实例

热门文章

  1. Linux io运行情况,Linux IO调度层分析
  2. Ndarry/Dataframe使用pytorch转为tensor格式
  3. python range函数报错:TypeError: ‘float‘ object cannot be interpreted as an integer
  4. 排序算法(5)----堆排序
  5. mysql使用cmd命令连接_通过cmd命令连接mysql
  6. wordpress php 链接,WordPress中获取页面链接和标题的相关PHP函数用法解析
  7. 启航龙图计算机网络,2020年哈尔滨工业大学854计算机基础考研大纲
  8. 不实用额外变量 交换_变量交换:巧用异或运算
  9. android studio怎么输入中文,Android studio 模拟器中输入中文
  10. va_start、va_end、va_arg 实现可变长参数