系统移植第一天
1 基础理论
1.1 什么是嵌入式
以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统,对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。
可裁剪(软硬件)
1.2 什么是系统
1.2.1 硬件系统
冯诺依曼结构: 控制器,运算器,输入,输出, 存储器
传统的硬件架构: cpu,内存,北桥(高速设备)+ 南桥(慢速设备) --》 芯片组, 显卡 ,外设等等
SOC(system on chip) 片上系统 ,一个芯片集成了硬件系统的主要部件 (内存和外存 引出去的目的: 方便定制)
arm: a r m 三个系列
a系列(高性能) a9 a53 a7x m系列 (低功耗,相对51高性能)m0 m3 m4 m7 r系列 (高实时,高可靠性)
4412—》 cortex-a9 armv7 stm32f103rct6 --》 cortex-m3
1.2.2 软件系统
1.2.2.1 无操作系统(裸机)
应用–》 驱动–》硬件 stm32中 写程序 调用驱动程序 控制硬件
1.2.2.2 有操作系统
应用程序 --》 系统调用–》 内核 --》 驱动–》硬件
2 什么是移植
将一些功能 搬移到 指定的硬件平台上去
2.1 系统移植四大件(五大件)
(1) 交叉编译器 cross - complier (2) 启动引导程序 BootLoader (3) 内核(linux操作系统)kernel (4) 根文件系统 rootfs
(5)应用程序
2.2 来装个系统
2.2.1 交叉编译器 --》 gcc
2.2.2
bios --》BootLoader bios: basic input output system bios --> uefi t通用外部固件接口
上电的第一段代码 : 初始化,检查硬件–》 引导系统–》 给系统传参
比如我们的电脑 可以选择 硬盘,光驱,优盘,网络(无盘工作站)来装系统或者运行系统
2.2.3
内核–》 操作系统内核 (windows NT)
2.2.4
根文件系统 --》 c盘的文件,功能性的,非操作系统的
2.3 以人为类比
BootLoader 闹钟,妈
kernel 灵魂
rootfs 肉体,器官
3 交叉编译器
一般整个工程项目开始前,交叉编译器必须定下来,后期不会做较大更改
gcc(本平台生成本平台目标机代码)
x86 —》 x86 程序
cross 交叉(本平台实现 目标机为arm 的代码)
x86 —》 arm 程序
一般情况下,包含在硬件厂商提供的 板级支持包内 (BSP board support package)
编译器提供网站下载 https://www.linaro.org/latest/downloads/
arm 嵌入式设备 交叉编译器提供组织
也可以自己制作
crosstool-ng 工具 可以生成 交叉编译器
3.1 交叉编译器的配置
3.2 常见命令
readelf
-h 显示 elf 头部信息
-s 显示段信息
size
计算各个段的大小
nm
显示符号
strip
删除符号 --》 精简文件 --》嵌入式必须
objdump
反汇编 -D
objcopy
拷贝或转换 目标文件 拷贝二进制 -O binary 注: 大写O
4 环境搭建
BootLoader: 本身在 板子的emmc内部 已烧写完毕
内核文件 uImage 是通过tftp传输到内存地址的 exyons4412-fs4412.dtb 设备树文件 也是tftp
根文件系统 /rootfs是通过 nfs的方式 远程同步的(挂载)
4.1 tftp 和 nfs
tftp 简单文件传输协议 udp
重启大法:
nfs 网络文件系统 (无盘工作站)
4.2 ubbot 常用命令
先在设备管理器里面看一下端口是几 putty 选 serial 波特率 115200 com几写好 左下角流控制设置为 none 保存
注意拨码开关
011x 是emmc上启动 uboot 100x 是sd卡 启动uboot
上电 敲任意键暂停
如果bootcmd内有内容 则会倒计时等待 不敲任意键则会执行 bootcmd
显示 uboot支持的命令 (不是linux的)
(1)help + 命令 类似于man的作用
(2)printenv 打印所有的环境信息
(3)setenv
setenv + 变量名 + 值 则设置这个值 只加变量名 则清空这个值
(4)saveenv
(5) md
memory display 显示内存的内容
md + 地址(16进制) (6)mm nm6 mm 修改后自增地址 (要算) nm 修改后 地址不变
4.3 挂板子
设置板子和Ubuntu的 ip地址
建议 Ubuntu 设置为 192.168.2.200 右上角标记 新建一个 取名叫board 填入 192.168.2.200 255.255.255.0 192.168.2.1 保存
bootcmd 可以 将连续的操作保存着,如果bootcmd 不是缺省 则 延时会启用
此时完成上面操作会出错
VFS: Cannot open root device “(null)” or unknown-block(0,0):
还差 nfs 根文件系统没挂上
bootargs 需要设置 bootargs 其实是 uboot给内核的传参
bootargs 几个要素: (1) root=?什么类型 nand启动 还是emmc启动 还是其他网络启动呢??
(2)nfsroot 在哪里? nfsroot=ip:/路径 读写
设置前缺认在不在这个目录
(3) 第一个启动的程序是谁
(4) 从哪里显示
(5) 板子的ip地址
(4)和(5)的原因是 uboot完成启动内核后,结束了工作,不存在了,所以串口输出 和 ip地址需要通过传参的方式发给内核
rm: can’t remove ‘hehe’: Permission denied
sudo chmod 777 /source/rootfs
作业:
挂板子成功,编译一个helloworld 在板子上运行
系统移植第二天
markdown
Bootloader
(面试)u-boot 和 bootloader 之间的区别 bootloader中的一种
讯为itop 友善之臂 u-boot无资料
启动引导程序
http://www.denx.de/wiki/U-Boot/Documentation ftp://ftp.denx.de/pub/u-boot
不是越新越好 最合适的版本:u-boot-2013.01.tar.bz2
目录结构
平台相关:arch board
我们参考的板子是 origen 参考板 评估板
平台无关: common uboot的命令源码 include lib 等
编译u-boot
make fs4412_config
错误:
1 linux@ubuntu:~/u-boot-2013.01$ make fs4412_config make: *** No rule to make target `fs4412_config’. Stop. make: *** [fs4412_config] Error 1
解决方法:找到 no rule 在哪里
1 linux@ubuntu:~/u-boot-2013.01$ grep “No rule to make target” * ./* -nF
mkconfig:25: echo “make: *** No rule to make target `$2_config’. Stop.” >&2 ./mkconfig:25: echo “make: *** No rule to make target `$2_config’. Stop.” >&2
–》vi mkconfig +25
–》 boards.cfg 里面有匹配规则
(1)target --》 origen
(2)arch --》 arm
(3)cpu --》 armv7
(4)board name --》 origen
(5)vendor --》 samsung
(6)soc --> exynos
(7)option
操作 复制这一行 在下一行粘贴 把目标改掉
1 linux@ubuntu:~/u-boot-2013.01$ make fs4412_config Configuring for fs4412 board…
下一步 vi Makefile +184 平台 写成arm 交叉编译器: 修改成
arm-none-linux-gnueabi-
下一步 make
错误: from lib/asm-offsets.c:18: /home/linux/u-boot-2013.01/include/config.h:10:28: fatal error: configs/fs4412.h: No such file or directory compilation terminated. make: *** [lib/asm-offsets.s] Error 1
其实是在 include/configs/ 只有origen.h 没有fs4412.h
在顶层目录
1 cp ./include/configs/origen.h ./include/configs/fs4412.h
2
3 操作:
4 (1)make clean
5 (2)make fs4412_config
6 (3)make
生成了三个文件: u-boot.bin 二进制 u-boot.lds 链接脚本 u-boot.map
三星支持 u-boot.bin的格式
sudo cp ./u-boot.bin /tftpboot
1 tftp 41000000 u-boot.bin 2 go 41000000
加载uboot失败
(1) 地址不对 查看 u-boot.map 提示 _start地址在 0x43e00000 (三星定义)
(2)串口没有设置过
u-boot 生成过程
make 出来的 u-boot.bin
–>
439 $(obj)u-boot.bin: $(obj)u-boot 440 $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ 441 $(BOARD_SIZE_CHECK)
找obj 143 obj := $(OBJTREE)/
找objtree
124 OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
找 OBJCOPY 找不到了 我们要是用 vi -t
建立tags 索引
ctags -R
搜索的时候 在这个tags存在的目录下搜索即可
vi -t OBJCOPY config.mk 内 定位到了
150 OBJCOPY = $(CROSS_COMPILE)objcopy
关于链接脚本
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
__image_copy_start = .;
arch/arm/cpu/armv7/start.o (.text*)
*(.text*)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : {
*(.data*)
}
11 arch/arm/cpu/armv7/start.o (.text*)
本质 : u-boot
入口 是 start.S
汇编代码分析
vi ./arch/arm/cpu/armv7/start.S
//1 初始化异常向量表
40 ldr pc, _undefined_instruction
41 ldr pc, _software_interrupt
42 ldr pc, _prefetch_abort
43 ldr pc, _data_abort
44 ldr pc, _not_used
45 ldr pc, _irq
46 ldr pc, _fiq
//2 设置arm指令集
127 bl save_boot_params
128/* set the cpu to SVC32 mode */
131 mrs r0, cpsr
132 bic r0, r0, #0x1f
133 orr r0, r0, #0xd3
134 msr cpsr,r0
–》
152 /* the mask ROM code should have PLL and others stable */
153 #ifndef CONFIG_SKIP_LOWLEVEL_INIT 154 bl cpu_init_cp15
155 bl cpu_init_crit
156 #endif
157
158 bl _main
159
//3 cpu_init_cp15 //关mmu(内存管理单元)
280 *
281 * cpu_init_cp15 282 *
283 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
284 * CONFIG_SYS_ICACHE_OFF is defined.
*
***********************************************************************/
287 ENTRY(cpu_init_cp15)
289 * Invalidate L1 I/D* /
291 mov r0, #0 @ set up for MCR
292 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
293 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
294 mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
295 mcr p15, 0, r0, c7, c10, 4 @ DSB
296 mcr p15, 0, r0, c7, c5, 4 @ ISB
297 298 / 299 * disable MMU stuff and caches*/
301 mrc p15, 0, r0, c1, c0, 0
302 bic r0, r0, #0x00002000 @ clear bits 13 (–V-)
303 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
304 orr r0, r0, #0x00000002 @ set bit 1 (–A-) Align
305 orr r0, r0, #0x00000800 @ set bit 11 (Z—) BTB
306 #ifdef CONFIG_SYS_ICACHE_OFF
307 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
308 #else
309 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
310 #endif
311 mcr p15, 0, r0, c1, c0, 0
312 mov pc, lr @ back to my caller
313 ENDPROC(cpu_init_cp15)
314
//4 cpu_init_crit 其他板级初始化
324 ENTRY(cpu_init_crit)
325 /* * Jump to board specific initialization… The Mask ROM willhave already initializedbasic memory. Go here to bump up clock rate and handle wake up conditions.330 */
331 b lowlevel_init @ go setup pll,mux,memory
332 ENDPROC(cpu_init_crit)
==》 b lowlevel_init
vi -t 是类似效果 在vi 内选中 关键字 ctrl + ‘]’ 前进 ctrl + ‘t’ 后退
追出来的第五十八个 跟origen 有关
81 /* init system clock /
82 bl system_clock_init
84 / Memory initialize /
85 bl mem_ctrl_asm_init
88 / *for UART */
89 bl uart_asm_init
90 bl tzpc_init
91 pop {pc} 初始化话 时钟 初始化 内存 初始化串口
找 _main 在start.s ctrl +]了 _main 选择了第一个arm平台 相关的 .s内 找到了真正的main
98 /* 99 * Set up initial C runtime environment and callboard_init_f(0). */
初始化 c运行的环境
166 /* call board_init_r / 167 ldr pc, =board_init_r / this is auto-relocated! */
调用了 board_init_r arch/arm/lib/board.c 板级相关的信息
运行在43e00000 不行的原因
涉及到一个 trustzone
让u-boot 起来 屏蔽掉 tsz lowlevel_init.s (58那个)
88 /* for UART */ 89 bl uart_asm_init 90 // bl tzpc_init 91 pop {pc}
三星的真实
Exynos 4412 SCP has 64 KB ROM (iROM) and 256 KB SRAM (iRAM) as internal memory.
内置 64k的只读存储器 irom 256k 内存 iram
The boot loader is comprises the first and the second boot loaders. The characteristics of these boot loaders are: iROM: It is a small and simple code to initiate SOC. It is implemented on internal ROM of SOC. First boot loader (BL1): It is chip-specific and stored in external memory device. Second boot loader (BL2): It is platform-specific and stored in external memory device. User should build and store this in an external memory device. It is not provided by Samsung
三星管 内部的 iROM 和 启动代码第一段 BL1 芯片相关
不管 BL2 平台相关
iROM is placed in internal 64 KB ROM. It initializes basic system functions such as clock and stack. iROM loads BL1 image from a specific booting device to internal 256 KB SRAM. The booting device is selected by Operating Mode (OM) pins. According to the secure boot key values, iROM may do an integrity check on BL1 image. BL1 initializes system clock, and DRAM controller. After initializing DRAM controller, it loads OS image from the booting device to DRAM. According to the secure boot key values, BL1 can do an integrity check on the OS image. After the booting completes, BL1 jumps to the operating system.
系统移植第三天
【1】u-boot
(1)uboot 是bootloader的一种
(2)uboot 作用: 初始化硬件,引导内核启动,给内核传参
(3)【面试题】你所使用的uboot的启动流程
宏观: 上电之后,4412内的irom代码(固化代码,无源码 bl0)将启动,从OM开关选择从 emmc或者sd卡启动; 接下来 将从只读存储器(emmc)读取 bl1(加载,验证,解密)到iram, 运行bl1,bl1会去读取 bl2(14k是u-boot.bin的一部分)到iram;最后再加载 u-boot.bin到内存(dram)有时候,又称之为 bl3。
具体:分两个阶段: 第一段: 初始化异常向量表 关中断 关mmu 初始化系统时钟 初始化内存 初始化串口 清bss段
第二阶段: 进一步初始化外围设备
u-boot的网卡移植
使用srom的方式 挂载了 dm9000;只要uboot阶段 能识别网卡 就能使用 ping 等命令
ORIGEN # ping 192.168.2.250
Unknown command 'ping' - try 'help'
276 #if defined(CONFIG_CMD_PING)
defined(CONFIG_CMD_PING)
1 vsp ./include/configs/fs4412.h
2 85 #undef CONFIG_CMD_PING
error:/home/linux/u-boot-2013.01/net/ping.c:69: undefined reference to `eth_halt'
vi /arch/arm/lib/board.c
665 #if defined(CONFIG_CMD_NET)
666 puts("Net: ");
667 eth_initialize(gd->bd);
668 #if defined(CONFIG_RESET_PHY_R)
669 debug("Reset Ethernet PHY\n");
670 reset_phy();
671 #endif
133
134 #ifdef CONFIG_CMD_NET
135 int board_eth_init(bd_t *bis)
136 {
137 int rc = 0;
138 #ifdef CONFIG_CS8900
139 rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
140 #endif
141 return rc;
142 }
143 #endif
110 int board_eth_init(bd_t *bis)
111 {
112 int rc = 0;
113
114 rc = dm9000_initialize(bis);
115
116 return rc;
117 }
#endif
/home/linux/u-boot-2013.01/board/samsung/origen/origen.c:114: undefined reference to `dm9000_initialize'
626 int dm9000_initialize(bd_t *bis)
627 {
628 struct eth_device *dev = &(dm9000_info.netdev);
629
630 /* Load MAC address from EEPROM */
631 dm9000_get_enetaddr(dev);
632
633 dev->init = dm9000_init;
634 dev->halt = dm9000_halt;
635 dev->send = dm9000_send;
636 dev->recv = dm9000_rx;
637 sprintf(dev->name, "dm9000");
638
639 eth_register(dev);
640
641 return 0;
642 }
38 COBJS-$(CONFIG_DRIVER_DM9000) += dm9000x.o
#define CONFIG_DRIVER_DM9000
80 #define CONFIG_DM9000_BASE 0x2c000000
81 #define DM9000_IO CONFIG_DM9000_BASE
82 #define DM9000_DATA (CONFIG_DM9000_BASE + 0x400)
83 #define CONFIG_DM9000_USE_16BIT 1
84 #define CONFIG_DM9000_NO_SROM 1
85 #undef CONFIG_DM9000_DEBUG
#define CONFIG_DM9000_BASE 0x5000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
第一个error 没设置 ipaddr
setenv ipaddr IP地址即可
第二个error 没 ethaddr
setenv ethaddr 00:01:02:03:04:05
【2】kernel
www.kernel.org
目录结构
arch 平台相关 其他的 平台无关: 驱动 工具 头文件,文档等
make mrproper
198 ARCH ?= $(SUBARCH)
199 CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
改成 ------->
ARCH ?= arm
CROSS_COMPILE ?= arm-none-linux-gnueabi-
cp ./arch/arm/configs/exynos_defconfig ./.config
make menuconfig
make uImage -j(cpu个数)
sudo cp ./arch/arm/boot/uImage /tftboot/
VFS: Cannot open root device "nfs" or unknown-block(0,255): error -6
vi -t EAGAIN
9 #define ENXIO 6 /* No such device or address */
注意: 需要安装两个包
libncurses5-dev (关系到 menuconfig的图形界面)
sudo apt-get install uboot-mkimage uboot-mkimage(关系到uImage的格式)
make menuconfig 窗口不能太小
系统移植第四天
内核移植
根据自己的硬件,修改配置,生成对应的内核镜像
目录
平台相关: arch cpu平台的支持
其他重要的目录:
【非常具有参考价值-- 内核man手册】Documentation
【驱动参考宝典】driver 包含 驱动源码 和 Makefile
例如:
linux-3.14/drivers/usb/serial 目录下有 ch341.c 而同目录的Makefile有
16 obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o
本质: ch341将会编译生成 ch341.o 最后加入到 内核镜像内
同目录内 有一个 Kconfig(菜单)
99 config USB_SERIAL_CH341
100 tristate "USB Winchiphead CH341 Single Port Serial Driver"
101 help
102 Say Y here if you want to use a Winchiphead CH341 single port
103 USB to serial adapter.
104
105 To compile this driver as a module, choose M here: the
106 module will be called ch341.
tristate state 状态 tri- 三个 是,否,模块
对应的右bool 是还是否
–》 重新编译内核
(1)make mrproper
(2)修改Makefile arm arm-none-linux-gnueabi- 注意末尾不要加空格
(3)拷贝 cp ./arh/arm/configs/exynos-defconfig ./.config
(4) make menuconfig 退出选yes
.config 被修改了
.config 给 Makefile 是用来生成 uImage的菜谱以及注意事项
(5)make uImage -j8 (8是核心数)
生成的文件 uImage 在 arch/arm/boot/uImage
生成过程:
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-3.14.0
Created: Mon Sep 10 09:44:30 2018
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2756512 Bytes = 2691.91 kB = 2.63 MB
Load Address: 40008000
Entry Point: 40008000
分析得出
Image --》 zImage --》 uImage
压缩的zImage 再加64k的头信息 得 uImage
命令 查看uImage的头信息
mkimage -l ./uImage
Image Name: Linux-3.14.0
Created: Mon Sep 10 09:44:30 2018
Image Type: ARM Linux Kernel Image (uncompressed)未压缩
Data Size: 2756512 Bytes = 2691.91 kB = 2.63 MB
Load Address: 40008000
Entry Point: 40008000
设备树生成
?设备树
什么是设备树
目的:硬件信息与驱动剥离 详细请见驱动部分 make dtbs
DTC arch/arm/boot/dts/exynos4210-origen.dtb
DTC arch/arm/boot/dts/exynos4210-smdkv310.dtb
DTC arch/arm/boot/dts/exynos4210-trats.dtb
DTC arch/arm/boot/dts/exynos4210-universal_c210.dtb
DTC arch/arm/boot/dts/exynos4412-odroidx.dtb
DTC arch/arm/boot/dts/exynos4412-origen.dtb
DTC arch/arm/boot/dts/exynos4412-smdk4412.dtb
DTC arch/arm/boot/dts/exynos4412-tiny4412.dtb
DTC arch/arm/boot/dts/exynos4412-trats2.dtb
DTC arch/arm/boot/dts/exynos5250-arndale.dtb
DTC arch/arm/boot/dts/exynos5250-smdk5250.dtb
DTC arch/arm/boot/dts/exynos5250-snow.dtb
DTC arch/arm/boot/dts/exynos5420-arndale-octa.dtb
DTC arch/arm/boot/dts/exynos5420-smdk5420.dtb
DTC arch/arm/boot/dts/exynos5440-sd5v1.dtb
DTC arch/arm/boot/dts/exynos5440-ssdk5440.dtb
dtc 是 device tree complier 编译器 设备树编译器 拿源码 dts source 生成 dtb bin
为啥没有我们的fs4412呢?
进去找 先复制 exynos4412-origen.dts exynos4412-fs4412.dts
在顶层目录 make dtbs 依然没现象
谁的锅? dts 目录下Makefile的问题
vi 这个Makefile 匹配origen 发现没有 +=fs4412
64 dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
65 exynos4210-smdkv310.dtb \
66 exynos4210-trats.dtb \
67 exynos4210-universal_c210.dtb \
68 exynos4412-odroidx.dtb \
69 exynos4412-origen.dtb \
70 exynos4412-smdk4412.dtb \
71 exynos4412-tiny4412.dtb \
72 exynos4412-trats2.dtb \
73 exynos5250-arndale.dtb \
74 exynos5250-smdk5250.dtb \
75 exynos5250-snow.dtb \
76 exynos5420-arndale-octa.dtb \
77 exynos5420-smdk5420.dtb \
复制 origen 一行 改成 fs4412
69 exynos4412-origen.dtb \
70 exynos4412-fs4412.dtb \
再回顶层目录
make dtbs
DTC arch/arm/boot/dts/exynos4412-fs4412.dtb
----->生成成功
sudo cp uImage 和设备树到板子运行看看
--------> 发现板子挂了
开始不从 Makefile 和 .config着手 从菜单开始考虑
Linux/arm 3.14.0 Kernel Configuration ──────────────────────────────┐
│ Arrow keys navigate the menu. selects submenus ---> (or empty submenus ----). │
│ Highlighted letters are hotkeys. Pressing includes, excludes, modularizes features. │
│ Press to exit, > for Help, > for Search. Legend: [*] built-in [ ] excluded │
│ module < > module capable
y 选中 n 不选 m 是模块
?帮助 esc esc 退出 选择yes 则保存到 .config
/ 查找
我们在 make menuconfig的时候
------>在 device driver –》 character device 查到的东西 来自于目录 ./driver/char/Kconfig
8 config XIEYUXING
9 bool "XIEYUXING device support"
10 help
11 Say Y here if you want to support the xieyuxing
12 When in doubt, say "N".
从新make menuconfig 在原位置看到
[] 代表双选 Y or N --》 bool
如果我们 输入' /'匹配 XIEYUXING 则查到
Symbol: XIEYUXING [=n] │ Type : boolean │ Prompt: XIEYUXING device support │ Location: │ -> Device Drivers │ (1) -> Character devices │ Defined at drivers/char/Kconfig:8 │
----------->
esc 退出保存后 查看顶层目录的 .config1118 # Character devices 1119 # 1120 CONFIG_XIEYUXING=y
再去 driver/cha/Makefile 查看没有 xxx匹配的规则,说明我们要自己加
obj-$(CONFIG_XIEYUXING) += xxxx.o
在同目录内 编写 xxx.c
---->再回到顶层目录
make uImage显示
CHK include/config/kernel.release
CHK include/generated/uapi/linux/version.h
CHK include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h' is up to date.
CALL scripts/checksyscalls.sh
CHK include/generated/compile.h
CC drivers/char/xieyuxing.o
drivers/char/xieyuxing.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
make[2]: *** [drivers/char/xieyuxing.o] Error 1
make[1]: *** [drivers/char] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [drivers] Error 2
make: *** Waiting for unfinished jobs....
CC drivers/char/xxx.o
说明我们想添加驱动的目的达到了如果我们把char目录下Kconfig的bool修改成 tristate进入 make menuconfig 选m 则顶层目录的 .config
完成配置 内核 和设备树 实现第一天的效果
原因: 目前挂板子不成功的原因
(1)uImage 没有配置完全 网卡驱动? nfs支持?
(2)设备树? 有没有dm9000的配置?
[1] dm9000
find -name dm9000.c ./drivers/net/ethernet/davicom/dm9000.c
5 obj-$(CONFIG_DM9000) += dm9000.o
894 # CONFIG_DM9000 is not set
894 # CONFIG_DM9000 is not set
Symbol: DM9000 [=n]
│ Type : tristate
│ Prompt: DM9000 support
│ Location:
│ -> Device Drivers
│ -> Network device support (NETDEVICES [=y])
│ (1) -> Ethernet driver support (ETHERNET [=y])
│ Defined at drivers/net/ethernet/davicom/Kconfig:5
│ Depends on: NETDEVICES [=y] && ETHERNET [=y] && (ARM [=y] || BLACKFIN || MIPS || COLDFIRE)
│ Selects: CRC32 [=y] && MII [=y]
按照方法去打开每一个 选项 再拷贝 再运行 错误如下:
[ 1.435000] VFS: Cannot open root device "nfs" or unknown-block(0,255): error -6
[ 1.440000] Please append a correct "root=" boot option; here are the available partitions:
[ 1.450000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,255)
网上资料很多 ,但是如何自己思考配置 更多要借助 "/"作用
root -->
Symbol: ROOT_NFS [=n]
│ Type : boolean
│ Prompt: Root file system on NFS
│ Location:
│ -> File systems
│ (3) -> Network File Systems (NETWORK_FILESYSTEMS [=y])
│ Defined at fs/nfs/Kconfig:159
│ Depends on: NETWORK_FILESYSTEMS [=y] && NFS_FS [=n]=y && IP_PNP [=n]
然而我们找不到"Root file system on NFS" 我们在依赖上却 IP_PNP 找 IP_PNP
│ Symbol: IP_PNP [=n]
│ Type : boolean
│ Prompt: IP: kernel level autoconfiguration
│ Location:
│ -> Networking support (NET [=y])
│ -> Networking options
│ (1) -> TCP/IP networking (INET [=y])
│ Defined at net/ipv4/Kconfig:107
│ Depends on: NET [=y] && INET [=y]
选上 kernel level autoconfiguration即可
--------->找 NFS_FS
Symbol: NFS_FS [=n]
│ Type : tristate
│ Prompt: NFS client support
│ Location:
│ -> File systems
│ (1) -> Network File Systems (NETWORK_FILESYSTEMS [=y])
│ Defined at fs/nfs/Kconfig:1
│ Depends on: NETWORK_FILESYSTEMS [=y] && INET [=y] && FILE_LOCKING [=y]
│ Selects: LOCKD [=n] && SUNRPC [=n] && NFS_ACL_SUPPORT [=n]
配置好后 还有 NFS_ACL_SUPPORT没有
NFS_V3_ACL [=n] || NFSD [=n]
Symbol: NFS_V3_ACL [=n]
│ Type : boolean
│ Prompt: NFS client support for the NFSv3 ACL protocol extension
│ Location:
│ -> File systems
│ -> Network File Systems (NETWORK_FILESYSTEMS [=y])
│ -> NFS client support (NFS_FS [=y])
│ (2) -> NFS client support for NFS version 3 (NFS_V3 [=y])
│ Defined at fs/nfs/Kconfig:52
│ Depends on: NETWORK_FILESYSTEMS [=y] && NFS_V3 [=y]
下面是百度上的资料:
进入[*] Networking support --->
Networking options --->
选中[*] IP: kernel level autoconfiguration
再进入File systems --->
[*] Network File Systems --->
选中如下选项:
<*> NFS client support
<*> NFS client support for NFS version 2
<*> NFS client support for NFS version 3
[*] NFS client support for the NFSv3 ACL protocol extension
<*> NFS client support for NFS version 4
[*] Provide swap over NFS support
[*] NFS client support for NFSv4.1
[*] NFS client support for NFSv4.2
[*] NFSv4.1 client support for migration
[*] Root file system on NFS
设备树
描述板子的硬件信息 分离设备信息 和驱动
compatible 用于驱动和设备树匹配的子节点:
内存地址 地址信息 <1,2> 1:起始地址 2:偏移大小
我们如何添加 dm9000的信息 到 设备树(dts)里面去呢 ?
(1) 百度 必然要找 fs4412相关的信息 :
dm9000具体怎么设置 ,每一家板子商的寄存器地址都不一样
(2) Documentation 找找看?? 配设备树,-dm9000有关系 猜一下路径
查看
1Davicom DM9000 Fast Ethernet controller
2
3 Required properties:
4 - compatible = "davicom,dm9000";
5 - reg : physical addresses and sizes of registers, must contain 2 entries:
6 first entry : address register,
7 second entry : data register.
8 - interrupt-parent : interrupt controller to which the device is connected
9 - interrupts : interrupt specifier specific to interrupt controller
10
11 Optional properties:
12 - local-mac-address : A bytestring of 6 bytes specifying Ethernet MAC address
13 to use (from firmware or bootloader)
14 - davicom,no-eeprom : Configuration EEPROM is not available
15 - davicom,ext-phy : Use external PHY
16
17 Example:
18
19 ethernet@18000000 {
20 compatible = "davicom,dm9000";
21 reg = <0x18000000 0x2 0x18000004 0x2>;
22 interrupt-parent = <&gpn>;
23 interrupts = <7 4>;
24 local-mac-address = [00 00 de ad be ef];
25 davicom,no-eeprom;
26 };
手册建议我们要改
(1)我们要修改寄存器 Bank1 of SMC 片选 cs 1 找到 0x5000000 6个零
地址寄存器:0x5000000 数据寄存器:0x5000004 reg = <0x5000000 0x2 0x5000004 0x2>;
(2) 找中断源 INT 找到 DM9000_IRQ 找到 XEINT6
找到了 GPX0_6 估算 中断父节点 是 gpx0
(3)设置中断值 不太清楚 再去参考别人的
16 #include “exynos4412.dtsi”
参考 linux-3.14/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
13 Example:
14 interrupt-parent = <&intc1>;
15 interrupts = <5 0>, <6 0>;
69 b) two cells
70 ------------
71 The #interrupt-cells property is set to 2 and the first cell defines the
72 index of the interrupt within the controller, while the second cell is used
73 to specify any of the following flags:
74 - bits[3:0] trigger type and level flags
75 1 = low-to-high edge triggered
76 2 = high-to-low edge triggered
77 4 = active high level-sensitive
78 8 = active low level-sensitive
修改完之后从新生成
22 ethernet@5000000 {
23 compatible = "davicom,dm9000";
24 reg = <0x5000000 0x2 0x5000004 0x2>;
25 interrupt-parent = <&gpx0>;
26 interrupts = <6 4>;
27 local-mac-address = [00 00 de ad be ef];
28 davicom,no-eeprom;
29 };
------->然后
make dtbs
DTC arch/arm/boot/dts/exynos4412-fs4412.dtb
sudo cp arch/arm/boot/uImage /tftpboot/
sudo cp arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot/
529 static bool clk_ignore_unused;
修改为 static bool clk_ignore_unused=true;
-------->最后再 make uImage 拷贝到 /tftpboot 下
系统移植第五天
摄像头移植
(1)内核中的摄像头驱动 zc3xx 中星微
find . -name zc3xx.c ./drivers/media/usb/gspca/zc3xx.c
make menuconfig
┌───────────────────────────────────────── Search Results ──────────────────────────────────────────┐ │ Symbol: USB_GSPCA_ZC3XX [=n] │ Type : tristate │ Prompt: ZC3XX USB Camera Driver │ Location: │ -> Device Drivers │ (1) -> Multimedia support (MEDIA_SUPPORT [=n]) │ -> Media USB Adapters (MEDIA_USB_SUPPORT [=n]) │ -> GSPCA based webcams (USB_GSPCA [=n]) │ Defined at drivers/media/usb/gspca/Kconfig:425 │ Depends on: USB [=y] && MEDIA_SUPPORT [=n] && MEDIA_USB_SUPPORT [=n] && MEDIA_CAMERA_SUPPORT [= n
发现最后一项gspca based 没这个菜单
Symbol: USB_GSPCA [=n] │ Type : tristate │ Prompt: GSPCA based webcams │ Location: │ -> Device Drivers │ -> Multimedia support (MEDIA_SUPPORT [=y]) │ (1) -> Media USB Adapters (MEDIA_USB_SUPPORT [=y]) │ Defined at drivers/media/usb/gspca/Kconfig:1 │ Depends on: USB [=y] && MEDIA_SUPPORT [=y] && MEDIA_USB_SUPPORT [=y] && MEDIA_CAMERA_SUPPORT [=n] && VIDEO_V4L2 [=n]
找到 meida_camera_support
Symbol: MEDIA_CAMERA_SUPPORT [=n]
│ Type : boolean
│ Prompt: Cameras/video grabbers support
│ Location:
│ -> Device Drivers
│ (1) -> Multimedia support (MEDIA_SUPPORT [=y])
│ Defined at drivers/media/Kconfig:21
│ Depends on: MEDIA_SUPPORT [=y]
(2)设备树
–》 配置usb的设备树 –》重新dtc生成 设备树文件 具体参考《系统移植实验手册》
然而板子没起来
usb支持 和 摄像头的一个UVC配置
make menuconfig
Device Drivers --->
[*] USB support --->
<*> EHCI HCD (USB 2.0) support
<*> EHCI support for Samsung S5P/EXYNOS SoC Series
<*> USB Mass Storage support
<*> USB3503 HSIC to USB20 Driver
USB Physical Layer drivers --->
<*> Samsung USB 2.0 PHY controller Driver
SCSI device support --->
<*> SCSI device support
<*> SCSI disk support
<*> SCSI generic support
Device Drivers
-》Multimedia support
-》Media USB Adapters
--- Media USB Adapters │ │
│ │ *** Webcam devices *** │ │
│ │ <*> USB Video Class (UVC) │ │
│ │ [*] UVC input events device support
验证结果:
ls /dev/video0 说明成功
根文件系统 (rootfs)
1.容易混淆的概念
文件系统 : 虚拟文件系统 (VFS)
磁盘文件系统: fat fat32 ntfs 根文件系统: 操作系统锁必须的 工具,库,目录等。
概念:根文件系统(root filesystem)是存放运行、维护系统所必须的各种工具软件、库文件、脚本、配置文件和其他特殊文件的地方,也可以安装各种软件包
实质 --》 rootfs.tar.gz
busybox的作用:生成 目标机的rootfs
目的缘由: 嵌入式设备普遍存储器不大,功能单一;
信念: 只用 20%的代码 实现 80%的功能
移植rootfs
busybox
(1) tar xvf busybox
(2) cd
(3) make menuconfig
(4) 修改交叉编译器
Location: │ │ -> Busybox Settings │ │ -> Build Options BusyBox 1.22.1 Configuration
(arm-none-linux-gnueabi-) Cross Compiler prefix
linux@ubuntu:~/busybox-1.22.1$ cd _install/
linux@ubuntu:~/busybox-1.22.1/_install$ ls
bin linuxrc sbin usr
bin linuxrc sbin usr
bin dev etc lib linuxrc mjpg mnt proc root sbin sys tmp usr var www
mkdir dev etc lib mnt proc root sys tmp var
回到顶层,然后更改_install目录名
mv ./_install rootfs
mv /source/rootfs backup_rootfs
mv ./rootfs /source/
出现错误 Failed to execute /linuxrc (error -2).
缺少依赖库,交叉编译器里有
cp -arf ~/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/* /source/rootfs/lib/
能挂载 又出错误 :缺少文件夹
can’t run ‘/etc/init.d/rcS’: No such file or directory
cd /source/rootfs/etc/
mkdir init.d
touch rcS
又有 can’t run ‘/etc/init.d/rcS’: Permission denied
给权限------------->chmod 77 /source/rootfs/etc/init.d/rcS
移植sqlite3
想法?
sqlite3 是执行软件 libsqlite3 是执行库 libsqlite3-dev 含头文件的
没有arm格式,需要移植arm格式的
(1)下载 https://www.sqlite.org/2018/sqlite-autoconf-3240000.tar.gz
(2)上传到虚拟机 解压缩 tar xvf + 源码包
(3) 进入目录
./configure --host=arm-none-linux-gnueabi --prefix=/home/linux/sqlite-arm
前面的是交叉编译器
后面的是结果生成的目录
(3)vi Makefile
修改一个 -DPACKAGE_STRING=\"sqlite\ 3.24.0\"
把 3.24.0 前面的 '\'和空格删掉
(4)make
(5)make install
(6)拷贝 sqlite-arm下的bin下的sqlite3 到板子上去
板子上电 执行sqlite 是可以的
(7) sqlite-arm 下的 lib的库 拷贝过去 给 程序用
sudo cp libsqlite3.so.0.8.6 /source/rootfs/lib/
库的软链接 名字叫 libsqlite3.so.0
cd /source/rootfs/lib
ln -s libsqlite3.so.0.8.6 libsqlite3.so.0
测试:
arm-none-linux-gnueabi-gcc sqlite_test.c -lsqlite3
sqlite_test.c:6:21: fatal error: sqlite3.h: No such file or directory
compilation terminated.
找不到头文件
-I 头文件位置
-L 动态库位置
arm-none-linux-gnueabi-gcc sqlite_test.c -lsqlite3 -I /home/linux/sqlite-arm/include/ -L /home/linux/sqlite-arm/lib/