文章目录

  • 一、开发环境搭建
    • 1.1 安装交叉编译工具链
    • 1.2 代码镜像烧写工具
    • 1.3 Ubuntu下所有的设备文件都在目录“/dev”里面
    • 1.4 Ubuntu 搭建TFTP服务器
    • 1.5 Ubuntu搭建NFS服务器
  • 二、u-boot编译步骤
    • 2.1 编译步骤
    • 2.2 问题
  • 三、Makefile知识点
    • 3.1 $(MAKE) -C
    • 3.2 变量传递
    • 3.3 命令含义解析
      • 3.3.1 MAKEFLAGS += -rR --include-dir=$(CURDIR)
      • 3.3.2 $(origin V)
      • 3.3.3 ifeq ("$(origin V)", "command line")
      • 3.3.4 @控制make中的命令会不会被输出在终端
      • 3.3.5 $(filter

一、开发环境搭建

1.1 安装交叉编译工具链

见另一篇博客《Linux安装交叉编译工具链》

1.2 代码镜像烧写工具

imxdownload :注意需要将imxdownload工具拷贝到工程根目录下,否则会烧写失败

1.3 Ubuntu下所有的设备文件都在目录“/dev”里面

插上 SD 卡以后,SD设备卡会出现在“/dev”里面,其中存储设备都是以“/dev/sd”开头的。

1.4 Ubuntu 搭建TFTP服务器

见另一篇博客《Linux搭建NFS服务器》

1.5 Ubuntu搭建NFS服务器

见另一篇博客《Linux搭建TFTP服务器》

二、u-boot编译步骤

2.1 编译步骤

  1. 官网下载u-boot源码
  2. Linux安装必要库
  3. 进入源码顶层目录执行编译命令,可以写一个sh脚本
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12

2.2 问题

  1. 怎么确定u-boot编译命令该用什么命令?如上述3条命令。所有的芯片都是统一的吗?
    ​参数一:mx6ull_14x14_ddr512_emmc_defconfig
    ​ 来自u-boot源码中configs目录中的配置文件名。半导体厂商出场的时候为了简化开发人员的开发难度,会配置很多开发板的一套默认配置,在configs目录下,对应的芯片使用对应的配置文件即可。
    参数二:-j12
    ​ 表示12个线程都进行编译,一般系统支持几核几线程线程可以根据需要设置,满线程时,编译速度最快。
    参数三:V=1
    在终端中输出短命令虽然看起来很清爽,但是不利于分析uboot的编译过程。可以通过设置变量“V=1“来实现完整的命令输出

三、Makefile知识点

3.1 $(MAKE) -C

​ makefile中递归嵌套调用makefile。参数-C指定子目录。

3.2 变量传递

​ export VARIABLE …… //导出变量给子 make 。
​ unexport VARIABLE…… //不导出变量给子 make。
​ 备注:
​ 有两个特殊的变量:“SHELL”和“MAKEFLAGS”,这两个变量除非使用“unexport”声明,否则的话在整个make的执行过程中,它们的值始终自动的传递给子make。

3.3 命令含义解析

3.3.1 MAKEFLAGS += -rR --include-dir=$(CURDIR)

​ +=”来给变量 MAKEFLAGS 追加了一些值
​ “-rR”表示禁止使用内置的隐含规则和变量定义
​ “–include-dir”指明搜索路径
​ “$(CURDIR)”表示当前目录

3.3.2 $(origin V)

​ 函数origin,表示获取变量V的来源

3.3.3 ifeq ("$(origin V)", “command line”)

ifeq ("$(origin V)", "command line")KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSEKBUILD_VERBOSE = 0
endif

​ 函数origin,表示变量V的来源,此句话表示变量V是否来自command line。
​ 前面命令行输入的编译命令有V=1,所以这里KBUILD_VERBOSE = 1,如果命令行没有V=1,则KBUILD_VERBOSE = 0

3.3.4 @控制make中的命令会不会被输出在终端

​ make在执行的时候默认会在终端输出命令,但是在命令前面加上“@”就不会在终端输出命令了。

3.3.5 $(filter <pattern…>, <text>)

​ filter 函数表示以 pattern 模式过滤 text 字符串中的单词,仅保留符合模式 pattern 的单词

3.3.6 make参数

​ O 表示指定的make工具输出目录
​ C 表示检查代码,C=1表示检查需要重新编译的文件,C=2表示检查所有源码文件

3.3.7 模块编译

​ make M=dir或make SUBDIRS=dir进行模块编译

3.3.8 sed命令

​ sed -e 表示替换命令

3.3.9 编译命令

​ 每次编译uboot的时候都要在make命令后面设置ARCH和CROS_COMPILE,使用起来很麻烦,可以直接修改顶层Makefile,在里面加入ARCH和CROSS_COMPILE的定义。


四、U-Boot中添加自己的板卡型号

4.1 拷贝类似平台的配置文件,重命名为自己平台的名字

​ cd configs
​ cp xxxx_defconfig dest_defconfig
​ 修改里面内容为自己板卡的名字

4.2 拷贝类似平台头文件,重命名为自己平台的头文件

​ cd include/configs/
​ cp xxxx.h dest.h
​ 修改里面#ifdef后面的名字为自己板卡的名字

4.3 添加对应板级文件夹

​ cd board/freescale/
​ cp xxx/ dest_board_dir_name -rf
​ 修改原板卡.c文件为目标板卡.c文件
​ cd dest_board_dir_name
​ mv xxx.c dest_board_name.c

4.4 修改图形界面配置文件

​ 当make menuconfig时配置选项中的可选项

4.5 编译u-boot(推荐仍旧使用shell脚本写入命令)

4.6 网络驱动修改

4.6.1 基本概念

  1. 部分芯片内部有个mac外设,mac外设单独无法工作,需要外接PHY芯片。即:内部mac+外部PHY。(通信速度快)

    部分芯片内不没有mac外设,会采用DM9000网络连接。DM9000芯片相当于:外部MAC+外部PHY。(通信速度慢)

  2. imx6ul芯片手册 22章ENET章节,讲解MAC具体细节

4.6.2 LAN8720A芯片

  1. LAN8720A芯片有个管理接口MDIO,包含两根线:MDIO和MDC。一个MDIO接口可以管理32个PHY芯片。
  2. 芯片addr(即:芯片ID),在芯片手册中可以查到,PHYAD0引脚是否上拉决定地址。
  3. 每个芯片都有一个复位引脚。
  4. 所有PHY芯片,其前16个寄存器一模一样,所以u-boot中已经写好了通用PHY驱动,所一般代码无需修改,可以直接使用。
  5. 芯片操作方法:查手册,待补充

4.6.3 移植PHY芯片驱动,u-boot源码修改步骤

  1. 看电路图,查询PHY芯片地址:0x0/0x1等

  2. 看电路图,查询PHY芯片复位引脚接的ARM哪个GPIO引脚

  3. 打开u-boot中上面步骤复制的对应板卡的.h文件,找到NET相关的宏配置,主要修改两个宏:

    ​ CONFIG_FEC_ENET_DEV 表示使用哪一个LAN口设备

    ​ CONFIG_FEC_MXC_PHYADDR 表示PHY芯片的地址

  4. 打开u-boot中上面步骤复制的对应板卡的.c文件,删除原有网络芯片(74LV595 )的驱动代码。并且添加对应板卡的控制代码,包括:define宏定义RESET复位引脚对应GPIO口、引脚配置代码等。

  5. 仍旧是.c文件,找到结构体数组fec1_pads、fec2_pads为两个网口的IO配置参数,在数组末尾添加拉你个网口的复位IO配置参数

  6. 仍旧是.c文件,添加网络复位IO初始化代码

  7. 添加LAN芯片软复位代码,文件:drivers/net/phy/phy.c 中的函数genphy_update_link

4.7 bootcmd和bootargs环境变量

4.7.1 bootcmd

​ bootcmd 保存着 uboot 默认命令, uboot 倒计时结束以后就会执行 bootcmd 中的命令。这些命令一般都是用来启动 Linux 内核的,比如读取 EMMC 或者 NAND Flash 中的 Linux 内核镜像文件和设备树文件到 DRAM 中,然后启动 Linux 内核。

​ 可以在 uboot 启动以后进入命令行设置 bootcmd 环境变量的值 ,命令如下:

setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000;'

4.7.2 bootargs

​ bootargs 保存着 uboot 传递给 Linux 内核的参数。 bootargs设置命令如下:

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'

​ bootargs 就是设置了很多的参数的值,这些参数 Linux 内核会使用到,常用的参数有:

​ 1. console

​ console 用来设置 linux 终端(或者叫控制台),也就是通过什么设备来和 Linux 进行交互,是串口还是 LCD 屏幕。

​ 2. root

​ root 用来设置根文件系统的位置, root=/dev/mmcblk1p2 用于指明根文件系统存放在mmcblk1 设备的分区 2 中。

​ 3. rootfstype

​ 此选项一般配置 root 一起使用, rootfstype 用于指定根文件系统类型

4.8 网络文件系统(网络挂载启动)

为了方便调试,可以使用网络挂载启动的方式,通过tftp或者nfs服务器进行系统启动,只需要如下几步即可:

  1. 配置tftp和nfs服务器
  2. 拷贝dtb文件和zImage文件到tftp服务器目录下
  3. 拷贝linux内核到nfs服务器目录下
  4. 设置环境变量bootargs和bootcmd为tftp模式下载设备树和zImage。

设置环境变量bootargs和bootcmd命令如下:

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000'
saveenv

五、Linux内核

5.1 编译Linux内核步骤

  1. 下载Linux内核镜像

  2. 顶层目录Makefile中配置交叉编译工具链,或者直接编写编译sh脚本在命令中附上交叉编译工具链。

    make disclean 清理工程,如果有修改配置文件,慎用该命令

    make xxx_defconfig 配置工程

    make menuconfig 打开图形界面,配置Linux(如果不需要配置linux,可以删掉该命令)

    make 编译Linux源码

  3. arch/arm/boot 目录下 zImage为Linux镜像文件

  4. arch/arm/boo/dts 目录下 .dtb文件为设备树文件

5.2 Linux内核源码工程目录结构

  1. arch 架构相关目录
  2. drivers 驱动相关目录
  3. include 头文件相关目录
  4. kenel 内核相关目录
  5. lib 库相关目录
  6. .config Linux最终使用的配置文件
  7. Kconfig 图形化界面配置文件

5.3 顶层Makefile详解

​ 基本和 uboot 的顶层 Makefile 一样,重点在于vmlinux 的生成。最后将 vmlinux 压缩成我们最常用的 zImage 或 uImage 等文件。

5.4 Linux内核启动流程

  1. Linux内核链接脚本文件:arch/arm/kernel/vmlinux.lds ,该文件可以找到Linux内核第一行程序从哪里执行。

    脚本文件中493行ENTRY(stext) 代码指定内核入口为stext,stext 定义在文件arch/arm/kernel/head.S 中 。

  2. 函数__lookup_processor_type 检查当前系统是否支持此 CPU ,其中一个结构体proc_info_list 保存支持的CPU信息。proc_info_list 在文件 arch/arm/include/asm/procinfo.h 中

  3. Linux 内核最终是需要和根文件系统打交道的,需要挂载根文件系统,并且执行根文件系统中的 init 程序,以此来进去用户态

ps -A:列出当前所有运行的进程

5.5 Linux内核移植

5.5.1 移植步骤

  1. 顶层Makefile修改交叉编译工具链

  2. 配置内核、编译内核,生成zImage 、.dtb(设备树) 文件。

    zImage路径:arch/arm/boot
    .dtb  路径:arch/arm/boot/dts
    
  3. 将上述两个文件拷贝到tftp服务器目录下,后面u-boot下载要用

  4. 从tftp服务器下载镜像emmc中

    tftp 80800000 zImage
    tftp 83000000 xxx.dtb
    
  5. 启动内核

    bootz 80800000 - 83000000
    

5.5.2 内核移植:在 Linux 中 添加自己的开发板

  1. 拷贝类似平台配置文件为自己开发板的配置文件

    cd arch/arm/configs
    cp xxx_defconfig 自己开发板名字_defconfig
    
  2. 拷贝开发板对应设备树文件

    cd arch/arm/boot/dts
    cp xxx_dts 自己的开发板名字.dts
    
  3. 修改makefile

    vim arch/arm/boot/dts/Makefile
    

    在dtb-$(CONFIG_SOC_IMX6ULL) 配置项中加入自己的开发板对应的设备树名称

  4. 顶层目录下创建编译脚本

    #!/bin/sh
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
    
  5. 赋予可执行权限

    chmod 777 imx6ull_alientek_emmc.sh
    
  6. 编译

    ./imx6ull_alientek_emmc.sh
    
  7. 拷贝zImage 、.dtb(设备树) 文件到tftp服务器目录中,使用tftp工具下载zImage和dtb设备树文件

    tftp 80800000 zImage
    tftp 83000000 imx6ull-alientek-emmc.dtb
    bootz 80800000 – 83000000
    

《正点原子嵌入式linux驱动开发指南V1.4》学习笔记相关推荐

  1. 第二行代码学习笔记——第六章:数据储存全方案——详解持久化技术

    本章要点 任何一个应用程序,总是不停的和数据打交道. 瞬时数据:指储存在内存当中,有可能因为程序关闭或其他原因导致内存被回收而丢失的数据. 数据持久化技术,为了解决关键性数据的丢失. 6.1 持久化技 ...

  2. 第一行代码学习笔记第二章——探究活动

    知识点目录 2.1 活动是什么 2.2 活动的基本用法 2.2.1 手动创建活动 2.2.2 创建和加载布局 2.2.3 在AndroidManifest文件中注册 2.2.4 在活动中使用Toast ...

  3. 第一行代码学习笔记第八章——运用手机多媒体

    知识点目录 8.1 将程序运行到手机上 8.2 使用通知 * 8.2.1 通知的基本使用 * 8.2.2 通知的进阶技巧 * 8.2.3 通知的高级功能 8.3 调用摄像头和相册 * 8.3.1 调用 ...

  4. 第一行代码学习笔记第六章——详解持久化技术

    知识点目录 6.1 持久化技术简介 6.2 文件存储 * 6.2.1 将数据存储到文件中 * 6.2.2 从文件中读取数据 6.3 SharedPreferences存储 * 6.3.1 将数据存储到 ...

  5. 第一行代码学习笔记第三章——UI开发的点点滴滴

    知识点目录 3.1 如何编写程序界面 3.2 常用控件的使用方法 * 3.2.1 TextView * 3.2.2 Button * 3.2.3 EditText * 3.2.4 ImageView ...

  6. 第一行代码学习笔记第十章——探究服务

    知识点目录 10.1 服务是什么 10.2 Android多线程编程 * 10.2.1 线程的基本用法 * 10.2.2 在子线程中更新UI * 10.2.3 解析异步消息处理机制 * 10.2.4 ...

  7. 第一行代码学习笔记第七章——探究内容提供器

    知识点目录 7.1 内容提供器简介 7.2 运行权限 * 7.2.1 Android权限机制详解 * 7.2.2 在程序运行时申请权限 7.3 访问其他程序中的数据 * 7.3.1 ContentRe ...

  8. 第一行代码学习笔记第五章——详解广播机制

    知识点目录 5.1 广播机制 5.2 接收系统广播 * 5.2.1 动态注册监听网络变化 * 5.2.2 静态注册实现开机广播 5.3 发送自定义广播 * 5.3.1 发送标准广播 * 5.3.2 发 ...

  9. 第一行代码学习笔记第九章——使用网络技术

    知识点目录 9.1 WebView的用法 9.2 使用HTTP协议访问网络 * 9.2.1 使用HttpURLConnection * 9.2.2 使用OkHttp 9.3 解析XML格式数据 * 9 ...

  10. 安卓教程----第一行代码学习笔记

    安卓概述 系统架构 Linux内核层,还包括各种底层驱动,如相机驱动.电源驱动等 系统运行库层,包含一些c/c++的库,如浏览器内核webkit.SQLlite.3D绘图openGL.用于java运行 ...

最新文章

  1. compareto方法_Java compareTo() 字符串方法
  2. 使用 Exceptionless 作为 Log Server 搭配 NLog 记录系统日志
  3. jooq和jdbc_将jOOQ与JDBC比较
  4. 【报告分享】产业互联网发展趋势及机会分析报告.pptx(附下载链接)
  5. P1551 亲戚题解
  6. sunplus 8202v iop源代码阅读笔记——2
  7. linux 编译c q64,Ubuntu 12.04 LTS 64位搭建Qt4终端编译环境
  8. ASP.NET没有魔法——ASP.NET MVC使用Area开发一个管理模块
  9. ABC三类地址、子网掩码及子网划分
  10. 数据分析新手小白入门学习指南,这五大知识清单值得收藏
  11. 实验6 Matlab数值计算
  12. 用计算机研究唐诗,妙哉,那个用文言文编程的小哥,竟从28万行唐诗中找出了对称矩阵...
  13. 使用N2N软件远程管理DLAP221设备
  14. GameObject的Active与InActive activeSelf, activeInHierarchy, SetActiveRecursively
  15. Python实现isPrime()函数,参数为整数,要有异常处理。如果整数是质数,返回True,否则返回False。通过调用isPrime()函数,打印200以内的所有质数,以空格分割。
  16. sketch html尺寸,SketchSize一键生成多尺寸,为何你的设计效率如此之高?
  17. 01组团队项目-Beta冲刺-1/5
  18. PKI-CA数字证书验证过程
  19. 2023 最新微信域名拦截检测API代码
  20. yanderify 让图片动起来 快速安装教程

热门文章

  1. 6-5 Approximating Eigenvalues (40分)
  2. 什么是项目集,如何有效管理?
  3. 卷积神经网络CNNs详解参考----MNIST
  4. 教师资格证计算机专业考什么内容,计算机教师资格证需要考什么?信息技术教师资格证考试内容...
  5. 看完Alibaba“Java成长笔记”我懂了! 为什么阿里的程序员成长如此之快?
  6. 一、Mahony姿态解算——坐标系变换
  7. SMTP邮件服务端口
  8. ArcGIS基于C#.NET的二次开发
  9. OCR技术(大批量生成文字训练集)
  10. SSM+天山产业园访客与疫情防控系统 毕业设计-附源码191123