首页 新闻 工控搜 论坛 厂商论坛 产品 方案 厂商 人才 文摘 下载 展览
中华工控网首页
  P L C | 变频器与传动 | 传感器 | 现场检测仪表 | 工控软件 | 人机界面 | 运动控制
  D C S | 工业以太网 | 现场总线 | 显示调节仪表 | 数据采集 | 数传测控 | 工业安全
  电 源 | 嵌入式系统 | PC based | 机柜箱体壳体 | 低压电器 | 机器视觉
收藏本文     查看收藏
    在google上输入arm linux,找到全是如何配制,就没有人解释一下吗?靠,我觉得不仅要知其然,还要知其所以然。不知道放哪里好。我喜欢这里,所以来这里投,试试 还有,我的机还在用PII,老是出问题,前不久,分区就没了一会,心痛啊!!!!!!!!!!!好多好东东都没了。顺便问一下大家谁有碰到过没有光驱接上,硬盘就不能启动的问题啊。这个问题可把我这个自称高手的人给难坏了    2004.5.23

    今天开始,我要好好看看arm linux的代码了,好久没有这样的豪言壮语了
    拿哪个开刀呢。翻翻以前的工作,加上正好有人问,所以决定先搞定entry-armv.S文件。
    看我一刀

    文件一开始是一大堆宏定义,用于指明是用的何种芯片。定义了三个针对不同芯片的宏,disable_fiq、get_irqnr_and_base和irq_prio_table。

    跳过这些宏,来到:
    .section “.text.init”, #alloc, #execinstr 这里说明了下面的段是初始化段,有关初始化段的内容参考书籍。

1        vector_IRQ:
2                ldr r13, .LCsirq
3                sub lr, lr, #4
4                str lr, [r13]
5                mrs lr, spsr
6                str lr, [r13, #4]
7                mrs r13, spsr
8                bic r13, r13, #MODE_MASK
9                orr r13, r13, #MODE_SVC|I_BIT
10                msr spsr_c, r13
11                and lr, lr, #15
12                ldr lr, [pc, lr, lsl #2]
13                movs pc, lr
14                .LCtab_irq: .word __irq_usr
15                .word __irq_invalid
16                .word __irq_invalid
17                .word __irq_svc
18                .word __irq_invalid
                …
解释:
1.IRQ中断向量的入口
2.读取.LCsirq地址的内容到r13寄存器中。.LCsirq定义如下:
.LCsirq: .word __temp_irq
即.LCsirq中保存了__temp_irq的地址,而__temp_irq定义如下:
__temp_irq: .word 0 @saved lr_irq
          .word 0 @saved spsr_irq
          .word -1 @old_r0
从这里可以得出r13保存了__temp_irq的地址,而这个地址用来保存了lr_irq、spsr_irq、old_r0的值。具体情况参见下面的解释。
3.恢复发生中断时的地址(该地址即是中断返回地址),参考ARM IRQ异常的书籍。
4.保存返回地址到r13,前面看到了r13的赋值情况,所以地址是被保存在__temp_irq的第一个word中。
5.读取中断发生时的CPSR,有关情况参考ARM IRQ异常的书籍
6.保存CPSR到__temp_irq的第二个word中。
7.将SPSR保存到r13中。注:这里不使用lr,而要另赋值到r13中,是因为要改变SPSR的值,而原来的值也有用。所以改变用r13,原来的值用lr。
8.清除模式位。MODE_MASK的定义参见\linux-2.4.26\include\asm-arm\proc-armv\ ptrace.h文件:
#define MODE_MASK        0x1f
9.在\linux-2.4.26\include\asm-arm\proc-armv\ ptrace.h下还定义了:
#define SVC_MODE        0x13
#define I_BIT                0x80
这时r13被修改为禁止irq中断的svc模式。
10.将修改好的模式放入spsr中。
11.lr保留了原来的cpsr,做与操作后,只保留其模式位。即说明该中断发生自何种模式下。
12.读取.LCtab_irq中的内容,放置于lr寄存器中。而.LCtab_irq中保存了中断发生自各种不同模式下的处理函数。其中使用了pc寄存器,详情参考ARM书籍。
13.切换模式并跳转到相应处理函数。

0        __irq_usr: sub sp, sp, #S_FRAME_SIZE
1                stmia sp, {r0 - r12}
2                ldr r4, .LCirq
3                add r8, sp, #S_PC
4                ldmia r4, {r5 - r7}
5                stmia r8, {r5 - r7}
6                stmdb r8, {sp, lr}^
7                alignment_trap r4, r7, __temp_irq
8                zero_fp
9                get_irqnr_and_base        r0, r6, r5, lr
10                movne r1, sp
11                adrsvc        ne, lr, 1b
12                bne do_IRQ
13                mov why, #0
14                get_current_task tsk
15                b ret_to_usr

解释:
0.此函数是当IRQ中断发生在usr模式时,调用的。它首先从堆栈中保留出存放寄存器的空间,用于保存现场。在entry-header.s中定义了如下宏:
#define S_FRAME_SIZE        72
#define S_OLD_R0        68
#define S_PSR                64
#else
#define S_FRAME_SIZE        68
#define S_OLD_R0        64
#define S_PSR                60
#endif

#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 S_OFF                8
#define S_FRAME_SIZE        72
#define S_OLD_R0        68
#define S_PSR                64

从这些宏中,我们可以得到arm linux使用的栈结构如下图:
0  |-------------|
   | S_R0        |
4  |-------------|
   | S_R1        |
8  |-------------|
   | S_R2        |
12 |-------------|
   | S_R3        |
16 |-------------|
   | S_R4        |
20 |-------------|
   | S_R5        |
24 |-------------|
   | S_R6        |
28 |-------------|
   | S_R7        |
32 |-------------|
   | S_R8        |
36 |-------------|
   | S_R9        |
40 |-------------|
   | S_R10       |
44 |-------------|
   | S_FP        |
48 |-------------|
   | S_IP        |
52 |-------------|
   | S_SP        |
56 |-------------|
   | S_LR        |
60 |-------------|
   | S_PC        |
64 |-------------|
   | S_PSR       |
68 |-------------|
   | S_OLD_R0    |
72 |-------------|

注:这个图在arm linux中很重要!

1.保存如上图所示的r0到r12寄存器。因为这些寄存器得以保存。我们现在可以大胆的使用这些寄存器了
2.读取.LCirq的内容到r4寄存器中。.LCirq的定义如下:
.LCirq .word __temp_irq
哈哈,在vector_IRQ中提到的__temp_irq在此显身。我们知道__temp_irq中保存了些什么。我想各位应该猜到了下面的代码是什么了吧
在这里将.LCirq的地址放到r4寄存器中。
3.将r8指到前面所说的保存S_PC的地方。前面保存了r0-r12,还有S_SP、S_LR、S_PC、S_PSR、S_OLD_R0没有保存。
4.读取__temp_irq中的内容
5.保存S_PC、S_PSR、S_OLD_R0。
6.保存S_SP、S_LR,要注意保存的是用户模式的sp和lr。
7.在entry-header.S中,定义了alignment_trap宏:

        .macro        alignment_trap, rbase, rtemp, sym
#ifdef CONFIG_ALIGNMENT_TRAP
#define OFF_CR_ALIGNMENT(x)        cr_alignment - x

        ldr        \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
        mcr        p15, 0, \rtemp, c1, c0
#endif
        .endm

 

状 态: 离线

公司简介
产品目录

公司名称: 深圳市盈鹏飞科技有限公司
联 系 人: 李希岗
电  话: 0086-13602511395
传  真: 0755-82523175,82523176-819
地  址: 深圳市福田区福明路40号,雷圳大厦12A06
邮  编: 518033
主  页:
 
该厂商相关技术文摘:
WINCE下如何添加CPL应用程序
Wince sqlite3移植
EAC-C925开机画面实现手册
英贝德推出单板机产品软件升级解决方案(WinCE篇)
EP9315电路设计要点
Linux下创建和使用RamDisk的技巧
英贝德科技移植PPP大揭秘:PPP拨号在ARM2410平台上的移植
AT91SAM9263在人机界面方面的应用
详解WinCE下USB Host驱动开发(2)
详解WinCE下USB Host驱动开发(1)
WinCE驱动中设备中断的处理
Linux内核学习之BogoMIPS值的计算
更多文摘...
立即发送询问信息在线联系该技术文摘厂商:
用户名: 密码: 免费注册为中华工控网会员
请留下您的有效联系方式,以方便我们及时与您联络

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 不良信息举报
工控网客服热线:0755-86369299
版权所有 中华工控网 Copyright©2022 Gkong.com, All Rights Reserved