嵌入式 linux 系统框架移植笔记入门
视频地址 Linux系统移植入门到精通/嵌入式高手必备技能_哔哩哔哩_bilibili
烧写分区 擦除 mmc erase 0(第0个块) 10000(空间) uboot所在地方为第一个区,默认已经分配完毕,使用fdisk只需要分区kernel,rootfs,datafs
uboot 烧写 update_mmc 2 2ndboot 48000000(文件位置) 200(烧录起始地址,预留1一个扇区,不知道为啥,后面再议,) 53bb0(烧录文件大小)
检测是否写入的一种方式 48000000是读取数据的存放位置 0x800 是读取起始地址 0x3000是读取的扇区个数,每个扇区512个字节
执行 bootm 48000000 和 go 48000000 不同处,在于bootm可能还带有参数进行跳转,go命令是直接跳转 在uboot数字默认是hex格式
uboot 中bootcmd是内核启动的指令 bootargs是与根文件系统相关 其中
root=/dev/mmcblk0p2 表示第三个分区(一共四个分区,依次是uboot,kernel,rootfs,datafs)
rootfstype=ext4 表示文件分区类型
init=/linuxrc 初始化进程,即1号进程
maxcpus 启动几个cpu
通过sftpcopy文件
通过nfs挂载文件实现快速下载
具体那些目录允许nfs客户端来访问是需要配置的
文件 /etc/exports
然后生效 /etc/init.d/nfs-kernel-server restart
检查 sudo exportfs
在载入footfs(根文件系统)时候,可以直接从网络上找如下,之后可以直接在nfs主机上操作根文件系统,进行读写删除
uboot基础知识
计算当前文件夹下文件总数 find ./ -type f | wc -l
打补丁 patch -p4 <xxx.patch
linux 读代码,有ctags ctags -R * 生成一个tags文件
win有si si添加汇编文件如下
make v=1 显示编译链接详细过程
在编译uboot时,最终生成 u-boot 先rmake config,再make,再 rm u-boot 再make v=1
u-boot.lds中先放置的是代码段,具体实现是在.o中,一般看lds中第一个.o即为第一个
uboot 启动
如果有一个函数有多个实现,可以看是否编译参与编译,eg
找源码另一种方案,结合 u-boot.map文件
在u-boot中,就有一种快速方法“从众多的同名函数中找到与我们相关的那一个”:
编译出来完的uboot会生成一个u-boot.map文件,你只要以这个“函数的名字”为关键字去u-boot.map中查找,就能找到编译出来的uboot映像,使用的是哪个文件中的函数了。
生成map案例 gcc -Wl,-Map,a.map foo.c -o foo
eg: 查找 _start
入口 _stext
reset 还有一堆操作 eg cpu_init_cp15 , disable mmu,然后检测指定位置有没有代码段,没有就重新加载一份,再,清空bss段,在向下有个函数调用 board_init_f
在 board_init_f 函数中调用 initcall_run_list 函数,依次执行 init_sequence_f 数组中的函数 完成了一系列硬件的初始化
在board_init_r 中 使用 grep "board_init_r" * -nrw 查找相关内容 同上 最后一步执行 run_main_loop 分水岭 之前 汇编语言居多 之后 基本都是c语言代码
在main_loop函数中有个 bootdelay_process 执行(,就是执行读秒倒计时的函数),进行预处理,并获取bootcmd作为返回值,返回,将延时时间赋值给一个全局变量
最终在autoboot_command中执行 在abortboot中读秒,若中间没打断,就执行s命令,跳转到kernel
若中间打断了, 就返回出来,执行 cli_loop 函数
uboot终端命令行提示符
uboot添加启动logo
patch打补丁案例
屏幕坐标轴 将图片转化为数组
c语言extern的用法
uboot中绘制的位置
uboot 源码目录下几乎都有一个 makefile 决定当前目录下有哪些写文件进行编译
烧录uboot
linux 内核移植
统计文件个数的一个方案 find ./ -type f | wc -l
注意交叉编译工具链
源码目录下
arch下是平台相关的 ,硬件相关的代码在eg:arch/arm/kernel
kernel 是内核最核心功能代码(硬件无关),eg任务管理,任务调度...
lib 目录下是平台无关的一些库函数,任何平台都能用
修改内核
devicd driver 里面看看哪些是不需要的,直接干掉
file system只包含一种
内核打补丁
linux内核也饿相当于裸板程序 查看看文件 大小 eg du -h arch/arm/boot/image
.o -> elf 文件eg vmlinux -> .bin(Image) 位置arch/arm/boot/image -> 文件太大,放不下,压缩下zimage(自解压缩代码+压缩后的Image) ->uImage(64字节的头信息+zImage),专门提供给uboot使用,多出来的64字节,即为内核的基本信息
要分析 Image 信息,可以先删除 Image ,然后 然后再执行一次看看链接的先后顺序 -T 链接 脚本 分心 连接脚本时,程序员可恶意定义除了 代码段,数据段,bss段外的自定义段
若在链接时,自定义段总未指定先后顺序,则默认,按照.o的连接出现顺序,eg,此处 head.o找那个没有.head.text段,则实际代码入口还得需要向后 查找
可以实际到head.S中国查看
内核启动分析
mmu -> 物理地址和虚拟地址之间的映射,此处先简单创建一个,凑合使用,后面会创建一个更加全面的
在__mmap_switched 函数中,r13执行位置在__turn_mmu_on,后面的就使用虚拟地址了 ,在__mmap_switched 函数中,有 start_kernel 的跳转 之后的函数基本就是c语言代码了
内核额启动流程
makefile
kconfig
make modules 生成modules 然后下载到板子上,然后手动装载
根文件系统
busybox
busybox默认的生成的根目录位置在当前目录下的_install下,却少不少 东西,可恶意 一条一条添加上来
缺少的库,可以去交叉编译工具链中查找 数学库和c库
copy文件带有软连接属性 加-d 对于文件夹 可以加-a
将库自动加载到内存,使用 流加载器 来完成 从交叉编译工具链中copy到指定目录
linuxrc 是在init/init.c下,有个 init_main 执行 具体执行parse_inittab -> /etc/inittab
/etc/inittab 文件
/etc/init.d/rcs 是一个bash脚本 文件中放置开机自启动相关程序 写完后需要手工添加一个可执行权限 chmod +x ... 创建 /etc/fstab 然后准备必要的目录文件
还有创建必要的设备文件
下载根文件系统
其他一些小问题
修改 /etc/init.d/rcs
小插曲,环境变量
文件系统
linux 查看历史指令
linux自带的命令 打包镜像
cramfs 文件系统优势: 小,不能修改,只读
常用文件系统类型 1 配置内核,让内核支持ext4
1 创建ext4文件
2 格式化ext4分区
3 挂载
4 copy数据
5 卸载
//