s5pv210之路(2) — 固件烧写文章中,我们搞定了固件烧写的环境,本节我们开始编译代码。
arm有多款编译工具链,它们之间的区别参考各版本arm-gcc区别与安装。
百度arm-gcc点进去,这里有许多的版本以及对应Linux和Window的版本,下载gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2或gcc-arm-none-eabi-10-2020-q4-major-win32.zip。这个工具链适合编译裸机(相对于Linux应用程序而言)程序,使用小巧的newlib库,生成的代码体积小。
$ tar -jxf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 $ cd gcc-arm-none-eabi-10-2020-q4-major/bin $ ./arm-none-eabi-gcc --version # 查看arm gcc版本 arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release) # 将工具链路径加入PATH环境变量,/opt/gcc-arm-none-eabi-10-2020-q4-major/bin是我的工具链路径 $ echo "export PATH=/opt/gcc-arm-none-eabi-10-2020-q4-major/bin:$PATH" >> ~/.bashrc $ . ~/.bashrc $ arm-none-eabi-gcc --version # 查看arm gcc版本 arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release)
这个工具链可以编译裸机程序,也可以编译Linux应用程序,使用Glibc库,我后面主要使用它来编译程序。目前没找到比较好的下载途径,但可以在ubuntu上使用apt
命令安装。
$ sudo apt install gcc-arm-linux-gnueabi $ arm-linux-gnueabi-gcc --version arm-linux-gnueabi-gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 Copyright (C) 2019 Free Software Foundation, Inc.
拷贝x210v3裸机开发教程\src\buzzer
文件夹到虚拟机,这是一个使用arm-none-eabi-gcc
和make
编译的工程,可以用来验证我们的环境。
# 在虚拟机中计入buzzer目录直接进行编译即可 $ cd buzzer $ make
编译成功了,但是有个mkv210
不存在,这个程序是用来制作SD卡镜像的,buzzer\mkv210.exe
是windows版本的,需要实现一个Linux的。
查看buzzer/source/start.S
文件,其中描述了镜像文件头是4个字节,分别是:镜像长度含16字节头
保留值为0
字节累加和不含16字节头
保留值为0
,镜像长度不要求对齐,代码实现时直接在原始的bin文件上修改第1个word和第三个word即可,我们的电脑多是小端环境,故没有考虑大端情况。详细参考 [project X] tiny210(s5pv210)上电启动流程(BL0-BL2)。
/* * bl1 header infomation for irom * * 0x0 - bl1 size * 0x4 - reserved (should be 0) * 0x8 - check sum * 0xc - reserved (should be 0) */ .word 0x2000 .word 0x0 .word 0x0 .word 0x0
实现镜像制作的源码为:
mkv210.c
#include <stdio.h> #include <stddef.h> #include <stdint.h> uint8_t buf[512]; struct { uint32_t len; uint32_t received0; uint32_t sum; uint32_t received1; } header; int main(int argc, char *argv[]) { FILE *binfp; uint32_t sum; long binlen; long i; int j; if (argc != 2) { fprintf(stderr, "Usage: mkv210 x.bin\n"); return -1; } binfp = fopen(argv[1], "rb+"); if (binfp == NULL) { fprintf(stderr, "open file error.\n"); return -1; } fseek(binfp, 0L, SEEK_END); binlen = ftell(binfp); if (binlen <= 16) { fprintf(stderr, "file is invalid. file sizes small then 16 bytes.\n"); fclose(binfp); remove(".bin.tmp"); return -1; } rewind(binfp); fread(&header, 1, sizeof(header), binfp); if ((header.len < binlen) || (header.len > 16*1024)) { fprintf(stderr, "file is invalid. img size in header is bigger then " "16KB or smaller then file sizes.\n"); fclose(binfp); remove(".bin.tmp"); return 1; } if ((header.received0 != 0) || (header.received1 != 0)) { fprintf(stderr, "file is invalid. header value should be zero.\n"); return -1; } header.len = binlen; sum = 0; for (i = binlen; i >= 512; i -= 512) { fread(buf, 512, 1, binfp); for (j = 0; j < 512; j++) { sum += buf[j]; } } fread(buf, i, 1, binfp); for (j = 0; j < i; j++) { sum += buf[j]; } header.sum = sum; fseek(binfp, 0L, SEEK_SET); fwrite(&header, 1, sizeof(header), binfp); fclose(binfp); return 0; }编译mkv210程序并添加到系统PATH中:
gcc mkv210.c -o mkv210 mkdir ~/bin cp mkv210 ~/bin $ echo "export PATH=/home/xflm/bin:$PATH" >> ~/.bashrc $ . ~/.bashrc
现在进入buzzer
目录编译这个工程就可以了,参考s5pv210之路(2) — 固件烧写烧写运行。
各版本arm-gcc区别与安装
[project X] tiny210(s5pv210)上电启动流程(BL0-BL2)