基于 Exynos 4412 的系统移植记录,ARM 裸机程序。
试验环境:
- SoC:Samsung Exynos 4412(ARM Coretex-A9 based Quad CPU)
- Board:iTOP-4412 POP 1GDDR
- Compiler:arm-linux-gnueabi-gcc(gcc version 7.5.0 (Linaro GCC 7.5-2019.12))
工程代码
LED 闪烁代码目录:
- CodeSign4SecureBoot_POP/(从讯为开发板资料中拷贝)
- bare_led/
- Makefile
- start.S
- led.c
Makefile
1 | CROSS := arm-linux-gnueabi |
gcc 编译选项
-c
:仅执行编译操作,不进行连接操作。-nostdlib
:用于告诉编译器不连接系统标准启动文件和标准库文件。此选项常用于裸机 bootloader、 linux 内核等程序,因为它们不需要启动文件、标准库文件。gcc-ld -Ttext
:链接器 ld 负责将这些段合并成最终的可执行文件或动态链接库。-Ttext 选项用于指定 .text 段在可执行文件中的起始地址。-Ttext 0x0
即将 .text 段的起地址设置为 0x0。gcc-objcopy
:用于将目标文件的内容复制到另一个目标文件中。具体而言,objcopy的作用可以分为以下几个方面:- 格式转换:objcopy可以将一个目标文件的格式转换为另一个格式。例如,可以将ELF格式的目标文件转换为COFF格式,或者将COFF格式的目标文件转换为ELF格式。
- 剪切和提取objcopy可以从一个目标文件中剪切出一部分内容,并将其保存到一个新的目标文件中。这对于从一个目标文件中提取特定的节(section)或符号(symbol)非常有用。
- 符号表操作:objcopy可以修改目标文件中的符号表,如更改符号的名称或属性。这在一些特殊的情况下非常有用,如在程序调试过程中修改符号信息。
- 调试信息处理objcopy可以提取、剪切、合并或删除目标文件中的调试信息。这对于调试过程中的符号跟踪、代码优化或大型软件项目的构建很有帮助。
gcc-objcopy -O binary <input_file> <output_file>
:使用这个命令可以将目标文件(通常是可执行文件或者目标文件)转换成为一个纯粹的二进制文件,不包含任何元数据和头部信息(例如程序入口点、符号表等),只包含代码和数据的字节流。这个二进制文件通常可以用于嵌入式系统、固件更新等特应用中。
start.S
1 | //#define CONFIG_SYS_ICACHE_OFF |
代码分析
.global _start
:.globl
定义一个全局标志,表明包含该标志的文件链接的任何文件都可以使用该符号,否则,仅在定义标志的文件中可见。ldr{<size>} Rx,=<immediate|symbol>
:Load register,从内存拷贝 指定大小 到寄存器。同样用法的另一个指令str
用于从寄存器拷贝到内存。指定大小:- b - unsigned byte
- h - unsigned half-word
- sb - signed byte
- sh - signed half-word
- sw - signed word
#0
:立即数寻址方式,代表数字0[r0]
:以 r0 为地址的内存地址mrc <pnum>, <opcode1>, <Rd>, <CRn>, <CRm>, <opcode2>
:Move to Register from Coprocessor,用于从协处理器寄存器(如CP15)中读取一个32位的数据。反向操作使用指令mcr
。其中:<pnum>
:协处理器的编号<opc1>
:指定操作类型<Rd>
:目标寄存器,用于接收来自协处理器的数据<Cp>
:协处理器地址<Cn>
:寄存器地址,用于选择协处理器的寄存器组<Cm>
:寄存器地址,于选择协处理器解码的寄存器mrc p15, 0, r0, c1, c0, 0
将CP15的控制寄存器(c1)的值读入ARM寄存器R0
bic {S} Rd, Rn, Operand2
:(Bit Clear)指令用于将寄存器中的指定位清零。将Rn
中的指定位清零,并将结果存储在Rd
中。操作数Operand2
中指定了要清零的位。其中:{S}
:可选项,指定是否更新条件码。Rd
:目标寄存器,存储清零结果。Rn
:源寄存器,存储待清零的值。Operand2
:操作数,可以是立即数、寄存器或寄存器移位操作数。
orr Rd, Rn, Operand2
:该指令的作用是将Rn
寄存器的值与Operand2
的值进行逻辑或操作,结果存储在Rd
寄存器中。这可以用来设置特定的位,或者将一组位的某些位置为1。所有逻辑操作指令:
- and - Bitwise AND
- bic - Bitwise Bit Clear
- eor - Bitwise Exclusive OR
- eon - Bitwise Exclusive OR NOT
- orr - Bitwise OR
- orn - Bitwise OR NOT, and
- mvn - Bitwise NOT
b/bl
:b(branch)指令用于无条件地跳转到一个指定的地址或标签。bl(branch with link)指令也是用于跳转,但不同于b指令的是,bl指令在跳转之前会先将当前指令的下一条指令的地址保存到链接寄存器(LR)中,这样在跳转完成后,程序可以使用bx(或者mov + bx)指令将链接寄存器(LR)的值加载到程序计数器(PC)中,返回到原来的位置。bl指令通常用于实现函数调用。
相关寄存器
led.c
1 |
|
相关寄存器
编译
1 | make img |
汇编直接点灯
修改 Makefile
1 | led.bin: start.o# led.o |
修改 start.S(仅点亮 LED)
1 |
|
烧写
1 | # 插入 SD 卡,显示为 /dev/sdb |