Linux-学习笔记3

@和原子哥一起学习Linux

C语言版本LED等灯驱动实验

1、C语言编译环境搭建

  1. 设置处理器模式
    将CPSR寄存器的bit4-0设置为0x13,设置6ULL进入特权模式SVC。
    读写状态寄存器使用MRS和MSR.MRS-读出 MSR-写入

  2. 设置SP指针 (栈指针)
    ALPHA 开发板的 DDR 容量:256MB,起始地址都为 0X80000000,终止地址为 0X8FFFFFFF . SP 指向DDR,向下增长。定义为2M=0x200000,所以定义栈顶地址为0x80200000.

  3. 跳转main函数
    使用b指令跳转

.global _start


_start:
        /*设置处理器进入SVC模式 */
        mrs r0,cpsr
        bic r0,r0,#0x1f  /*清除cpsr bit4-0 */
        orr r0,r0,#0x13  /*使用SVC模式 */
        msr cpsr,r0      /*写入CPSR */

        ldr sp, =0X80200000  /*设置sp指针*/

        b main           /*跳转main */

2、Makefile

objs = start.o main.o

ledc.bin : $(objs)
	arm-linux-gnueabihf-ld -Ttext 0X87800000 $^ -o ledc.elf
	arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@
	arm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis

%.o :%.c
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<

%.o :%.S
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<

clean:
	rm -rf *.o ledc.bin ledc.elf ledc.dis

其中:
$^的意思是所有依赖文件的集合,在这里就是 objs 这个变量的值
$@的意思是目标集合,在这里就是“ledc.bin”
$<的意思是依赖目标集合的第一个文件

“-O”选项指定以什么格式输出,后面的“binary”表示以二进制格式输出

“-S”表示不要复制源文件中的重定位信息和符号信息

“-D”选项表示反汇编所有的段

-m machine 指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构.这里例子中指定反汇编得到的目标文件使用ARM架构。

Wall:【Warning all】
选项可以打印出编译时所有的错误或者警告信息。这个选项很容易被遗忘,编译的时候,没有错误或者警告提示,以为自己的程序很完美,其实,里面有可能隐藏着许多陷阱。变量没有初始化,类型不匹配,或者类型转换错误等警告提示需要重点注意,错误就隐藏在这些代码里面。没有使用的变量也需要注意,去掉无用的代码,让整个程序显得干净一点。下次写Makefile的时候,一定加-Wall编译选项。

-nostdlib:【No Standard Library 】
不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器。这个选项常用于编译内核、bootloader等程序,它们不需要启动文件、标准库文件。

-c 应该是只编译不链接

“-o”选项指定链接生成的 elf 文件名

3、链接脚本

SECTIONS{
    . =0X87800000;
    .text :
    {
        start.o
        *(.text)
    }
    .rodata ALIGN(4) : {*(.rodata*)}
    .data ALIGN(4) : {*(.data) }
    __bss_start=.;
    .bss ALIGN(4) : {*(.bss) *(COMMON) }
    __bss_end=.;
}

注意写的格式
. =0X87800000; 点-空格-0X87800000-;
.text : 点-text-空格-:

写完后修改:

	arm-linux-gnueabihf-ld -T(链接脚本文件名.lds) $^ -o ledc.elf

你可能感兴趣的:(linux,阿尔法开发板,linux)