统一声明: 博客转载 声 明 : 本博客部分内容来源于网络、书籍、及各类手册。 ????????内容宗旨为方便查询、总结备份、开源分享。 ????????部分转载内容均有注明出处,如有侵权请联系博客告知并删除,谢谢! 百度云盘提取码:统一提取码: ziyu
百度云 Linux系统移植思维导图 下载链接:https://pan.baidu.com/s/1xTvwE9o8VlmnkBFh5oSOtg
一、环境搭建
1.1、嵌入式Linux开发
1.1.1、嵌入式系统定义 (1)、一般定义 以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统,对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。
(2)、广义定义 凡是带有微处理器的专用软硬件系统都可称为嵌入式系统。
(3)、特点 三低:成本、体积、功耗 三高:可靠性 安全性
1.1.2、通用嵌入式系统组成 (1)、硬件 Coretex-A9开发板: ?? 核心板:4片内存 1片EMMC ?? 外围板:外部IO
启动方式: ?? EMMC: 0111 ?? SD卡:1000
(2)、软件 无os的嵌入式系统 ?? 应用层 ?? 驱动层 ?? 硬件层 有os的嵌入式系统 ?? 应用层 ?? 内核层 ?? 驱动层 ?? 硬件层 1.1.3、基本组成与开发流层 Cross-complier:交叉编译器 --> arm-none-linux-gnueabi-gcc bootloader: u-boot kernel: 内核 rootfs: 根目录及目录下的所有文件统称根文件系统; 1.1.4、内核结构 应用层 系统调用 内核层 驱动层 硬件层
1.2、嵌入式Linux环境开发的搭建
硬件:主机、目标机、连接介质(RS232、网线、USB)
软件:交叉编译器
1.2.1、Linux环境下载与安装
转载 最新超详细VMware虚拟机下载与安装 链接:https://blog.csdn.net/qq_40950957/article/details/80467513
转载 VMware虚拟机安装Linux系统(详解版) 链接:http://c.biancheng.net/view/714.html
Ubuntu系统 下载 链接:https://cn.ubuntu.com/download
推荐:Ubuntu低版本可能不能上网下载,可以推荐我配置好的 Ubuntu 64_20.04 可上网高版本,直接解压打开使用VM打开即可。 Ubuntu 64_20.04 阿里云链接:https://www.aliyundrive.com/s/DWUDBP5KZsU Ubuntu 64_20.04 百度云链接:https://pan.baidu.com/s/1OEYYSHQ1eTVJE-iHjWb7WQ
转载 VMware Workstation Ubuntu 20.04 LTS无法连接网络问题 参考链接:https://blog.csdn.net/qq_36393978/article/details/106472278
1.2.2、安装交叉编译器
百度云盘 交叉编译器 下载链接:https://pan.baidu.com/s/1E05MEdMvoUXh7S6ii7Nb-g
详情可参考上一章 《ARM系统移植 》5.3.1、环境搭建及第一个汇编 链接地址:https://blog.csdn.net/qq_43498137/article/details/119761322
(1)、解压交叉编译器到工作目录 解压命令: tar -xvf gcc-4.6.4.tar.xz
(2)、添加交叉编译器到环境变量 vi /etc/bash. bashrc 最后一行添加: export PATH=$PATH:/home/hqyj/gcc-4.6.4/bin
(3)、生效命令 source /etc/bash. bashrc
(4)、验证是否搭建成功 arm-linux-gcc -v
1.2.2、tftp 【服务器 -> Ubuntu端】
(1)、下载安装tftp服务器 需要高版本可上网的Ubuntu,才可下载 sudo apt-get install tftpd-hpa (2)、验证 vi /etc/default/tftpd-hpa 有内容证明成功了 (3)、修改tftp服务器的配置文件 sudo vi /etc/default/tftpd-hpa 1 # /etc/default/tftpd-hpa 2 3 TFTP_USERNAME=“tftp” 4 TFTP_DIRECTORY="/home/hqyj/tftpd" ??//指定tftp服务器的目录;自己创建的路径 5 TFTP_ADDRESS=“0.0.0.0:69” 6 TFTP_OPTIONS="-l -c -s" 修改好之后保存并提出即可:wq
(4)、重启服务 sudo service tftpd-hpa restart
【客户端 -> 开发板】
(1)、查看服务器端网络接口命令: ifconfig (2)、开发板串口连接电脑
如果未显示端口或者读取不出端口号,可能未安装驱动 或 更新。 阿里云 串口驱动 下载链接:https://www.aliyundrive.com/s/NdJPk7ygj1F
(3)、打开串口工具
百度云 超级终端 下载链接:https://pan.baidu.com/s/12uwJeO1fOHJXsegW4K98uQ
(4)、启动 开发板网络接口(网线)连接上电脑接口(网线) 选择开发板启动模式 ,(我这里选择的是TF/SD模式 下启动) 启动开发板:打开开发板电源开关,迅速按电脑ENTER键 (电脑任意键都可以),否则会进入Linux系统 (5)、打印环境信息:pri (6)、设置参数的:set 设置开发板的ip:set ipaddr 192.168.7.210 ????????/* ip可自行设置 */ 设置服务器(Ubuntu)的ip:set serverip 192.168.7.28 ?? /*需要与服务器(Ubuntu ip一样),Ubuntu 查看命令:ifconfig */ 设置网关:set gatewayip 192.168.7.1 ????????? /*ip可自行设置 */ 设置子网掩码:set netmask 255.255.255.0 ???????/*需要与服务器(Ubuntu ip一样),Ubuntu 查看命令:ifconfig */ 保存:save (7)、测试服务器和客户端网络是否ping通 ping [服务器地址ip] eg:ping 192.168.7.28 若ping通,则显示下列信息: host 192.168.7.28 is alive
百度云 myled.bin 源文件下载链接:https://pan.baidu.com/s/1YLlUAIGiEHpbn4j7bIfcng
(8)、下载 文件 tftp 0x41000000 [文件名]
(9)、运行 go 41000000 补充:删除多余的设置 1.2.4、nfs配置 nfs配置见本章:4.1、【NFS】 网络文件系统
1.2.5、开发板烧写系统 下载内核(uImage) 、设备树(exynos4412-fs4412.dtb)、根文件系统(ramdisk.img)
(1)、测试服务器和客户端网络是否ping通 详细步骤参考上一节 (2)、下载 下载没有顺序要求,启动运行必须有要求。 把三个烧写系统源文件放在自己创建的服务器(Ubuntu)文件夹下
百度云 三个烧写系统源文件 下载链接:https://pan.baidu.com/s/1SYGyCBFaPvX7nQ_dFRD7qQ
下载内核:tftp 41000000 uImage 下载设备树:tftp 42000000 exynos4412-fs4412.dtb 下载根文件系统:tftp 43000000 ramdisk.img (3)、启动 启动顺序:1.下载内核(uImage) -> 2.根文件系统(ramdisk.img) -> 3.设备树(exynos4412-fs4412.dtb) 启动运行:bootm 41000000 43000000 42000000 补充:启动失败的可能原因及解决办法 解决方法 :set bootargs root=/dev/ram rw console=ttySAC2,115200 init=/linuxrc clk_ignore_unused
1.2.6、编译生成的可执行文件下载到开发板 实现在ubuntu编辑c文件并编译,将编译生成的可执行文件下载到开发板运行
【Ubuntu】 (1)、新建一个 .c文件 创建文件: vi hello.c 编译文件:arm-none-linux-gnueabi-gcc hello.c ????? arm-linux-gcc hello.c 拷贝文件:cp a.out /home/hqyj/tftpd ?? //拷贝到自己创建的服务器文件夹位置 补充:Linux下给文件权限 【开发板】 (1)、给开发板设置ip ifconfig eth0 192.168.7.123 ?? //ip可自定义 (2)、测试开发板与ubuntu是否网络连通 服务器(ubuntu) ip 测试开发板与ubuntu是否网络连通: ping 192.168.7.28 从服务器下载可执行文件: tftp -g -r a.out 192.168.7.28 (3)、运行可执行程序 给权限:chmod 777 a.out 运行:./a.out
1.3、GNU命令
1.3.1、readelf 显示elf格式可执行文件的信息
1.3.2、as 功能类似:gcc -c
1.3.3、size size列出目标文件每一段的大小以及总体的大小
eg:
size a.out
text data bss dec hex filename
1526 600 8 2134 856 a.out
1.3.4、strip / arm-linux-strip --> 重点 用来丢弃目标文件中的全部或者特定符号,减小文件体积
eg:
gcc main.c
objdump -Sl a.out > t_g
strip a.out
objdump -Sl a.out > t_s
1.3.5、objdump / arm-linux-objdump --> 重点 将二进制文件反汇编成汇编文件
eg:
gcc -g main.c
sudo dmesg -c
./a.out
dmesg
objdump -Sl a.out > t
1.3.6、objcopy/arm-linux-objcopy --> 重点 将elf格式文件转bin格式
eg:
objdump -O binary -S start.elf start.bin
1.3.7、addr2line 通过指令地址定位到指令的行号
二、U-Boot
Das U-Boot 是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括PPC、ARM、AVR32、MIPS、x86、68k、Nios与MicroBlaze。这也是一套在GNU通用公共许可证之下发布的自由软件。
2.1、Bootloader 简介
2.1.1、Bootloader 概念
-
Bootloader是硬件启动的引导程序,是运行操作系统的前提 -
在操作系统内核或用户应用程序运行之前运行的一小段代码。 对软硬件进行相应的初始化和设定,为最终运行操作系统准备好环境; -
在嵌入式系统中,整个系统的启动加载任务通常由 Bootloader来完成。
2.1.2、Bootloader 特点
- Bootloader不属于操作系统,一般采用汇编语言和语言开发。
- 在移植系统时,首先为开发板移植 Bootloader。
- Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。
- 定制化。
2.1.3、操作模式 (1)、自启动 适用于后期的开发人员 (内核 应用)
(2)、交互模式 使用u-boot移植的人员
2.1.4、Bootloader 两个阶段 (1)、第一个阶段:汇编阶段
- 初始化基本的硬件(内存 时钟 …)
- 把 bootloader 自搬运到内存中;
- 设置堆栈指针并将bss段清零。为后续执行C代码做准备;
- 跳转到第二阶段代码中
(2)、第二个阶段:c阶段
- 初始化本阶段使用到的硬件(串口 gpio 网卡 …)
- 等待命令
- 执行命令
2.1.5、Bootloader 分类 GRUB:适用于x86平台 装双系统Ware
u-boot:受众广适用于各大平台
2.2、U-Boot 特点
代码结构清晰、易于移植(见目录结构) 支持多种处理器体系结构(见arch目录) 支持众多开发板(目前官方包中有200多种,见board目录) 命令丰富 --> 例如:set pri 支持网络协议 --> 例如:tftp网络协议 支持文件系统
2.3、U-Boot 命令
显示所有环境变量:pri / printenv
设置新的环境变量:set / setenv ?? |–> set ipaddr 192.168.1.100
保存环境变量的值:save / saveenv
通过网络下载程序:tftp ?? |–> tftp 地址 文件名 eg: tftp 0x4000000 uImage
通过串口 kermit办议下载二进制数据:loadb ?? |–> loadb 0x4000000
movi 命令(不是 Ubuntu命令) ?? |–> movi read/write kernel/uboot 内存地址 ?? |–> movi write rootfs addr size 写roofs到EMMC
自启动命令:bootcmd ??|–> set bootcmd tftp 41000000 uImage;tftp 42000000 exynos4412-fs4412.dtb;tftp 43000000 ramdisk.img;bootm 41000000 43000000 42000000 ?? bootm kernel-addr ramdisk-addr dtb-addr
给内核传递启动参数:bootargs ?? |–> bootargs root=/dev/ram rw console=ttySAC2,115200 init=/linuxrc clk_ignore_unused ???? |–> root=/dev/ram 根文件系统运行在内存 ???? |–> rw 根文件系统可读可写 ???? |–> console 串口2 ???? |–> init 进程为/linuxrc
SD – EMMC切换 SD卡:(1000) ?? tftp 0x40000000 u-sd.bin ?? movi write u-boot 0x40000000 EMMC:(0111) ?? 上电看效果
2.4、U-Boot 移植
【准备】 2.4.1、明确需求 将内核加载起来即可
2.4.2、准备:资料 uboot下载地址:ftp://ftp.denx.de/pub/u-boot/ 下载适合的即可,我下载的版本是:u-boot-2013.10.tar.bz2
解压命令:tar -xvf u-boot-2013.01.tar.bz2 2.4.3、uboot支不支持芯片 (1) 、支持: goto 4 (2) 、不支持: 下最新的uboot 芯片厂商 老板
2.4.4、uboot支不支持板子 (1)、 支持: goto 5 (2)、 不支持: 找最近的uboot 板子厂商要 借鉴:同芯片的板子
2.4.5、uboot启动流程 (1)、找入口地址 ?? Makefile -> 链接脚本(arch/arm/cpu/u-boot.lds) -> start.S(_start)(arch/arm/cpu/armv7/start.S) ???? |–>_start ?????? |–> 切换cpu模式为SVC 关中断 设置向量表 ?????? |–> bl cpu_init_cp15(关MMU caches) ?????? |–> bl cpu_init_crit ???????? |–> b lowlevel_init (board/samsung/fs4412/lowlevel_init.S) ???????? ?? |–>if(uboot is not ram) ???????? ???? |–> 初始化时钟 初始化内存
???????? ?? |–> bl uart_asm_init (串口初始化) ???????? ?? |–> bl tzpc_init (trust zone初始化:保存比较重要的数据) ?????? |–>bl _main (arch/arm/lib/crt0.S ) ???????? |–> 设置堆栈 清空bss ???????? |–>board_init_r (arch/arm/lib/board.c) ???????? ?? |–> 各种设备的初始化(电源 串口 中断 网络 控制台 日志…) ???????? ?? |–>死循环 ???????? ???? for ( ; ; ) ???????? ???? { ???????? ?????? main_loop(); //等待命令 执行命令 ???????? ???? }
2.4.6、移植 (1)、借鉴:同芯片的板子(origen) ?? cp -a board/samsung/origen/ board/samsung/fs4412/ ?? cp include/configs/origen.h include/configs/fs4412.h
(2)、在Makefile中指定交叉编译头
#ifeq ($(HOSTARCH),$(ARCH))
185 CROSS_COMPILE ?= arm-none-linux-gnueabi-
186 #endif
编译文件:arm-none-linux-gnueabi-gcc hello.c
??? ?arm-linux-gcc hello.c
(3)、make distclean //清除其他板子生成的文件 ?? 清除一次即可
(4)、make fs4412_config ?? vi boards.cfg 添加我们自己的板子 ???? |–> fs4412 arm armv7 fs4412 samsung exynos (5)、make //编译
2.4.7、将u-boot.bin拷贝到tftp目录 cp u-boot.bin /home/farsight/tftpboot
2.4.8、SD卡烧写
百度云 SD卡烧写文件 下载链接:https://pan.baidu.com/s/1cDCGik_aj68Z2PgAbGUIjA
(1)、将sd卡插入电脑pc端 (2)、将sd卡格式化 (2)、烧写系统 2.4.9、验证 SD卡启动: ?? tftp 0x41000000 u-boot.bin ?? tftp 0x41000000 u.bin ?? movi write uboot 0x41000000 断电切换启动方式到EMMC,上电。
2.4.10、将tftp下载到板子,看效果 【现象】 板子变板砖。。。
【原因】 硬件:利用测试工具测试硬件 --> 没有问题 软件: ?? 死循环 ?? 程序没有执行 ?? …
【验证】
百度云 系统移植代码 下载链接:https://pan.baidu.com/s/1m3NV9BkLtGngXyXvk19N5g
点灯大法 在程序最开始位置点灯(arch/arm/cpu/armv7/start.S)添加点灯程序:
ldr r1,=0x11000c40
ldr r2,[r1]
bic r2,#0xf0000000
orr r2,#0x10000000
str r2,[r1]
ldr r1,=0x11000c44
ldr r2,[r1]
orr r2,#0x80
str r2,[r1]
【现象】 板子依然是板砖。。。
百度云 booting sequence 下载链接:https://pan.baidu.com/s/1tJcVGNIjm3FyqlwpEG_rMg
Ubuntu 没有执行 --> booting sequence (芯片手册) ?? |–> 先执行iROM,简单的初始化,例如:时钟 内存 ?? |–> iROM将1BL1加载到SRAM(内部256k内存)中执行,并做check校验,BL1做芯片级的初始化 ?? |–> BL1将BL2加载到SRAM中执行,BL2做DRAM的初始化,例如:DRAM的初始化 ?? |–> BL2将u-boot.bin加载DRAM中执行 BL1:由Samsung 提供,一般由芯片厂商提供 BL2:Samsung 不提供,一般由板子厂商提供
SD卡启动: ?? 512B + BL1(8k) + BL2(16k) + u-boot.bin EMMC启动: ?? BL1(8k) + BL2(16k) + u-boot.bin
【验证】 修改 编译 将BL1+BL2+u-boot.bin --> u.bin
SD卡启动 --> tftp 41000000 u.bin -> movi write uboot 41000000 -> EMMC启动
【现象】 板子上的灯终于亮了。。。。但在闪烁,表示板子在重启
百度云 系统移植点亮LED 源代码下载链接:https://pan.baidu.com/s/1dac3smdsiv9idJ_PBA9z5Q
【分析】 (1)、异常(野指针 段错误…) (2)、看门狗 --> 关 板子还是复位 (3)、复位 <- 电源模块 <- 接收到了复位信号 <- 谁发送复位信号给电源模块 ?? 解决:不让电源模块接收手动复位信号 --> ONO拉高 --> GPX0_2管脚拉高
百度云 S5M8767A01 / 数据手册 下载链接:https://pan.baidu.com/s/1BO1z0N8QTvUZxagNxxK7ZQ
在start.S添加以下代码:
ldr r1,=0x11000c00
ldr r2,[r1]
bic r2,#0xf00
orr r2,#0x100
str r2,[r1]
ldr r1,=0x11000c04
ldr r2,[r1]
orr r2,#0x4
str r2,[r1]
【现象】 LED 常亮,不闪烁了! 板子终于不复位了,但是串口没显示。。。
【分析】 串口没有显示的原因: ?? 硬件:没问题 ?? 软件: ?? ?? 1)、串口初始化不成功 ?? ?? 2)、波特率不是115200bps
【验证】 (1)、查看初始化有没有有问题 vi board/samsung/fs4412/lowlevel_init.S
uart_asm_init:
ldr r7, =EXYNOS4_GPIO_PART1_BASE --> 0x11400000
mov r0, r7 --> r0 = 0x11400000
ldr r1, =EXYNOS4_GPIO_A0_CON_VAL --> r1 = 0x22222222
str r1, [r0, #EXYNOS4_GPIO_A0_CON_OFFSET] --> *(0x11400000) = 0x22222222
ldr r1, =EXYNOS4_GPIO_A1_CON_VAL --> r1 = 0x222222
str r1, [r0, #EXYNOS4_GPIO_A1_CON_OFFSET] --> *(0x11400020) = 0x222222
ldr r0, =EXYNOS4_UART_BASE --> r0 = 0x13800000
add r0, r0, #EXYNOS4_DEFAULT_UART_OFFSET --> r0 = 0x13800000+0x020000 = 0x13820000
ldr r1, =ULCON_VAL --> r1 = 0x3
str r1, [r0, #ULCON_OFFSET] --> *(0x13820000) = 0x3
ldr r1, =UCON_VAL --> r1 = 1 << 9 | 1 << 8 | 1 << 7 | 1 << 6 | 1 << 2 | 1 << 0
str r1, [r0, #UCON_OFFSET] --> *(0x13820004) = r1
ldr r1, =UFCON_VAL --> r1 = 1<<8 | 1<<4 | 1<<0
str r1, [r0, #UFCON_OFFSET] -->*(0x13820008) = r1
ldr r1, =UBRDIV_VAL --> 0x35
str r1, [r0, #UBRDIV_OFFSET] --> *(0x13820028)
ldr r1, =UFRACVAL_VAL --> 0x4
str r1, [r0, #UFRACVAL_OFFSET] --> *(0x1382002c)
(2)、看波特率是否是115200bps --> 确定时钟为100MHZ --> 确定时钟源+分频值
ldr r0, =EXYNOS4_CLOCK_BASE --> r0 = 0x10030000
ldr r1, =CLK_SRC_PERIL0_VAL --> r1 = 6<<8
ldr r2, =CLK_SRC_PERIL0_OFFSET --> r2 = 0xC250
str r1, [r0, r2] --> *(0x1003c250) = 6<<8 时钟源:SCLKMPLL_USER_T
ldr r1, =CLK_DIV_PERIL0_VAL --> r1 = 7<<8
ldr r2, =CLK_DIV_PERIL0_OFFSET -->r2 = 0xC550
str r1, [r0, r2] -->*(0x1003c550) = 7<<8
uart时钟:
SCLK_UART2 = MOUTUART2/(UART2_RATIO + 1) = SCLKMPLL_USER_T/(7+1) = 800M/8 = 100M
【修改】 串口时钟有可能没有初始化,在 uart_asm_init(board/samsung/fs4412/lowlevel_init.S)中添加串口的时钟初始化
ldr r0, =EXYNOS4_CLOCK_BASE
ldr r1, =CLK_SRC_PERIL0_VAL
ldr r2, =CLK_SRC_PERIL0_OFFSET
str r1, [r0, r2]
ldr r1, =CLK_DIV_PERIL0_VAL
ldr r2, =CLK_DIV_PERIL0_OFFSET
str r1, [r0, r2]
同时屏蔽trustzone初始化,即: ?? @ bl tzpc_init /初始化非trustzone 而uboot里边有trustzone数据/ 【效果】 超级终端命令: ?? tftp 0x41000000 u.bin ?? movi write uboot 0x41000000
断电切换启动方式到EMMC模式,上电。 修改串口输出信息 vi board/samsung/fs4412/origen.c vi include/configs/fs4412.h 超级终端命令: ?? tftp 0x41000000 u.bin ?? movi write uboot 0x41000000
断电切换启动方式到EMMC模式,上电。
百度云 系统移植串口 源代码下载链接:https://pan.baidu.com/s/1ZjA1Us9q2uk1CMK8ADVjbw
串口能够正常显示了,但是不认识网络命令 【修改】 vi include/configs/fs4412.h ?? #undef CONFIG_CMD_PING --> #define CONFIG_CMD_PING ?? #undef CONFIG_CMD_NET --> #define CONFIG_CMD_NET 【编译看效果】 ping tftp命令认识了,但是卡住了 【分析】 >可参考 网络 文档下载链接:https://pan.baidu.com/s/1zkI4Fmh5qyKMysj5OrcBbw 网卡出问题 --> 网卡初始化出问题 --> ??? ?? |–> 死循环 ?? |–> 网卡驱动有问题 -> 网卡初始化(arch/arm/lib/board.c) ???? |–> eth_initialize(gd->bd); ?????? |–>board_eth_init(bis) (board/samsung/fs4412/origen.c定义) 借鉴其他板子 ???????? |–> dm9000_initialize(bd_t *bis) //板子的网卡初始化 【验证】 (1)、在 include/configs/fs4412.h文件中添加以下头文件
#ifdef CONFIG_CMD_NET
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x05000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
#define CONFIG_ETHADDR 11:22:33:44:55:66
#define CONFIG_IPADDR 192.168.7.213
#define CONFIG_SERVERIP 192.168.7.31
#define CONFIG_GATEWAYIP 192.168.7.1
#define CONFIG_NETMASK 255.255.255.0
#endif
(2)、在 board/samsung/fs4412/origen.c 添加以下代码 --> 借鉴其他板子
#ifdef CONFIG_DRIVER_DM9000
int board_eth_init(bd_t *bis)
{
return dm9000_initialize(bis);
}
#endif
【现象】 ping有反应了,但是报0x05000000错误 error: ?? dm9000 not found at 0x05000000 id: 0x00000000 【分析】 0x0x05000000错误 --> SROM驱动有问题 --> srom配置文件
借鉴 s59板子:
void s5p_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf)
{
u32 tmp;
struct s5p_sromc *srom =
(struct s5p_sromc *)samsung_get_base_sromc();
tmp = srom->bw;
tmp &= ~(0xF << (srom_bank * 4));
tmp |= srom_bw_conf;
srom->bw = tmp;
srom->bc[srom_bank] = srom_bc_conf;
}
static void smc9115_pre_init(void)
{
u32 smc_bw_conf, smc_bc_conf;
struct s5pc100_gpio *const gpio =
(struct s5pc100_gpio *)samsung_get_base_gpio();
s5p_gpio_cfg_pin(&gpio->k0, CONFIG_ENV_SROM_BANK, GPIO_FUNC(2));
smc_bw_conf = SMC_DATA16_WIDTH(CONFIG_ENV_SROM_BANK);
smc_bc_conf = SMC_BC_TACS(0x0) | SMC_BC_TCOS(0x4) | SMC_BC_TACC(0xe)
| SMC_BC_TCOH(0x1) | SMC_BC_TAH(0x4)
| SMC_BC_TACP(0x6) | SMC_BC_PMC(0x0);
s5p_config_sromc(CONFIG_ENV_SROM_BANK, smc_bw_conf, smc_bc_conf);
}
int board_init(void)
{
smc9115_pre_init();
gd->bd->bi_arch_number = MACH_TYPE_SMDKC100;
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
return 0;
}
跟踪: 方式1: ?? board_eth_init() ???? |–>s5p_config_sromc()
方式2:(建议) ?? board_init() --> 定义 board/samsung/fs4412/origen.c ???? |–>exynos4412_pre_init() --> 自己定义 ?????? |–>exynos4412_config_sromc() -->自己定义
【验证】 在文件 --> vi board/samsung/fs4412/origen.c 添加以下代码:
struct exynos4_gpio_part1 *gpio1;
struct exynos4_gpio_part2 *gpio2;
#ifdef CONFIG_DRIVER_DM9000
#define EXYNOS4412_SROMC_BASE 0X12570000
#define DM9000_Tacs (0x1)
#define DM9000_Tcos (0x1)
#define DM9000_Tacc (0x5)
#define DM9000_Tcoh (0x1)
#define DM9000_Tah (0xC)
#define DM9000_Tacp (0x9)
#define DM9000_PMC (0x1)
struct exynos_sromc {
unsigned int bw;
unsigned int bc[6];
};
void exynos_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf)
{
u32 tmp;
struct exynos_sromc *srom =(struct exynos_sromc *)(EXYNOS4412_SROMC_BASE);
tmp = srom->bw;
tmp &= ~(0xF << (srom_bank * 4));
tmp |= srom_bw_conf;
srom->bw = tmp;
srom->bc[srom_bank] = srom_bc_conf;
}
static void dm9000aep_pre_init(void)
{
unsigned int tmp;
unsigned char smc_bank_num = 1;
unsigned int smc_bw_conf=0;
unsigned int smc_bc_conf=0;
writel(0x00220020, 0x11000000 + 0x120);
writel(0x00002222, 0x11000000 + 0x140);
writel(0x22222222, 0x11000000 + 0x180);
writel(0x0000FFFF, 0x11000000 + 0x188);
writel(0x22222222, 0x11000000 + 0x1C0);
writel(0x0000FFFF, 0x11000000 + 0x1C8);
writel(0x22222222, 0x11000000 + 0x1E0);
writel(0x0000FFFF, 0x11000000 + 0x1E8);
smc_bw_conf &= ~(0xf<<4);
smc_bw_conf |= (1<<7) | (1<<6) | (1<<5) | (1<<4);
smc_bc_conf = ((DM9000_Tacs << 28)
| (DM9000_Tcos << 24)
| (DM9000_Tacc << 16)
| (DM9000_Tcoh << 12)
| (DM9000_Tah << 8)
| (DM9000_Tacp << 4)
| (DM9000_PMC));
exynos_config_sromc(smc_bank_num,smc_bw_conf,smc_bc_conf);
}
#endif
#ifdef CONFIG_DRIVER_DM9000
int board_eth_init(bd_t *bis)
{
return dm9000_initialize(bis);
}
#endif
int board_init(void)
{
gpio1 = (struct exynos4_gpio_part1 *) EXYNOS4_GPIO_PART1_BASE;
gpio2 = (struct exynos4_gpio_part2 *) EXYNOS4_GPIO_PART2_BASE;
#ifdef CONFIG_DRIVER_DM9000
dm9000aep_pre_init();
#endif
gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
return 0;
}
【效果】 tftp终于is alive 了 自启动: EMMC 模式下上电不管,让开发板自启动。 set bootcmd tftp 41000000 uImage; tftp 42000000 exynos4412-fs4412.dtb;tftp 43000000 ramdisk.img;bootm 41000000 43000000 42000000
百度云 本节源码链接:https://pan.baidu.com/s/19eAUK4idBExs1v_2HPWmfg
三、内核移植
3.1、linux内核
(1)、将底层硬件抽象向上提供统一的接口;
(2)、文件系统fs:将用户数据转化成文件格式存储,向下将文件转为二进制字节流存储在硬件上;
(3)、进程线程:提升性能
(4)、MMU:虚拟内存,用户不需要关心物理内存
内核官网:https://www.kernel.org/
3.2、内核移植
3.2.1、将内核源码解压 linux-3.14.tar.xz --> linux-3.14目录
百度云 linux-3.14.tar.xz 下载链接:https://pan.baidu.com/s/1ZCKoLlG4doNaC0bUoq_yVA
自己创建一个文件夹,解压在Linux下 解压命令:tar -xvf linux-3.14.tar.xz 3.2.2、目录介绍 arch:不同架构的芯片 Documentation:文档 init:内核初始化 lib:内核用到的库文件 sound:音频 block:块设备(比较重要 磁盘时块设备) driver:驱动 ipc:进程间通信方式 tools:工具 firmware:固件 -> 芯片起来之前预先烧写的东西 samples:示例 user:用户的东西 fs:文件系统 mm:内存管理 scripts:脚本文件所在目录(很有用) virt:内核的虚拟机的东西在里边 include:头文件 kernel:内核的逻辑 net:网络相关的 security:安全加密的一些东西 security:安全加密的一些东西
3.2.3、编译内核 (1)、make menuconfig //选择需要添加/删除的模块 make menuconfig 如果报错可能:1、缺库。2、把Linux窗口页面拉大一些即可。 下载库:sudo apt-get install libncurses5-dev
<Enter> 进入子菜单
---> 有子目录
<N> 不选中
<Y> 选中
</> 搜索
<ESC> 退出
(2)、修改Makefile vi Makefile ARCH ?= arm CROSS_COMPILE ?= arm-linux-
(3)、修改配置文件为ARM平台的 make exynos_defconfig //文件位置目录:(arch/arm/configs) make exynos_defconfig (4)、编译内核 make uImage 第一次编译比较久,以上编译报 【问题】 问题:“mkimage” command not found - U-Boot images will not be built ?? 解决1: ???? sudo apt-get install uboot-mkimage //安装mkimage命令 ???? sudo apt-get install u-boot-tools
?? 解决2: ???? cp u-boot-2013.01/tools/mkimage /usr/bin //将uboot中的mkimage工具添加到环境变量
???? 注意: ?????? 默认生成zImage
重新编译: make uImage (5)、拷贝uImage到tftp(服务器)目录 cp uImage /home/farsight/tftpboot cp uImage /home/hqyj/tftpd 3.2.4、编译设备树 设备树 ??树形结构描述设备
(1)、借鉴origen板子 cp exynos4412-origen.dts exynos4412-fs4412.dts (2)、添加我们自己的板子设备树到Makefile vi arch/arm/boot/dts/Makefile 在文件中添加: ?? exynos4412-fs4412.dtb (3)、编译设备树(内核主目录编译) make dtbs DTC arch/arm/boot/dts/exynos4412-fs4412.dtb (4)、拷贝exynos4412-fs4412.dtb到tftp目录 cp exynos4412-fs4412.dtb /home/farsight/tftpboot cp arch/arm/boot/dts/exynos4412-fs4412.dtb /home/hqyj/tftpd/ (5)、下载内核与设备树 板子EMMC启动
【现象】 ifconfig不能配置ip,tftp不能下载文件 【解决】 make menuconfig ?? Location: ?? -> Device Drivers ???? -> Network device support (NETDEVICES [=y]) ?????? -> Ethernet driver support (ETHERNET [=y]) ???????? |–> DM9000 (DM9000 [=y]) 保存,esc退出即可!
make uImage cp uImage /home/hqyj/tftpd
下载开发板,emmc启动
【现象】 ifconfig还是不能配置ip,tftp还是不能下载文件,驱动准备好了,设备还没有。 错误:网络不可达
【分析】 有可能没有网卡设备,借鉴:arch/arm/boot/dts/s3c6410-mini6410.dts 【解决】 在设备树添加DM9000网卡设备,vi arch/arm/boot/dts/exynos4412-fs4412.dts 添加以下代码:
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
srom-cs1@0x05000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x05000000 0x1000000>;
ranges;
ethernet@0x05000000 {
compatible = "davicom,dm9000";
reg = <0x05000000 0x2 0x05000004 0x2>;
interrupt-parent = <&gpx0>;
interrupts = <6 IRQ_TYPE_LEVEL_HIGH>;
davicom,no-eeprom;
};
};
make dtbs cp arch/arm/boot/dts/exynos4412-fs4412.dtb /home/hqyj/tftpd/ 开发板emmc启动 启动:boot uboot设置bootargs: set bootargs root=/dev/ram rw console=ttySAC2,115200 init=/linuxrc clk_ignore_unused 自动获取ip: udhcpc 下载文件:
百度云 3.2内核移植 源码下载链接:https://pan.baidu.com/s/1u-0sgAszxlkpw0f4Mf58tg
【内核自动获取ip】 set bootargs root=/dev/ram rw console=ttySAC2,115200 init=/linuxrc clk_ignore_unused ip=192.168.7.213(板子) 【自动配置ip】 make menuconfig //自动配置ip ?? |–>Networking support > Networking options > IP: kernel level autoconfiguration [ y ] 内核移植,文件可以成功下载!
四、根文件系统
4.1、【NFS】 网络文件系统
服务器端:【ubuntu】 sudo apt-get install nfs-kernel-server ??//下载安装nfs网络服务器 mkdir /home/farsight/nfs/rootfs ????//在家目录下创建nfs服务器目录
vi /etc/exports ??????????//修改配置文件 ?? /home/farsight/nfs/rootfs *(rw,sync,no_root_squash,no_subtree_check) 启动服务:sudo service nfs-kernel-server restart 解压 rootfs到nfs目录
百度云 rootfs.tar.xz 源文件下载链接:https://pan.baidu.com/s/1cnX0FJ53DawQ1h-RBIZKbw
客户端:【内核】
百度云 Linux-3.14 源码下载链接:https://pan.baidu.com/s/1u-0sgAszxlkpw0f4Mf58tg
make menuconfig
|-> File systems
|->Network File Systems
|-> <*> NFS client support
|-> [*] Root file system on NFS
make uImage cp uImage /home/farsight/tftpboot cp arch/arm/boot/uImage /home/hqyj/tftpd/ 修改bootargs/bootcmd: set bootcmd tftp 41000000 uImage;tftp 42000000 exynos4412-fs4412.dtb;bootm 41000000 - 42000000
set bootargs root=/dev/nfs nfsroot=(服务器IP)192.168.7.143:/home/farsight/nfs/rootfs(nfs目录),v3 rw console=ttySAC2,115200 clk_ignore_unused init=/linuxrc ip=192.168.7.213(板子IP) 可sd卡;emmc启动 后续不需要TFTP下载,直接就在根文件系统下
4.2、【linux系统常用调试方法】
4.2.1、内核和驱动的调试 kgdb printk --> 驱动开发里边打印用到 LED点灯大法 --> 内核最开始的代码 串口打印 --> 内核起来之前用puts或printk打印信息 ?? |–> puts ?? |–>printk 用于内核启动起来之后调试 查看日志信息工具:通过内核的日志信息查看程序出现问题的地方 ?? oops panic --> 错误报告 ?? oops异常:会导致内核异常 ?? panic异常:也会导致内核异常 硬件调试器: ?? BDI或JTAG工具调试
4.2.2、应用程序的调试 gdb printf strace:可以跟踪程序执行流程 可以跟踪到封装的库里边
4.2.3、printk有8种打印级别 分级别的原因: ?? 内核的代码为了后续定位问题方便,会加printk的打印输出,这些输出不能加太多,因为内核一直在运行,长时间之后输出的日志文件就会非常大,所以需要控制打印。 ?? 在产品发布时指定打印级别,内核就会按照级别打印,优先级比指定级别高的打印,低的不打印;
4.3、【根文件系统】
4.3.1、概念 根目录即目录下所有文件统称根文件系统;
4.3.2、目录文件遵循FHS标准 /bin /sbin /etc /lib /root /tmp /mnt linuxrc /proc 进程的信息
4.3.3、linux系统启动流程(重点)
bootloader
|
|
内核
|
|
挂载roofs
|
|
init(第三方) --> inittab --> /etc/init.d/rcS
|
|
shell(终端) 执行各种linux命令
4.3.4、inittab (/etc/inittab)–> 指定内核的行为规则 ::sysinit:/etc/init.d/rcS 指定内核执行的第一个文件 /etc/init.d/rcS ::askfirst:-/bin/sh 询问方式登录shell
4.3.5、/etc/init.d/rcS #!/bin/sh #This is the first script called by init process /bin/mount -a mkdir /dev/pts mount -t devpts devpts /dev/pts echo /sbin/mdev>/proc/sys/kernel/hotplug mdev -s
/bin/mount -a 把/etc/fstab里边的东西挂载 cat fstab ?????? |–> /sys 与 内核的 sysfs挂载起来 ?????? |–> /proc 与 内核的 proc挂载起来 ???? ssh登录需要的东西 ???? 支持设备的热插拔:usb插拔时不用重启系统
4.4、【BusyBox】制作根文件系统
百度云 busybox-1.22.1.tar.bz2 源码下载链接:https://pan.baidu.com/s/1_kcfiXMJ_P-narkdxS_eYA
(1)、解压:tar -xvf busybox-1.22.1.tar.bz2 (2)、make menuconfig ?? Busybox Settings —> ???? Build Options —> ?????? |–>[*] Build BusyBox as a static binary (no shared libs) ?????? |–> (arm-linux-) Cross Compiler prefix (3)、make 编译 (4)、make install 将.o展开成具体命令* (5)、cd _install (6)、创建文件夹:mkdir dev etc lib mnt proc root sys tmp (7)、cp /home/farsight/nfs/rootfs/etc/ etc -a //借鉴roofs下边的etc目录文件* cp -a /home/hqyj/nfs/rootfs/etc/ *./
(8)、cp /home/farsight/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/ ./ -a ** cp -a /home/hqyj/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/ ./ -a (9)、arm-none-linux-gnueabi-strip * //压缩lib的体积
百度云 根文件系统制作 源码下载链接:https://pan.baidu.com/s/1NHfkJ0qYh0bTEFOutqDd0w
4.5、【ramdisk.img <-- rootfs】
通过NFS测试以后,就可以制作 ramdisk文件系统了,具体如下:
(1)、制作一个大小为8M的镜像文件 $ cd ~ $ dd if-/dev/zero of-ramdisk bs=lk count=8192 (ramdisk 8M)
(2)、格式化这个镜像文件为ext2 $ mkfs.ext2 -F ramdisk
(3)、在 mount下面创建 initrd目录作为挂载点 $ sudo mkdir /mnt/initrd
(4)、将这个磁盘镜像文件挂载到/ mnt/initrd下 注意这里的 ramdisk不能存放在 rootfs目录中 $ sudo mount -t ext2 ramdisk /mnt/initrd
(5)、将我们的文件系统复制到 ramdisk中 将测试好的文件系统里的内容全部拷贝到/mnt/ initrd目录下面 $ sudo cp /source/rootfs/* /mnt/initrd - a
(6)、卸载 initrd $ sudo umount /mnt/initrd
(7)、压缩 ramdisk为 ramdisk.gz并拷贝到/ tftpboot下 $ gzip --best -c ramdisk > ramdisk.gz
(8)、格式化为 uboot识别的格式 $ mkimage -n “ramdisk” -A arm-O linux -T ramdisk-C gzip-d ramdisk.gz ramdisk.img $ cp ramdisk.img /tftpboot
(9)、配置内核支持 RAMDISK 制作完 ramdisk. img后,需要配置内核支持 RAMDISK作为启动文件系统
make menuconfig
File systems -->
<*> Second extended fs support
Device drivers
SCSI device support -->
<*> SCSI disk support
Block devices -->
<*>raM block device support
(16) Default number of RaM disks
(8192) Default ram disk size( kbytes)(修改为8M
General setup -->
[*]Initial RAM filesystem and ram disk (initramfs/initrd) support
重新编译内核,复制到 tftpboot
转载 制作Ramdisk文件系统 可参考链接:https://blog.csdn.net/u014213012/article/details/51582826
(10)、在U-BOOT命令行重新设置启动参数 setenv bootcmd tftp 41000000 ulmage; tftp 42000000 exynos4412-fs44 12 dtb; titp 43000000 ramdisk. img; bootm410000004300000042000000 saveenv 重新启动开发板查看能否正常启动
练习:
- /etc的 profile init.d inittab fstab写一下,参考roofs的etc
转载:/etc/inittab,/etc/init.d/rcS和/etc/profile分析 可参考链接:https://blog.csdn.net/Qiuoooooo/article/details/79300739 - rootfs做成ramdisk.img
转载:制作rootfs文件 ramdisk 可参考链接:http://blog.chinaunix.net/uid-24148050-id-95542.html
跳转:上一篇、ARM体系结构!
跳转:上一篇、ARM体系结构!
跳转:下一篇、人工智能!
待更新。。。
跳转:开头
|