以下部分资料和硬件参考于韦老师的百问网。
嵌入式linux启动流程
宏观上:
Windows:BIOS -> 启动windows-> 识别C盘 -> 运行APP
Linux:bootloader(常用u-boot) -> 启动Linux内核(内核本身+驱动程序) -> 识别根文件系统(系统必备APP+用户APP) -> 运行APP
微观上:
Reset(硬件复位) -> ROM(内部只读存储器) -> U-boot(bootloader引导程序,设置环境变量,启动kernel) -> Kernel+dtb(内核+设备树) -> Rootfs(根文件系统) -> APP(系统应用+用户应用/usr/bin/)
编译流程
一个C/C++文件需要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)、链接(linking)才能变成可执行文件。
gcc -E -o hello.i hello.c(预处理,获取文件所需要的库,展开宏定义,.c->.i)
gcc -S -o hello.s hello.i(编译,生成汇编指令,检测语法,.i->.s)
gcc -c -o hello.o hello.s(汇编,生成机器码,.s->.o)
gcc -o hello hello.o(链接生成app,.o->.elf)
下列是gcc指令常用的选项
常用选项 |
描述 |
-E |
预处理 |
-c |
把预处理、编译、汇编都完成,但不进行链接 |
-o |
指定输出文件 |
-I(大写i) |
指定头文件目录 |
-L |
指定链接时库文件目录 |
-l(小写L) |
指定链接哪一个库文件,如-labc 链接的是libabc.so文件 |
-v |
显示编译细节 |
#include <…>:工具链所指定的目录LIBRARY_PATH下查找,可通过-I添加路径
链接库的创建使用
(一)、制作和使用动态链接库(.so,share object)
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -shared -o libsub.so sub.o sub2.o sub3.o(可以使用多个.o生成动态库)
gcc -o test main.o -lsub -L .(libsub.so所在目录)
运行test前需要把动态链接库libsub.so放到/lib里或者修改环境变量LD_LIBRARY_PATH添加该库的路径。
(二)、制作和使用静态链接库(.a,archive )
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
ar crs libsub.a sub.o sub2.o sub3.o (可以使用多个.o生成静态库)
gcc -o test main.o libsub.a (如果.a不在当前目录下,需要使用-L指定它的绝对或相对路径)
不需要把静态链接库放到板子上。如果执行arm-linux-gnueabihf-gcc -c -o sub.o sub.c交叉编译需要在最后面加上 -fPIC参数。
开发前基础库下载
sudo apt-get install curl mtd-utils gcc make git vim python net-tools openssh-server
python-dev build-essential subversion
libncurses5-dev zlib1g-dev gawk gcc-multilib flex git-core gettext
gfortran libssl-dev libpcre3-dev xlibmesa-glu-dev libglew1.5-dev
libftgl-dev libmysqlclient-dev libfftw3-dev libcfitsio-dev graphviz-dev
libavahi-compat-libdnssd-dev libldap2-dev libxml2-dev p7zip-full bzr
libkrb5-dev libgsl0-dev u-boot-tools lzop
tftp-hpa tftpd-hpa openssh-server git nfs-kernel-server samba
nfs-common -y
各压缩格式操作
tar只是一个打包工具,并不是压缩格式,它能对gzip(tar.gz)和bzip2(tar.bz2)格式进行操作。
(一)、gzip(针对小文件)
- 解压:tar -zxvf input.tar.gz(-C path 指定解压路径)
- 压缩:tar -zcvf output.tar.gz output
gzip指令只能压缩单个文件,不能压缩目录
- 解压:gzip -dk file.gz
- 压缩:gzip -k file(输出file.gz)
(二)、bzip2(针对大文件)
- 解压:tar -jxvf input.tar.bz2(-C path 指定解压路径)
- 压缩:tar -jcvf output.tar.bz2 output
bzip2指令只能压缩单个文件,不能压缩目录
- 解压:bzip2 -dk file. bz2
- 压缩:bzip2 -k file(输出file.bz2)
常用的汇编指令
1、LDRB/LDRH/LDR(读内存指令,load register,分别代表读取1/2/4字节数据)
LDR r0, [addrA] r0 = A
2、STRB/STRH/STR(写内存指令,store register,分别代表写入1/2/4字节数据)
STR r0, [addrA] A=r0
3、ADD/SUB(加减指令,add/subtract,不涉及寄存器操作,仅在CPU内部实现)
ADD r0, r1, r2 r0=r1+r2
4、BL(跳转,branch and link,记录返回地址至R14 lr,执行label)
BL label
5、PUSH(出栈指令,等于多次调用STR指令,且减少栈指针R15 sp的值)
PUSH {r3, pc}
6、POP(入栈指令,等于多次调用LDR指令,且增加栈指针sp的值)
POP {r3, pc}
创建线程要素
1、线程控制块
2、栈
3、函数入口
遇到的问题
(一)、error: RPC failed; curl 18 transfer closed with outstanding read data remain
postBuffe太小,需要把它设置大些
git config --global http.postBuffer 524288000
(二)、make all时缺少模块ExtUtils::MakeMaker
sudo yum install perl-ExtUtils-MakeMaker
(三)、make all时权限问题
configure: error: you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this check)
See `config.log' for more details
make: *** [/root/myir/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/build/host-tar-1.29/.stamp_configured] Error 1
export FORCE_UNSAFE_CONFIGURE=1
(四)、makeinfo: command not found
缺少指定的命令,下载texinfo包即可,
sudo yum install texinfo
(五)、虚拟机扩容
进入windows下virtualbox的目录,打开cmd。
1、进入VM VirtualBox目录
cd C:\Program Files\Oracle\VirtualBox\
2、查看已挂载硬盘参数
VBoxManage list hdds
3、输出数据,获取硬盘对应UUID
UUID: 97705cfe-5d0a-4221-9e62-d5f2ab67927f
Parent UUID: base
State: locked write
Type: normal (base)
Location: D:\virtualmachine\UBUNTU\UBUNTU.vdi
Storage format: VDI
Capacity: 20480 MBytes
Encryption: disabled
4、给指定硬盘扩容,如扩容至40G。
VBoxManage modifyhd 97705cfe-5d0a-4221-9e62-d5f2ab67927f --resize 40960
5、输出下列信息说明成功。
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
6、进入虚拟机,在ubuntu应用界面输入disks,给指定硬盘(如sda1扩容)。
(六)、挂载nfs路径错误
mount: /mnt: bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount. helper program.
没有配置nfs,操作步骤如下:
1、在文件/etc/exports下添加需要共享的路径
/home/seanoy *(rw,nohide,insecure,no_subtree_check,async,no_root_squash)
2、重启nfs服务
sudo /etc/init.d/nfs-kernel-server restart
3、挂载测试(将本机的目录/home/seanoy挂载到目录/mnt处)
sudo mount -t nfs -o nolock,vers=3 127.0.0.1:/home/seanoy /mnt