You are on page 1of 100

分类号: 学校代号:11845

UDC: 密 级: 学 号:2111403006

广东工业大学硕士学位论文
(工学硕士)

基于 ARM Cortex-A9 的嵌入式 Linux 内核


移植研究与实现

罗名驹

指导教师姓名、职称: 陈益民 副教授


学科(专业)或领域名称: 仪器科学与技术
学 生 所 属 学 院: 信息工程学院
论 文 答 辩 日 期: 2017 年 5 月
A Dissertation Submitted to Guangdong University of Technology
for the Degree of Master
(Master of Engineering Science)

Research and Porting Embedded Linux


Kernel Based on ARM Cortex-A9

Candidate: Luo Mingju


Supervisor: Prof.Chen Yimin

May 2017
School of Information Engineering
Guangdong University of Technology
Guangzhou, Guangdong, P. R. China, 510006
摘 要

摘 要

ARM 架构的处理器凭借其低功耗和优异的性能,大量使用在手机、工业控制和
消费电子等嵌入式相关领域。Linux 内核因其源码开源、性能优异、系统可按需裁
剪和支持各类 CPU 架构等诸多优势,成为嵌入式设备上使用最广泛的操作系统,
Linux 系统内核移植是嵌入式 Linux 系统开发的核心基础工作。Linux 内核在演进过
程中不断弃用了一些过时老旧的代码,添加了一些新的功能特性。对 ARM Linux
内核来说一个显著的特性是从 3.x 版本的 ARM Linux 内核开始引入了设备树,设备
树的使用减少了 ARM Linux 内核中板级文件的冗余编码。U-boot 作为嵌入式系统使
用最为广泛的 Bootloader 之一,从 v2014.04 这个版本开始加入了对 ARM Linux 内
核设备树的支持,使得在 ARM Linux 内核和 U-boot 中使用同一个设备树文件成为
了可能。
本文以 ARM Cortex-A9 架构的 Samsung Exynos4412 芯片开发板为硬件平台,较
为详细深入的研究了如何移植引入设备树的 U-boot 和 Linux 内核到 ARM 平台上的
关键技术。具体的研究和移植工作有:研究设备树的语法结构及其在 ARM Linux
内核上的用法;搭建 Linux 内核移植开发环境,包括 Ubuntu 系统、交叉编译工具链、
Samba、版本管理工具 Git 等;分析 Exynos4412 芯片的启动流程、U-boot 的启动流
程、U-boot 的设备驱动模型;Linux 内核启动流程及其配置裁剪、编译;构建嵌入
式 Linux 根文件系统;把 U-boot(u-boot-v2016.11)和 Linux 内核(Linux-4.4)移
植到目标开发板。
通过分析研究移植引入设备树的新版本 U-boot 和 Linux 内核到 ARM Cortex-A9
架构的 Samsung Exynos4412 芯片开发板,对移植新版本的 U-boot 和 Linux 内核到
其他 ARM 架构平台具有参考价值和借鉴意义。

关键词:ARM Cortex-A9,U-boot,Linux 内核移植,设备树

I
广东工业大学硕士学位论文

Abstract

The ARM architecture processor because of its low power consumption and
excellent performance, extensive use in mobile phones, industrial control and consumer
electronics and other embedded related areas. Due to its open source code, excellent
performance, the system can be cut on demand and support all kinds of CPU architecture
and many other advantages, Linux kernel become the most widely used operating system
on embedded devices. Linux kernel porting is at the core of embedded Linux system
development work. Linux kernel in the evolution of the process has been abandoned
some outdated old code, adding some new features. A significant feature of the ARM
Linux kernel is the introduction of a device tree from the 3.x version, which reduces the
redundancy of board-level files in the ARM Linux kernel.U-boot is one of the most
widely used Bootloaders for embedded systems. Since v2014.04 version,U-boot added
device tree to support the ARM Linux kernel,making it possible to use the same device
tree file in the ARM Linux kernel and U-boot.
In this paper, using Samsung Exynos4412 chip development board which based on
ARM Cortex-A9 architecture as the hardware platform, study the key technology of how
to porting the ARM Linux kernel and U-boot to ARM platform. The specific research
and porting work is as follows. Research the grammar of the device tree and its usage on
the ARM Linux kernel.Set up the Linux kernel development environment, including
Ubuntu system, cross compiler tool chain, Samba, version management tools Git,
etc.Analysis of the startup process of the Exynos4412 chip, U-boot boot process, U-boot
device driver model , Linux kernel configuration compilation and its startup process.
Making embedded Linux root file system. Finally, successfully porting the new version
of U-boot (u-boot-v2016.11) and Linux kernel(Linux-4.4) to the target development
board.
Through analysis and study how to porting the new version of U-boot and Linux
kernel to the Samsung Exynos4412 chip development board which based on ARM
Cortex-A9 architecture has reference value and significance for porting new version of
U-boot and Linux kernel to other ARM architecture platform.

Keywords: ARM Cortex-A9, U-boot, Linux kernel porting, device tree


II
目 录

目 录

摘 要 ................................................................................................................................. I
Abstract ............................................................................................................................ II
目 录 ...............................................................................................................................III
Contents ......................................................................................................................... VI
第一章 绪论 .....................................................................................................................1
1.1 课题研究的背景和意义 ..........................................................................................1
1.2 国内外研究现状 ......................................................................................................2
1.2.1 嵌入式系统的发展现状和趋势 ......................................................................2
1.2.2 本课题研究现状 ...........................................................................................2
1.3 课题研究内容及章节安排 ......................................................................................3
1.4 本论文的特点和创新点 ..........................................................................................4
1.5 本章小结 .................................................................................................................4
第二章 ARM Linux 下的设备树简介 .............................................................................5
2.1 设备树概述 .............................................................................................................5
2.1.1 设备树组成和结构 .........................................................................................5
2.1.2 设备树源文件 .................................................................................................5
2.1.3 设备树源码编译器 .........................................................................................8
2.1.4 设备树二进制文件 .........................................................................................8
2.2 设备树的使用方法 ..................................................................................................8
2.3 本章小结 ............................................................................................................... 13
第三章 嵌入式 Linux 系统移植环境搭建 .................................................................... 14
3.1 目标板硬件平台简介 ............................................................................................ 14
3.1.1 Samsung Exyson4412 芯片简介 ................................................................... 14
3.1.2 目标板硬件介绍 ........................................................................................... 15
3.2 宿主机开发环境搭建 ............................................................................................ 16
3.2.1 Ubuntu 系统安装 .......................................................................................... 17

III
广东工业大学硕士学位论文

3.2.2 交叉编译工具链安装 ................................................................................... 19


3.2.3 其他开发工具和库的安装 ............................................................................ 21
3.3 本章小结 ............................................................................................................... 23
第四章 移植引导加载程序 U-boot ............................................................................... 24
4.1 引导加载程序 U-boot 简介 ................................................................................... 24
4.2 Exyson4412 芯片启动模式选择 ........................................................................... 24
4.3 U-boot 移植分析 ................................................................................................... 26
4.3.1 U-boot 源代码结构 ....................................................................................... 26
4.3.2 U-boot 配置和编译 ....................................................................................... 27
4.3.3 U-boot 启动流程分析 ................................................................................... 28
4.3.4 U-boot 的设备驱动模型 ............................................................................... 32
4.3.5 U-boot 移植总体思路分析 ........................................................................... 33
4.4 U-boot 在目标板上的移植 .................................................................................... 34
4.4.1 U-boot 源码中添加目标板目录和文件 ........................................................ 34
4.4.2 使用目标板上的 LED 灯进行代码调试 ...................................................... 35
4.4.3 初始化 Exynos4412 芯片时钟 ...................................................................... 37
4.4.4 初始化调试串口 ........................................................................................... 39
4.4.5 初始化内存拷贝 U-boot 到片外内存运行 ................................................... 40
4.5 本章小结 ............................................................................................................... 43
第五章 嵌入式 Linux 内核移植 .................................................................................... 44
5.1 Linux 内核相关介绍 ............................................................................................. 44
5.1.1 Linux 内核源码下载 ..................................................................................... 44
5.1.2 Linux 内核源代码目录结构 ......................................................................... 44
5.1.3 Linux 内核的整体架构 ................................................................................. 46
5.1.4 Linux 内核的配置和编译 ............................................................................. 47
5.2 ARM Linux 内核启动过程分析 ............................................................................ 49
5.3 移植 Linux 内核到目标板 .................................................................................... 50
5.3.1 Linux 内核源码中添加目标板配置文件 ..................................................... 50
5.3.2 根据目标板硬件裁剪 Linux 内核 ................................................................ 51
5.3.3 使用 U-boot 启动 Linux 内核 ....................................................................... 52
IV
目 录

5.4 本章小结 ............................................................................................................... 55


第六章 嵌入式 Linux 根文件系统构建 ........................................................................ 56
6.1 嵌入式 Linux 文件系统概述 ................................................................................ 56
6.2 嵌入式文件系统制作工具 Busybox 简介 ............................................................ 57
6.3 制作嵌入式 Linux Ramdisk 文件系统 .................................................................. 58
6.3.1 制作 Linux 根文件系统 ................................................................................ 58
6.3.2 制作 Ramdisk 文件系统 ............................................................................... 61
6.4 修改 U-boot 启动参数启动 Linux 内核 ............................................................... 62
6.5 本章小结 ............................................................................................................... 63
结论与展望 ..................................................................................................................... 64
参考文献 ......................................................................................................................... 66
攻读学位期间发表论文 ................................................................................................. 69
学位论文独创性声明 ..................................................................................................... 70
学位论文版权使用授权声明 ......................................................................................... 70
致谢................................................................................................................................. 71
附录 A U-boot 源码中添加目标板目录和文件代码 ..................................................... 72
附录 B Exyson4412 时钟初始化关键代码 .................................................................... 77
附录 C Exyson4412 串口初始化关键代码 .................................................................... 78
附录 D Exyson4412 内存初始化关键代码 .................................................................... 80
附录 E Linux 内核移植代码 .......................................................................................... 83

V
广东工业大学硕士学位论文

Contents

Abstract(Chinese) .................................................................................................................... I
Abstract(English) .................................................................................................................... II
Contents(Chinese) .................................................................................................................. III
Contents(English) ...................................................................................................................VI
Chapter1 Introduction ............................................................................................................ 1
1.1 Background and Significance of the Issue .................................................................... 1
1.2 Research Status at Home and Abroad ............................................................................ 2
1.2.1 The Present Situation and Trend of Embedded System ...................................... 2
1.2.2 The Status Quo of this Research ...................................................................... 2
1.3 Project Research Contents and Chapter Arrangement ................................................. 3
1.4 The characteristics and innovation of this paper .......................................................... 3
1.5 Chapter Summary ............................................................................................................ 4
Chapter2 ARM Linux Device Tree Introduction .............................................................. 5
2.1 Overview of the Device Tree .......................................................................................... 5
2.1.1 Device Tree Composition and Structure ............................................................... 5
2.1.2 Device Tree Source File ......................................................................................... 5
2.1.3 Device Tree Compiler ............................................................................................ 8
2.1.4 Device Tree Blob .................................................................................................... 8
2.2 The Usage of Device Tree .............................................................................................. 8
2.3 Chapter Summary .......................................................................................................... 13
Chapter3 Install Embedded Linux System Transplant Environment ......................... 14
3.1 Introduction to the Target Board Hardware Platform ................................................ 14
3.1.1 Samsung Exyson4412 Chip Introduction ........................................................... 14
3.1.2 Target Board Hardware Introduction .................................................................. 15
3.2 Install Host Development Environment ...................................................................... 16
3.2.1 Ubuntu System Installed ...................................................................................... 17
3.2.2 Cross-compilation Tool Chain Installation ........................................................ 19

VI
Contents

3.2.3 Install Other Development Tools and Libraries ................................................ 21


3.3 Chapter Summary .......................................................................................................... 23
Chapter4 Porting U-boot ...................................................................................................... 24
4.1 Bootloader U-boot Introduction ................................................................................... 24
4.2 Exyson4412 Chip Boot Mode Selection ...................................................................... 24
4.3 U-boot Transplant Analysis .......................................................................................... 26
4.3.1 U-boot Source Code Structure............................................................................. 26
4.3.2 U-boot Configuration and Compilation .............................................................. 27
4.3.3 U-boot Startup Process Analysis ......................................................................... 28
4.3.4 U-boot Device Driver Model ............................................................................... 32
4.3.5 U-boot Transplant Analysis ................................................................................. 33
4.4 Porting U-boot on the Target Board ............................................................................ 34
4.4.1 Add the Target Board Directory and File in U-boot ......................................... 34
4.4.2 Use the LED on the Target Board for Code Debugging ................................... 35
4.4.3 Initialize the Exynos4412 Chip Clock ................................................................ 37
4.4.4 Initialize the Debug Serial Port ........................................................................... 39
4.4.5 Initialize Memory and Copy U-boot to Off-chip Memory ............................... 40
4.5 Chapter Summary .......................................................................................................... 43
Chapter5 Porting Embedded Linux kernel ...................................................................... 44
5.1 Introduction to the Linux Kernel .................................................................................. 44
5.1.1 Linux Kernel Source Download .......................................................................... 44
5.1.2 Linux Kernel Source Code Directory Structure ................................................ 44
5.1.3 The Overall Architecture of the Linux Kernel................................................... 46
5.1.4 Linux Kernel Configuration and Compilation ................................................... 47
5.2 ARM Linux Kernel Boot Process Analysis ................................................................ 49
5.3 Porting the Linux Kernel to the Target Board ............................................................ 50
5.3.1 Add the Target Board Configuration File to the Linux Kernel source Code . 50
5.3.2 Cut the Linux Kernel According to the Target Board Hardware ..................... 51
5.3.3 Use U-boot to Boot the Linux Kernel................................................................. 52

VII
广东工业大学硕士学位论文

5.4 Chapter Summary .......................................................................................................... 55


Chapter6 Embedded Linux Root File System Construction ......................................... 56
6.1 Embedded Linux File System Overview ..................................................................... 56
6.2 Introduction to Embedded File System Making Tools Busybox .............................. 57
6.3 Production of Embedded Linux Ramdisk File System .............................................. 58
6.3.1 Make Linux Root File System ............................................................................. 58
6.3.2 Make the Ramdisk File System ........................................................................... 61
6.4 Modify the U-boot Boot Parameters to boot the Linux Kernel ................................. 62
6.5 Chapter Summary .......................................................................................................... 63
Conclusions and Prospect ..................................................................................................... 64
Reference ................................................................................................................................. 66
Publications ............................................................................................................................. 69
Promethean Declaration ....................................................................................................... 70
Copyright Declaration........................................................................................................... 70
Acknowledgements ................................................................................................................ 71
Appendix A Add the Target Directory and File in U-boot Source Code .................... 72
Appendix B Exyson4412 Clock Initialization Key Code ................................................ 77
Appendix C Exyson4412 Serial Port Initialization Key Code ....................................... 78
Appendix D Exyson4412 Memory Initialization Key Code ........................................... 80
Appendix E Linux kernel Porting Code ............................................................................ 83

VIII
第一章 绪论

第一章 绪论

1.1 课题研究的背景和意义

随着计算机技术、通信技术和互联网技术的快速发展及其在生产生活中的广泛
应用,我们的世界已经进入了计算机、通信、消费电子三者的紧密融合的“后 PC 时
代”。
嵌入式设备是“后 PC 时代”使用最多的设备,最典型的特征是智能手机的普及。
不仅在消费电子领域,嵌入式设备还广泛用于工业控制、数字通信、汽车电子、医
疗仪器等诸多领域,嵌入式系统在当前人们生产生活中随处可见。嵌入式设备中使
用最多的处理器是基于 ARM 架构的 SoC(System on Chip),这得益于 ARM 处理器
自身高性能低功耗设计和 ARM 公司独特的授权方式得到了众多知名半导体厂商的
支持,开发出了许多基于 ARM 架构的嵌入式芯片。
大部分嵌入式设备都是运行 Linux 系统或者是基于 Linux 内核的 Android 操作系
统。Linux 内核因其源码开源、性能优异可靠、系统可按需裁剪和支持各类 CPU 架
构等诸多优势,成为目前非常流行的嵌入式操作系统,是嵌入式设备操作系统的首
选。
在设备树(Flattened Device Tree)[1]还没有引入到 ARM Linux 内核之前,Linux 内
核源代码 arch/arm 目录下有大量重复的代码来描述板级硬件的细节信息。这些用来
描述板级硬件细节信息的代码导致 ARM Linux 内核代码逐渐变得庞大冗余。ARM
社区为改变 ARM Linux 内核代码冗余的情况,在 Linux 内核 3.x 版本引入了设备树。
在 ARM Linux 内核中使用设备树后,Linux 内核可以直接通过设备树文件来获取板
级硬件的细节信息,大大减少 ARM Linux 内核中的冗余代码。U-boot 是嵌入式系统
最为广泛使用的 Bootloader 之一 ,其代码结构也在逐步向 Linux 内核代码的编译结
构演进,并且逐渐完善对设备树的支持。在 ARM Linux 内核和 U-boot 中引入设备
树后,不但使 U-boot 和 Linux 内核可以使用同一个 ARM 架构芯片的设备树文件,
而且用一个内核镜像去引导同一类 ARM 架构芯片的硬件平台成为了可能,可以大
大减少 Linux 系统移植和驱动开发的工作量。

1
广东工业大学硕士学位论文

嵌入式操作系统是整个嵌入式系统软件的核心,嵌入式操作系统的移植也就成
了嵌入式系统软件开发的核心和关键。在嵌入式 Linux 开发领域,Linux 系统移植
是极其重要的组成部分,在嵌入式设备上移植好 Linux 系统是大部分嵌入式产品软
件开发的基础。移植 Linux 系统需要具备硬件和软件的知识才能很好的完成移植
Linux 系统的工作。因此研究移植新版本的 U-boot 和 Linux 内核到 ARM 平台上,
对嵌入式 Linux 系统内核移植和设备开发具有一定的参考价值和借鉴意义。

1.2 国内外研究现状

1.2.1 嵌入式系统的发展现状和趋势

嵌入式技术已广泛应用在生产、工作、生活各个方面。小到我们每个人日常生
活中使用的手机、数码相机、智能扫地机器人,大到工业机器人、汽车飞机、载人
飞船等,到处都有嵌入式系统和嵌入式技术的应用。嵌入式设备正在以各种不同的
形式悄然改变着人们的生产、工作和生活方式,可以说它是信息技术的一个新发展,
是信息产业的一个新亮点,也成为当前最热门的技术之一。
嵌入式系统广泛应用于生产、工作、生活各个方面得益于半导体技术和嵌入式
软件技术的飞速发展。嵌入式处理器是嵌入式设备的核心部分,是整个嵌入式系统性
能的硬件基础。随着半导体生产工艺的提高和对高性能的个人、家庭娱乐和信息终
端的巨大需求,嵌入式处理器的主频和性能都在大幅增长,性能功耗比越来越高。
嵌入式处理器朝着多核处理器和多线程技术方向发展,以手机的处理器为例,已经
从单核发展到了双核、四核、八核,而且性价比越来越高。
目前在嵌入式领域使用的操作系统有:µC/OS-II、Linux、Windows Embedded、
VxWorks 等,以及广泛应用在智能手机和平板电脑上的 Android 系统、IOS 系统等。
在这些嵌入式操作系统中使用最广泛的是 Linux 系统和基于 Linux 内核的 Android
系统。提供更灵活的可裁性、更高的运行效率、更丰富的多媒体人机界面、更强的
安全保障机制和更好的网络接入是嵌入式操作系统的发展方向。

1.2.2 本课题研究现状

国内外系统介绍移植 Linux 内核到 ARM 平台的论文比较少,特别是缺少系统介


绍如何移植引入设备树的新版本 Linux 内核和 U-boot 到 ARM 平台上的文章。通过

2
第一章 绪论

研究分析 CNKI 总库中搜索到的最近几年来与 ARM Linux 系统内核移植紧密相关的


硕士学位论文,发现研究 Linux 内核移植的文章详细的阐述嵌入式 Linux 系统移植
相关的基本理论和一般方法,但对具体的移植细节描述的比较简略;移植的 Linux
内核和 U-boot 版本比较旧,移植的 ARM 平台芯片也比较老旧。

1.3 课题研究内容及章节安排

本文研究的内容是移植引入设备树的新版本 Linux 内核和 U-boot 到 ARM


Cortex-A9 架 构 的 Samsung Exynos4412 芯 片 开 发 板 上 , 对 移 植 新 版 本 的
U-boot(u-boot-v2016.11)和 Linux 内核(Linux-4.4)到 ARM Cortex-A9 架构的 Samsung
Exynos4412 芯片开发板进行较为深入研究,并且详细阐述了相关的移植分析过程和
具体的移植步骤,完成了 U-boot 和 Linux 内核相关移植工作。本文共分为 6 章,各
章的内容介绍如下:
第一章为绪论部分,主要介绍了嵌入式 Linux 内核移植研究的背景、意义和现
状,阐述了嵌入式系统的发展现状和趋势,同时对本文的主要研究内容及其组织框
架做了一个简单明了的说明。
第二章 ARM Linux 下的设备树简介。主要研究设备树(Flattened Device Tree)的
语法结构和在 ARM Linux 中的应用。
第三章嵌入式 Linux 系统移植环境搭建。主要介绍了 Linux 系统移植开发环境的
搭建,介绍了 Samsung Exynos4412 芯片和目标板硬件 Tiny4412 开发板,阐述了如
何安装宿主开发机 Ubuntu 系统、ARM Linux 交叉编译环境和在移植过程中要使用
到的开发工具以及相应的库函数。
第 四 章 移 植 引 导 加 载 程 序 U-boot 。 主 要 研 究 移 植 新 版 本 的
U-boot(u-boot-v2016.11)到 Tiny4412 开发板。首先介绍了 Exyson4412 芯片的启动模
式选择,接着介绍了 U-boot 源代码结构、配置、编译以及其启动流程,并对新版本
U-boot 引入的设备驱动模型做了介绍,最后总结了 U-boot 移植的总体思路,并给出
了详细移植 U-boot 到目标板的步骤。
第五章嵌入式 Linux 内核移植。介绍了嵌入式 Linux 内核移植相关的内容,详细
阐述了移植新版本的 Linux 内核(Linux-4.4)到 Tiny4412 开发板的方法和步骤。
第六章嵌入式 Linux 根文件系统构建。对 Linux 根文件系统和文件系统制作工具

3
广东工业大学硕士学位论文

Busybox 做了相应的介绍,并构建了 Linux 根文件系统,制作 Ramdisk 文件,在目


标板上成功启动了新移植的 Linux 内核,完成了 Linux 内核移植的基本工作。
最后,对整个 Linux 系统内核移植研究工作做了概况总结,提出 Linux 内核移植
研究应该进一步研究和完善的地方。

1.4 本论文的特点和创新点

1、详细研究设备树(Flattened Device Tree)的语法结构,及其在 U-boot 和 Linux


内核中的应用。
2、选用基于 ARM Cortex-A9 的 Exyson4412 芯片开发板,该四核处理器性能强
劲,可以流程运行 Android 系统,为后续移植研究 Android 系统做好了前期铺垫。
在移植准备阶段详细分析了 Exyson4412 芯片的启动过程,为更好的研究移植 Linux
内核做好了硬件知识铺垫。
3 、 在 移 植 引 导 加 载 程 序 U-boot 阶 段 , 选 用 了 引 入 设 备 树 的 新 版 本
U-boot(u-boot-v2016.11)。与现有的同类研究在 U-boot 移植阶段对 U-boot 移植实现
过于简略、缺乏具体的移植过程、移植的 U-boot 版本比较老旧相比,本文对如何移
植引入设备树的 U-boot 做了更为深入的研究,并给出了详细的移植步骤。
4、在 Linux 内核移植阶段,使用引入设备树的新发行版本 Linux 内核(Linux-4.4)。
避免了跟同类研究使用冗长的篇幅“复述”原理而对 Linux 内核移植方法和过程却较
少提及的情况,本文直接阐述了 Linux 内核移植的详细方法和完整步骤。

1.5 本章小结

本章在查阅国内外参考文献的基础上,提出了研究移植引入设备树的 U-boot 和
Linux 内核移植到 ARM Cortex-A9 架构的 Samsung Exynos4412 芯片开发板的研究内
容,主要工作如下:
1.说明课题的研究背景和研究意义。
2.介绍了嵌入式 Linux 内核移植到 ARM 平台上的国内外研究现状。
3.对本文的主要研究内容以及组织框架做了一个简要的说明,为后面阐述 Linux
内核移植作准备。

4
第二章 ARM Linux 下的设备树简介

第二章 ARM Linux 下的设备树简介

2.1 设备树概述

2.1.1 设备树组成和结构

设备树是一种描述板级硬件配置的树形数据结构,它来源于 Open Firmware (OF)


[2]
,并继承了 Open Firmware IEEE 1275 设备树的定义[3]。
在设备树中,可描述板级硬件的信息包括 [4]:
 CPU 的数量和类别
 内存基地址和大小
 总线和桥
 中断控制器
 Clock 控制器
 GPIO 控制器
 外围设备
Linux 内核会根据设备树传递进来的硬件信息展开得到 Linux 内核所需的硬件设
备信息。

2.1.2 设备树源文件

设备树源文件(Device tree source)由结点(node)和属性(property)组成,


每个结点可包含子结点和属性,该文件一般存放在 Linux 内核的 arch/arm/boot/dts/
目录下,通常一个板级硬件对应这一个.dts 文件 [5]。
下面是一个简单设备树源码示例:
/{
model = "MyBoardName"
compatible= "MyBoardFamilyName"
#address-cells = <1>
#size-cells = <1>

5
广东工业大学硕士学位论文

aliases {
i2c0 = &i2c0;
i2s0 = &i2s0;
spi0 = &spi0;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0{
compatible = "arm,cortex-a9";
device_type = ”cpu";
reg = <0>;
};
};
memory@0{
name = "memory"
device_type = "memory"
reg = <0x00000000 0x20000000>
}
chosen{
name = "chosen"
bootargs="console=ttySAC0,\
115200 root=/dev/mmcblk0p5"
}
}
从设备树源码示例可以到,设备树的基本单元由节点组成,每个节点都由节点单
元名称标识,并且每一个属性都有相对应的值。节点用节点名字标识,其形式为
node-name@unit-address。
1、根节点

6
第二章 ARM Linux 下的设备树简介

每个设备树源码文件里面有且仅有一个根节点“/”,且节点名必须是“/”。根节点
下有若干个节点,每个节点中的属性(property)描述了该节点的特性。根节点下包
含的属性有:
model:板级硬件模块的名称;
#address-cells:表示该目标板或者硬件模块的地址线;
#size-cells:表示该目标板或者硬件模块的地址线宽度。
2、CPU 节点
CPU 节点描述了 CPU 的特性,每一个 CPU 都有一个与之一一对应的 CPU 节点。
CPU 节点下常用的属性有 [6]:
#address-cells:表示 CPU 的地址线;
#size-cells:表示 CPU 的地址线宽度;
device_type:节点设备类型,必须设为"cpu";
reg: 用于指定 CPU 的编号。
3、memory 节点
memory 节点是设备树文件必备的节点,它定义了板级硬件物理内存的起始地址
和大小。该节点下常用的属性有:
device_type:节点设备类型,必须设为"memory ";
reg:用<address size>指定了内存地址和大小。例如<0x00000000 0x20000000>
表示内存地址从 0x00000000 开始,大小为 512M 的内存节点。
4、SoC 节点
SoC 节点描述了 CPU 上集成的外设接口,例如 I2C、SPI、串口等。SoC 节点包
含的属性有:
device_type:节点设备类型,必须设为"soc";
ranges:该节点表示了 SoC 寄存器地址;
5、chosen 节点
chosen 节点不是用来描述硬件资源的信息,而是向 Linux 内核传递一些运行时
的参数。使用 chosen 节点可以取代 Bootloader 通过 tag list 传递运行参数给 Linux 内
核。例如:bootargs 这个属性传递的是 command line 的信息;initrd-start 这个属性传
递是 initrd 的开始地址。

7
广东工业大学硕士学位论文

6、aliases 节点
aliases 节点定义了一些节点的别名。在设备树源文件中引用一个节点时要指明相
对于根节点的绝对路径,例如/node-name-1/node-name-2。aliases 节点定义一些节点
路径的别名,使引用节点变得简洁。
Linux 内核开发者把 SoC 芯片公用的.dts 文件单独分离出来,保存为.dtsi 文件。
当其它.dts 文件需要使用这些公共的.dtsi 文件时就把该.dtsi 包含进去。大部分的
ARM SoC 的.dtsi 文件都引用了 arch/arm/boot/dts/skeleton.dtsi 这个设备树源码文件。

2.1.3 设备树源码编译器

设备树源码编译器(Device tree compiler)是将设备树源码文件(.dts)编译为设备


树二进制文件(.dtb)的工具。配置 Linux 内核时选中 CONFIG_DTC 选项,Linux 内核
在编译的过程中会自动编译生成设备树编译器。在 Linux 内核源码根目录下运行
make dtbs 命令时,设备树源码编译器会把选中的.dts 编译成.dtb。

2.1.4 设备树二进制文件

使用设备树源码编译器把.dts 格式的设备树源码文件编译成.dtb 格式的设备树二


进制文件(Device tree blob)。在制作板级硬件制作启动镜像时,通常会在指定区域
存放.dtb 文件,U-boot 在引导内核的过程中会把该.dtb 二进制文件读取到内存特定
的区域中。

2.2 设备树的使用方法

在 ARM Linux 未引入设备树时,ARM Linux 内核在 arch/arm/plat-xxx 和 arch/arm/-


mach-xxx 做的主要工作是 [7]:
注册 platform_device,绑定 resource:
static struct resource xxx_resources[] = {
[0] = {
.start = …,
.end = …,
.flags= IORESOURCE_MEM,
},

8
第二章 ARM Linux 下的设备树简介

[1] = {
.start = …,
.end = …,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device xxx_device = {
.name = "xxx",
.id = -1,
.dev ={
.platform_data = &xxx_data,
},
.resource = xxx_resources,
.num_resources=ARRAY_SIZE(xxx_resources),
};
注册 i2c_board_info、spi_board_info 等:
static struct i2c_board_info __initdata xxx_i2c_devices[] = {
{ I2C_BOARD_INFO("name", 0x1a), },
};
static struct spi_board_info xxx_spi_devices[] = {
{ /* DataFlash chip */
.modalias = "mtd_dataflash",
.chip_select = 1,
.max_speed_hz = 15 * 1000 * 1000,
.bus_num = 0,
},
};
填充由 MACHINE_START 和 MACHINE_END 包围起来的的一系列 callback 函
数:

9
广东工业大学硕士学位论文

MACHINE_START(xxx_board,"ARM-xxx")
.atag_offset = 0x100,
.map_io = xxx_map_io,
.init_early = xxx _init_early,
.init_irq = xxx _init_irq,
.timer = & xxx _timer,
.handle_irq = gic_handle_irq,
.init_machine = xxx _init,
.restart = xxx_board _restart,
MACHINE_END
使用设备树后,resource 信息可以从设备树文件节点中的 reg、interrupts 等属性
得到; Linux 内核中板级硬件的回调函数通过调用 of_platform_bus_probe(NULL,xx-
x_of_bus_ids, NULL)函数,可自动展开所有的 platform_device。
假设我们有一款基于 ARM 架构芯片的板级硬件,Linux 内核在 arch/arm/mach-
-xxx/的板级文件中使用如下方式展开.dts 文件中的设备结点对应的平台设备信息:
static struct of_device_id xxx_of_bus_ids[] __initdata = {
{ .compatible = "simple-bus", },
{},
};
void __init xxx_mach_init(void)
{
of_platform_bus_probe(NULL,xxx_of_bus_ids, NULL);
}
#ifdef CONFIG_ARCH_XXX
DT_MACHINE_START(XXX_DT, "Generic XXX (Flattened Device Tree)")

.init_machine = xxx_mach_init,

MACHINE_END

10
第二章 ARM Linux 下的设备树简介

#endif
把 I2C、 SPI 等 这 些 硬 件 设 备 信 息 填 充 到 对 应 的 设 备 树 源 码 文 件 中 的 I2C
controller 结点、SPI controller 结点上去,I2C host 驱动、SPI host 驱动的 probe 函数
在注册主设备的时候获得这些硬件信息:
i2c2: i2c@e1a00000 {
compatible = "yyyy,xxxx-i2c";
reg = <0xe1a00000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
...
};
spi0: spi@e1300000 {
compatible = "yyyy,xxxx-spi";
reg = <0xe1300000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
...
};
MACHINE_START 和 MACHINE_END 包围起来的一系列板级硬件 callback 函数
变成为:
static const char * const xxx_dt_match[] __initconst = {
"arm,xxx_board",
NULL,
};
DT_MACHINE_START(XXX_BOARD_DT, "ARM-xxx ")
.dt_compat = xxx_dt_match,
.smp = smp_ops(xxx_board_smp_ops),
.map_io = xxx_dt_map_io,
.init_early = xxx_dt_init_early,

11
广东工业大学硕士学位论文

.init_irq = xxx_dt_init_irq,
.timer = &xxx_dt_timer,
.init_machine = xxx_dt_init,
.handle_irq = gic_handle_irq,
.restart = xxx_board_restart,
MACHINE_END
.dt_compat 成员是用来表明相关的板级硬件与.dts 文件中根结点的 compatible 属性的
兼容关系。如果 U-boot 传递给内核的设备树中根结点的 compatible 属性出现在某个
板级硬件的.dt_compat 表中,相关的板级硬件就与对应的设备树匹配,被执行相关
板级硬件的初始化函数。
对驱动来说,当驱动与.dts 中描述的设备结点匹配后,会执行驱动的 probe()函数。
对于平台驱动而言,需要添加一个 OF 匹配表。例如.dts 文件的"yyy,xxx-i2c-bus"兼
容 I2C 控制器结点的 OF 匹配表是:
static const struct of_device_id xxx_i2c_of_match[] = {
{ .compatible = "yyy,xxx-i2c-bus ", },
{},
};
MODULE_DEVICE_TABLE(of,xxx_i2c_of_match);
static struct platform_driver i2c_xxx_driver = {
.driver = {
.name = "xxx-i2c-bus ",
.owner = THIS_MODULE,
.of_match_table = xxx_i2c_of_match,
},
.probe = i2c_xxx_probe,
.remove = i2c_xxx_remove,
}

12
第二章 ARM Linux 下的设备树简介

2.3 本章小结

本章介绍了设备树的优点及其在 ARM Linux 的用法,详细阐述了 ARM Linux


内核引入设备树后,相关内核板级支持包和驱动代码的变化。在 ARM Linux 内核引
入设备树后,ARM Linux 内核删除了 arch/arm 目录下大量用于注册板级信息的代码,
并且驱动也以设备树中定义的设备结点进行匹配注册。这样可以减少 Linux Kernel
中 arch/arm 目录下大量的冗余代码,提高代码的复用性;加速 ARM Linux 板级支持
包的开发,使用现有的内核镜像去引导具有相同芯片集的硬件平台成为可能。

13
广东工业大学硕士学位论文

第三章 嵌入式 Linux 系统移植环境搭建

3.1 目标板硬件平台简介

3.1.1 Samsung Exyson4412 芯片简介

Exyson4412 芯片是三星公司研发的 32 位精简指令集、低功耗、性能优异的


Coretex-A9 四核微处理器,运行主频高达 1.5GHz,Exyson4412 芯片内部集成了
Mali-400 MP 高性能图形引擎,支持 3D 图形流畅运行,并可播放 1080P 高清视频,
能流畅运行 Linux、Android 操作系统 [8]。三星旗舰智能手机 Galaxy S3 的 CPU 采用
的就是 Exyson4412 芯片。

图 3-1 Exyson4412 芯片框图

Fig.3-1 Exynos4412 Block Diagram

Exyson4412 芯片性能参数:
1、Exyson4412 CPU 参数:采用 ARM Cortex-A9 内核,ARMv7 指令集、32nm 制

14
第三章 嵌入式 Linux 系统移植环境搭建

程的四核处理器;主频 1.5GHz,128/64 位内部总线结构;32/32KB 的数据/指令一


级缓存,1024KB 的二级缓存;可以实现 2000DMIPS(每秒 2 亿指令集)的高性能运
算能力。
2、Exyson4412 GPU 参数:Exyson4412 内建高性能的 ARM Mali-400 MP 3D 图
形引擎和 2D 图形引擎;多边形生成率为 44M 三角形/秒,像素填充率可达 1.6G 像
素/秒;支持 DX9、SM3.0、OpenGL2.0 等 PC 级别显示技术;支持 JPEG 硬件编解
码,最大支持 8192*8192 分辨率图片;支持全高清、多标准的视频编码,内建 MFC,
支持 MPEG-1/2/4、VC-1、H.263、H.264 编解码,支持数字 TV 输出。
3、Exyson4412 芯片内存性能参数:Exyson4412 芯片存储控制器支持 LPDDR、
LPDDR2、DDR2 和 DDR3 类型的内存,最大支持 2GB 内存;Flash 支持 NANDflash、
NORflash、OneNand、iNAND,最大支持 Flash 储存空间为 32G,最大支持 TF 卡扩
展储存空间为 32G[8]。

3.1.2 目标板硬件介绍

本文使用的移植目标硬件是友善之臂公司设计生产的 Tiny4412 SDK 开发板。


1、Tiny4412 核心板介绍
Tiny4412 核心板使用三星 Exynos4412 四处理器,运行主频高达 1.5GHz;标配
1G DDR3 内存和 4GB 高速 eMMC 闪存。

图 3-2 Tiny4412 核心板

Fig.3-2 The Core board of Tiny4412

2、Tiny4412 底板介绍
开发板底板使用的是 Tiny4412SDK 1506 这个标准版底板,底板硬件资源特性如
下:

15
广东工业大学硕士学位论文

1) LCD1 支持一线协议背光调节和电容触摸;LCD2 支持一线电阻触摸和一线背


光调节;LCD 可支持从 3.5 寸到 12.1 寸屏,支持高清屏。
2) HDMI 高清接口(Type A);1 个标准 SD 卡座。
3) 1 个 10/100M 以太网 RJ45 接口,使用 DM9621 网卡芯片;
4) 1 个 DB9 式 RS232 串口(另有 3 个 TTL 电平串口);
5) 1 路 3.5mm 音频输出接口,1 路麦克风输入接口;
6) 3 路 USB Host 2.0 接口(其中一路通过排针引出);
7) 电源接口座型号为 DC-23B,输入电压为 5V 直流电;
8) 4 个可用户自定义按键,1 个蜂鸣器;
9) 1 个 RTC 时钟备份电池,1 个重力感应芯片,1 个 I2C-EEPROM 芯片;
10) 3 个串口座(TTL 电平),10 路 GPIO 接口,2 路 PWM 接口;
11) 1 个 Camera 接口,1 路 SPI 接口,1 路 I2C 接口。

图 3-3 Tiny4412 底板接口布局

Fig.3-2 The Interface Layout of Tiny4412 Bottom Board

3.2 宿主机开发环境搭建

在嵌入式开发过程中有宿主机和目标机的角色之分。宿主机是执行编译、链接
嵌入式软件的计算机;目标机是运行嵌入式软件的硬件平台。嵌入式开发通常是在

16
第三章 嵌入式 Linux 系统移植环境搭建

宿主机上编写好程序,使用交叉编译工具生成目标板上可以执行的二进制代码,再
将编译好的二进制代码下载或者烧写到目标板指定的存储位置,目标板上电后可以
从指定的存储位置读取代码开始执行。

3.2.1 Ubuntu 系统安装

如果是没有其他多余的计算机来安装 Ubuntu 系统,一般的做法是在安装有


Windows 系统的计算机中安装虚拟机软件,再在虚拟机中安装 Ubuntu 系统。
本开发环境使用的虚拟机软件是 VMWare WorkStation(简称 VMWare),安装的
VMWare 版 本 是 VMware-workstation-full-12.5.2-4638234 , 可 以 到 其 官 网
http://www.vmware.com/products/workstation.html 上 下 载 。 Ubuntu 系 统 使 用 的 是
ubuntu-14.04.3-desktop-amd64 这个版本,可以到 Ubuntu 官网 http://www.ubuntu.com-
/download/进行下载,注意下载时选择 Desktop 版本。
VMware 软件安装完成后,我们需要在 VMware 虚拟机创建出一个虚拟的 PC 机,
接着在虚拟的 PC 机中安装 Ubuntu 系统。打开安装好的 VMware 软件,根据提示在
VMware 中建出一个虚拟的 PC 机。要注意的地方有如下几点:
1、在选择客户机操作系统界面,客户及操作系统选择“Linux”,版本选择“Ubuntu
64 位”;
2、在处理器配置界面,处理器数量一般都是 1,表示你只有一个 CPU,每个处
理器的核心数量则要根据自己的处理器情况来配置,比如我的笔记本 CPU 是 i7-4700
是四核的,所以可以把处理器的核心数量配为 2;
3、在虚拟机内存配置界面,至少要为虚拟机分配 2GB 的内存;
4、在网络类型设置界面,选择“使用桥接网络”;
5、在 IO 控制器选择界面,我们选择“LSI Logic”类型;
6、在选择虚拟磁盘类型的时候,选择“SCSI”类型即可;
7、在选择磁盘界面,选择“创建新虚拟磁盘”;
8、在指定磁盘容量界面,指定我们要为 Ubuntu 分配的虚拟磁盘大小,至少要
分配 20GB,而且勾选“将虚拟磁盘存储为单个文件”,会提升虚拟磁盘的性能;
在 VMware 里创建好的虚拟机 PC 机界面如图 3-4 所示:

17
广东工业大学硕士学位论文

图 3-4 虚拟 PC 机界面

Fig.3-4 The Virtual Interface of PC

在虚拟机里创建好虚拟的 PC 机后,我们接着在虚拟的 PC 机中安装 Ubuntu 操


作系统。点击图 3-4 里面的“CD/DVD”选项,在新弹出的“虚拟机设置”子窗口中,在
右侧“连接”栏目下,勾选“使用 ISO 映像文件”,点击“浏览”按钮找到之前准备好的
Ubuntu 镜像文件打开,之后回到虚拟机设置界面,点击“确定”按钮则可以返回到
VMware 主界面。点击主界面的“开启此虚拟机”,则可以进入操作系统的安装环节。
接下来根据提示一步一步安装 Ubuntu 系统。
第一次安装完 Ubuntu 系统启动会有点慢,Ubuntu 系统启动后会出现登录界面,
选择相应的用户名输入密码就可进入 Ubuntu 系统,如图 3-5 所示。至此,整个 Ubuntu
系统安装完毕。

18
第三章 嵌入式 Linux 系统移植环境搭建

图 3-5 Ubuntu 操作系统界面

Fig.3-5 The Interface of Ubuntu Operating System

安装好 Ubuntu 系统后,我们可以安装 VMware Tools 工具,这个工具可以方便


我们在 Window 系统和虚拟机里面双向的复制粘帖文件,而且还可以优化虚拟机里
面的 Ubuntu 系统的显示画面。

3.2.2 交叉编译工具链安装

工具链是用来构建计算机软件的软件工具集合,一般包括链接器、汇编器、归
档器、编译器、库函数和头文件 [9]。交叉工具链的特点是在一个通用的平台(如 x86
主机)上编译程序,在另一个平台(通常是嵌入式目标板)上运行程序,自行配置、
建立合适的交叉工具链是一项复杂、繁琐的工作,一般情况下优先选择发行版本的
交叉工具链 [10]。
本开发环境使用的是 Linaro 提供的 ARM 交叉编译工具链,可以到 Linaro 官网
http://releases.linaro.org/去下载已经制作好的交叉编译工具链。编译新版本的 U-boot
和 Linux 内核需要选择比较新的 ARM 交叉编译工具链,如果使用的交叉编译工具
链 版 本 比 较低可能会导致编译不通过。这里要注意的一点是要根据虚拟机里的
Ubuntu 系统的位数来选择 64 位的交叉编译器工具链还是 32 位的交叉编译工具链。
我下载的是 gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz 这个版本的交
叉编译工具链。
首先在 Ubuntu 系统中安装相关的标准 C 开发环境库,在 Ubuntu 系统终端执行

19
广东工业大学硕士学位论文

命令:
$ sudo apt-get install gcc g++ libgcc1 libg++ make gdb
完成相关库的安装。安装好相关库后,在/usr/local/目录下新建名为 ARM-toolchain
的文件夹用于存放交叉编译工具链。接下来就是下载交叉编译工具链,相关命令如
下:
$ cd /usr/local/ARM-toolchain
$ sudo wget http://releases.linaro.org/components/toolchain/binaries/6.1-2016.08/ar-
m-linux-gnueabi/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz
$ xz -d gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz
$ tar xvf gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar
接下来需要把交叉编译工具链的路径添加到 Ubuntu 系统的环境变量中去。在
/etc/bash.bashrc 文件中添加如下内容:
# Add ARM toolschain path
if[ -d/usr/local/ARM-toolchain/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi
] ; then
PATH=/usr/local/ARM-toolchain/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnuea
bi/bin:"${PATH}"
fi
然后执行 source /etc/bash.bashrc 命令使新的环境变量生效。
安装完成后,我们可以在终端执行 arm-linux-gnueabi-gcc –v 命令来查看交叉编
译工具链的版本信息,如下图所示:

20
第三章 嵌入式 Linux 系统移植环境搭建

图 3-6 交叉工具链版本信息

Fig.3-6 The Version Information of Cross Toolchain

3.2.3 其他开发工具和库的安装

1、Samba 服务器安装和配置
Samba 为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。使
用 Samba 可以在 Windows 上访问 Linux 上的共享文件,在嵌入式开发中使用 Samba
可以很方便的在 Window 系统中查看编辑宿主机上的源代码。
1)安装 Samba 服务器
在 Ubuntu 系统终端执行如下命令安装 Samba 服务器:
$ sudo apt-get install samba
2)配置 Samba 服务器
假 设 我 们 需 要 把 Ubuntu 系 统 下 的 felix 用 户 /home/felix/ 路 径 下 的
DevelopEnvironment 文件夹共享出来。首先需要在/etc/samba/smb.conf 文件中增加如
下配置项:
[Samba_Share]
comment = Samba Share
browseable = yes
path = /home/felix/ARM-DevelopEnvironment
writable = yes
valid = felix

21
广东工业大学硕士学位论文

接着运行 sudo smbpasswd -a felix 命令,设置登录 Samba 服务的密码,设置好


后重启 Samba 服务器:
$ sudo service smbd restart
$ sudo service nmbd restart
3)Window 访问 Linux 共享目录
在 Window 系统的 start 搜索栏输入 Ubuntu 系统的 IP 地址(例如\\192.168.1.108),
回车弹出登录窗口,输入 Samba 服务器的用户名和密码后,就可以在 Window 系统
与 Ubuntu 系统间复制文件。
2、安装版本管理工具 Git
Git 是 Linus Torvalds 为了帮助管理 Linux 内核源码而开发的一个开源分布式版
本控制软件,与 CVS, Subversion 等集中式版本控制工具不同,Git 不需要服务器端
软件支持。Git 工具给团队协作开发提供了极大的方便,它可以高效灵活的用来管
理我们自己的开发项目。现在,越来越多的著名项目采用 Git 来管理项目开发。
在 Ubuntu 系统中可以使用如下命令安装 Git 工具:
$ sudo apt-getinstallgit
$ sudo apt-get install git-doc git-svngit-email git-gui gitk
安装完成第一次使用 Git 需要进行如下设置:
$ git config--global user.name "你自己的用户名"
$ git config --global user.email "你自己的邮箱地址"
3、其他一些依赖库和工具
1)在 Ubuntu14.04 64 位系统中已经安装 32 位库,执行下列命令进行安装:
$ sudo apt-get install libc6:i386
$ sudo apt-get install lib32z1
2)安装设备树编译工具
我们在编译设备数源文件需要相应的设备树编译工具的支持,执行下来命令安
装设备树编译工具 device-tree-compiler:
$ apt-get install device-tree-compiler

22
第三章 嵌入式 Linux 系统移植环境搭建

3.3 本章小结

本章首先介绍了目标移植平台的硬件参数,然后详细阐述了嵌入式 Linux 系统
开发环境的搭建,包括 VMware 软件和 Ubuntu 系统的安装、交叉编译工具的安装
和其他在移植过程中需要使用的一些工具和相关函数库的安装。为后续嵌入式源代
码编译移植和调试准备好了开发环境。

23
广东工业大学硕士学位论文

第四章 移植引导加载程序 U-boot

在大部分嵌入式设备中,操作系统内核运行之前会先运行引导加载程序,它的
主要工作是初始化硬件设备,例如关闭芯片看门狗、屏蔽所有中断、禁用 MMU 和
缓存,初始化内存芯片,初始化输出显示设备等;规划好系统运行的内存空间,准
备好系统的运行环境;从启动设备上拷贝操作系统和文件系统到内存指定的地方,
跳转到内存指定的地方执行内核。U-boot 是嵌入式系统中最常使用的引导加载程序。

4.1 引导加载程序 U-boot 简介

U-Boot 是 Das U-Boot 的简称,其全称是 Universal Boot Loader,遵循 GPL 条款


的开放源码项目 [11]。最早由 DENX 软件工程中心的 Wolfgang Denk 基于 8xxrom 的
源码创建了 PPCBOOT 工程,此后不断添加对其他处理器的支持。后来,Sysgo Gmbh
把 ppcboot 移植到 ARM 平台上,创建了 ARMboot 工程。然后以 ppcboot 工程和
armboot 工程为基础,创建了 U-Boot 工程。2002 年 12 月 17 日第一个 U-Boot 版本
U-Boot-0.2.0 发布,同时 PPCBoot 和 ARMboot 停止维护,U-Boot 现在仍然由 DENX
的 Wolfgang Denk 维护。一开始 U-boot 的版本号是由 X.Y.Z 来表示的,从 0.2.0 一
直到 1.3.4,之后便开始使用年份加月份的表示方法。从 u-boot-2008.10 到现在的
u-boot-2016.11 平均每 3 个多月出一个新版本,每次代码的结构都会有一些修正和改
进,U-boot 从 u-boot-2014.04 这个版本开始加入了对设备树的支持。
U-Boot 被移植到包括主流的 PowerPC、ARM、X86、MIPS、NIOS、XScale 等
体系结构的上百种开发板上,成为功能最多、灵活性最强,并且开发最积极的开源
BootLoade[11]。U-boot 官方主页地址是 http://www.denx.de/wiki/U-Boot/WebHome。
U-boot 官方 Git 代码仓库地址是 http://git.denx.de/?p=u-boot.git。

4.2 Exyson4412 芯片启动模式选择

移植 U-boot 到新的目标板上,首先要对目标板上处理器芯片的启动方式、系统
时钟初始化、串口初始化、内存初始化以及目标板的内存地址空间分配有一个比较
清楚的认识,特别是要了解芯片的启动过程。

24
第四章 移植引导加载程序 U-boot

Exyson4412 芯片的 OM 引脚设置 Exyson4412 从不同的启动设备中加载程序,


如 NAND Flash、SD 卡、eMMC 卡、USB。

图 4-1 OM 引脚配置启动设备

Fig.4-1 OM Configuration For Selecting The Booting Device

目标板 Tiny4412 关于芯片启动方式的电路图 [12]如下图所示:

图 4-2 Tiny4412 OM 引脚配置

Fig.4-2 OM Configuration For Tiny4412

由图 4-1 和图 4-2 可知,XOM0,XOM1,XOM4,XOM5 都设置成 0,XOM2 和 XOM3


这两个脚分别接在 74LVC1G04 反向器的输入和输出上。XOM2 接 1 时,XOM3 为 0,
OM[5:1]为 00010,此时选择的是从 SD 卡(SDMMC_CH2)启动;XOM2 接 0 时,XOM3

25
广东工业大学硕士学位论文

为 1,OM[5:1]为 00100,此时选择的是从 eMMC(eMMC44_CH4)启动。目标板的启


动方式由目标板上的 S2 开关决定。
Exyson4412 芯片从 SD 卡启动时,iROM 会从 SD 卡偏移地址 512 字节处读入
8K 字节的数据存在 iRAM 地址 0x02021400 位置处。BL1 从 SD 卡偏移地址(512 +8K)
字节处读入 16K 字节的数据存在 iRAM 地址 0x02023400 处。因此 BL1 不能大于
8K ,BL2 不能大于 16K。当 BL2 启动后,它将存放在 SD 卡另外位置的完整操作
系统镜像和文件系统读入片外内存。

图 4-3 BL1 和 BL2 在 SD 卡的位置

Fig.4-3 The Location of BL1 and BL2 in SD Card

4.3 U-boot 移植分析

4.3.1 U-boot 源代码结构

我们可以使用 Git 工具从 U-boot 源代码仓库下载 U-boot 源码。通过列命令下载


u-boot-2016.11 这个版本的 U-boot 源码:
$ git clone git://git.denx.de/u-boot.git u-boot/
$ cd u-boot/
$ git checkout tags/v2016.11 -b u-boot-v2016.11-tiny4412
执行上面的命令后,我们把 u-boot 源代码下载在 u-boot/这个目录下,并且使用 Git
工具把 u-boot-2016.11 这个版本的 U-boot 源码 checkout 为 u-boot-v2016.11-tiny4412
分支。Ubuntu 终端执行下列命令可以查看 U-boot 的版本信息:
$ cd ~/u-boot/
$ make ubootversion
U-boot 源码目录一般可以分为三大类:第一类目录是与处理器体系结构或开发
板硬件直接相关;第 2 类目录是一些通用的函数或者驱动程序;第 3 类目录是 U-Boot
的应用程序、工具或者文档。U-Boot 的源码顶层目录说明如下:

26
第四章 移植引导加载程序 U-boot

arch 目录存放的是跟体系结构相关的关文件;
api 目录存放的是与体系结构无关的 API;
board 目录存放的 U-boot 已支持的开发板目录文件;
cmd 目录存放 U-Boot 命令相关的代码;
common 目录存放的是独立于处理器体系结构的通用代码;
configs 目录存放的是 U-boot 所支持的开发板配置文件;
disk 目录存放的是磁盘驱动相关的代码;
doc 目录存放的是 U-boot 相关的文档;
drivers 目录存放的是 U-boot 支持的通用设备驱动程序代码;
dts 目录存放的是编译设备树相关的文件;
examples 目录存放 U-Boot 的示例程序;
fs 目录存放的是文件系统相关的代码,例如 cramfs, ext2, jffs2 等;
include 目录存放的是一些头文件;
lib 目录存放的是通用的库文件;
Licenses 目录存放的是各种许可文件;
net 目录存放的是与网络协议栈相关的代码;
post 目录存放的是上电自检的代码;
scripts 目录存放的是各种编译脚本和 Makefiles 文件;
test 目录存放的是各种单元测试的文件;
tools 目录存放的是制作 S-Record 或者 U-Boot 格式的映像等工具。

4.3.2 U-boot 配置和编译

在 U-boot 源码目录 u-boot/configs/目录下可以看到很多开发板的配置文件,这些


配置文件的命名方式为 xxxx_defconfig(xxxx 为开发板名称)。以 origen 这款开发板
为例来说明 U-boot 的编译方法。在 U-boot 源码根目录 u-boot/下执行如下命令:
$ make distclean
$ make origen_defconfig
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
编译完成后,在 U-boot 源代码根目录下就生成了 origen 这款开发板对应的 u-boot.bin
二进制文件。

27
广东工业大学硕士学位论文

4.3.3 U-boot 启动流程分析

以 armv7 架构的 CPU 为例,U-boot 在启动过程中主要做的事情分为 2 部分,一


是 CPU 架构级的初始化工作,二是板级相关的初始化工作。CPU 架构级的初始化
工作主要包括关闭中断,设置 svc 模式,禁用 MMU、TLB,设置时钟、看门狗等。
板级相关的初始化工作主要包括堆栈环境的设置;代码重定向之前的板级初始化,
包括串口、环境变量等初始化工作;代码重定向之后的板级初始化,例如 eMMc、
Nand Flash、网卡、LCD 显示屏等的初始化工作;最后进入命令行状态,等待终端
输入命令以及对命令进行处理。
1、U-boot 代码执行入口
分 析 U-boot 的 代 码 执 行 入 口 , 首 先 要 分 析 U-boot 源 码 目 录 u-boot/ar-
ch/arm/cpu/u-boot.lds 这个链接脚本文件。u-boot.lds 链接脚本文件内容如下(内容有
省略):
....
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
...
. = 0x00000000;
. = ALIGN(4);
.text :
{
*(.__image_copy_start)
*(.vectors)
CPUDIR/start.o (.text*)
*(.text*)
}
...

28
第四章 移植引导加载程序 U-boot


从 u-boot.lds 链接脚本文件可知,U-boot 的代码入口函数是_start。armv7 架构的 CPU
的_start 定义在 U-boot 源代码目录的 u-boot/arch/arm/lib/vector.S 文件中:
...
_start:
b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
...
U-boot 执行_start 直接跳转到了 U-boot 源代码目录的 u-boot/arch/arm/cpu/armv7/-
start.S 文件的 reset 函数。
因此,分析 armv7 架构的 CPU 的 U-boot 启动流程就从 U-boot 源代码目录的
u-boot/arch/arm/cpu/armv7/start.S 文件的 reset 代码开始分析。
2、CPU 架构级的初始化代码分析
U-boot 源代码目录的 u-boot/arch/arm/ cpu/armv7/start.S 文件的 reset 部分主要代
码如下:
.globl reset
.globl save_boot_params_ret
#ifdef CONFIG_ARMV7_LPAE
.global switch_to_hypervisor_ret
#endif
reset:
/* Allow the board to save important registers */
b save_boot_params

29
广东工业大学硕士学位论文

save_boot_params_ret:
/*
* disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
* except if in HYP mode already
*/
mrs r0, cpsr
and r1, r0, #0x1f @ mask mode bits
teq r1, #0x1a @ test for HYP mode
bicne r0, r0, #0x1f @ clear all mode bits
orrne r0, r0, #0x13 @ set SVC mode
orr r0, r0, #0xc0 @ disable FIQ and IRQ
msr cpsr,r0
/*
* Setup vector:
* (OMAP4 spl TEXT_BASE is not 32 byte aligned.
* Continue to use ROM code vector only in OMAP4 spl)
*/
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
bic r0, #CR_V @V=0
mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register
/* Set vector address in CP15 VBAR register */
ldr r0, =_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
#endif
/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15

30
第四章 移植引导加载程序 U-boot

#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
bl cpu_init_crit
#endif
#endif
bl _main
这段 reset 部分的代码首先通过设置 CPSR 寄存器里设置 CPU 为 SVC 模式,禁
止中断;通过调用 cpu_init_cp15 函数,初始化协处理器 CP15,禁用 MMU 和 TLB;
再通过调用 cpu_init_crit 函数,进行一些关键的初始化动作,其中最主要的是调用
lowlevel_init 函数为跳转到_main 函数运行准备好运行环境;最后跳转到_main 函数
中去执行。
3、板级初始化代码分析
板 级 初 始 化 代 码 的 入 口 就 是 _main 函 数 , 该 函 数 定 义 在 U-boot 源 代 码
u-boot/arch/arm/lib/crt0.S 文件中。
_main 函数完成的主要工作总结为:
1)设置 C 代码的运行环境,为接下来调用 board_init_f 函数做准备。
设置 堆栈 ,为执行 C 语言代码做好准备。如果使用了 U-boot 的 SPL(由
CONFIG_SPL_BUILD 宏定义)功能,则可以由 CONFIG_SPL_STACK 宏定义堆栈
基 址 ; 否 则 使 用 CONFIG_SYS_INIT_SP_ADDR 宏 定 义 堆 栈 基 址 。 接 着 调 用
board_init_f_alloc_reserve 函数,为 U-boot 的全局变量 GD (global data) 数据结构分
配内存空间;再调用 board_init_f_init_reserve 函数,对全局变量 GD 进行初始化。
2)如果当前运行的是 SPL 模式,则进入_main 函数就直接返回不执行后面的初
始化函数。正常的 U-boot 模式会继续执行 board_init_f 函数,在 board_init_f 函数中
调用 initcall_run_list 函数依次执行 init_sequence_f 函数数组里面的函数,例如 U-boot
驱 动 模 型 初 始 化 、 环 境 变 量 的 初 始 化 、 串 口 的 初 始 化 、 内 存 的 初 始 化 、 U-boot
relocation 操作前的环境初始化等。
4)执行 U-boot relocation 操作,把内存中的 u-boot 进行重定位;清除 BBS 段。
5)调用 board_init_r 函数,在 board_init_r 函数中调用 initcall_run_list 函数,执
行 init_sequence_r 函数数组里面的函数,完成后续的板级初始化操作。最后 U-boot
运行到了 run_main_loop 函数,并且在 run_main_loop 函数进入命令行状态,等待终

31
广东工业大学硕士学位论文

端输入命令以及对命令进行处理。

4.3.4 U-boot 的设备驱动模型

U-boot 从 v2014.04 这个版本开始加入了对设备树的支持,引入了驱动模型


(driver model),简称为 DM。与 Linux 内核的设备驱动模型类型,U-boot 的驱动模
型和设备树相互配合使用,不仅统一设备驱动框架、提供设备树视图,还降低设备
驱动的开发复杂度。
U-boot 的驱动模型主要有四个组成部分,分别是 udevice、driver、uclass 和
uclass_driver。
udevice 是指具体设备的抽象,对应驱动是 driver,driver 主要负责和硬件通信,
为 uclass 提 供 实 际 的 操 作 集 。 udevice 的 数 据 结 构 定 义 在 U-boot 源 码 的
u-boot/include/dm/device.h 文件中。
uclass 可以理解为一些具有相同属性的 udevice 提供对外操作的接口,uclass 的
驱动是 uclass_driver,主要为上层提供接口。uclass 的数据结构定义在 U-boot 源码
的 u-boot/include/dm/uclass.h 文件中。
uclass_driver 对应 uclass 的驱动程序,主要提供如绑定 udevice 的一些操作。
uclass_driver 的数据结构在 U-boot 源码的 u-boot/include/dm/uclass.h 中定义。
以 origen 开发板的 U-boot 驱动模型的 serial 驱动为例,要使用这个 serial 驱动,
需要在 U-boot 源代码目录 u-boot/configs/下对应的 origen_defconfig 配置文件中定义
下列两个宏:
CONFIG_DM=y
CONFIG_DM_SERIAL=y
接下来还要 U-boot 源代码目录 u-boot/arch/arm/dts/exynos4210-origen.dts 设备树文件
中添加 serial 设备节点信息:
/dts-v1/;
#include "skeleton.dtsi"
/{
aliases {
console = "/serial@e2900000";
};

32
第四章 移植引导加载程序 U-boot

serial@e2900000 {
compatible = "samsung,exynos4210-uart";
reg = <0xe2900000 0x100>;
interrupts = <0 51 0>;
id = <0>;
};
};
U-boot 通过调用 initf_dm 函数来初始化驱动模型,从设备树二进制文件中解析
udevice 和 uclass,建立了 udevice 和 uclass 之间的绑定关系。对应的 serial driver 会
执行 probe 函数探测是否有与之相对应的 serial 设备。

4.3.5 U-boot 移植总体思路分析

在 Exyson4412 芯片上电启动首先启动 iROM 里面的程序,iROM 里面的程序会


拷贝 BL1 到 iRAM 里面去执行,接着 BL1 会继续拷贝 BL2 到 iRAM 中去运行。
Samsung 公司已经提供了 BL1 二进制文件,大小为 8K。BL2 就是引导加载程序 U-boot
的二进制文件,其大小被限制在了 16K,但是正常编译出来的 u-boot.bin 已经远远大
于 16K 了。因此,我们要使用 U-boot 提供的 SPL(Secondary Program Loader)功
能来解决这个问题。
SPL 是 U-boot 中 独 立 的 一 个 代 码 分 支 , 复 用 了 U-boot 的 代 码 , 由
CONFIG_SPL_BUILD 配置项控制,它把 U-boot 的执行分为了 2 个阶段。SPL 是
U-boot 第一阶段执行的代码,完成芯片级、板级的一些初始化操作,最主要的是初
始化时钟和片外内存、加载 U-boot 第二阶段的代码并跳转到内存中去执行这部分代
码。因此,在移植引导加载程序 U-boot 到 Exyson4412 目标板时,要使能 U-boot 的
SPL 功能。
U-boot 支持 ARM 架构的开发板比较多,在移植的过程中可以选择与所要移植
的目标板采用相同 SoC 的开发板或者是相同 CPU 核的开发板作为参考。本文移植
U-boot(版本为 u-boot-v2016.11)到 Exyson4412 目标板参考了 U-boot 已经支持的
origen 开发板。origen 开发板采用的 SoC 是 Exynos4210,与 Exyson4412 芯片同属
于 Samsung Exyson4 系列的芯片,并且支持 U-boot 的 SPL 功能。
在移植的过程中,先参考 origen 开发板添加 Exyson4412 目标板 U-boot 的代码

33
广东工业大学硕士学位论文

结构并且编译通过,接着借助目标板上的 LED 指示灯进行 SPL 部分代码的调试。


SPL 部分的正常运行起来后,使能串口调试功能,移植 U-boot 第二阶段代码。

4.4 U-boot 在目标板上的移植

4.4.1 U-boot 源码中添加目标板目录和文件

参考 origen 开发板,在 U-boot 源码中添加 Tiny4412 目标板的目录和配置文件,


并修改相应的配置文件。
1、添加目标板相应的目录文件
在 Ubuntu 终端进入在 U-boot 源代码 u-boot/目录下,执行下列命令添加 Tiny4412
板级目录和配置文件:
$ cd board/samsung/
$ cp origen tiny4412 –raf
$ mv tiny4412/origen.c tiny4412/tiny4412.c
$ mv tiny4412/tools/mkorigenspl.c tiny4412/tools/mktiny4412spl.c
$ cd ../../
$ cp include/configs/origen.h include/configs/tiny4412.h
$ cp configs/origen_defconfig configs/tiny4412_defconfig
$ cd arch/arm/dts/
$ cp exynos4412-origen.dts exynos4412-tiny4412.dts
2、修改配置文件,具体修改参考附录 A U-boot 源码中添加目标板目录和文件代
码。
1) 修改 board/samsung/tiny4412/Kconfig;
2)修改 board/samsung/tiny4412/Makefile;
3)修改 arch/arm/mach-exynos/Kconfig;
4)修改 arch/arm/mach-exynos/Makefile;
5)修改 arch/arm/mach-exynos/exynos4_setup.h;
6)修改 arch/arm/dts/Makefile,用于编译 Tiny4412 开发板设备树;
7)修改 board/samsung/tiny4412/tools/mktiny4412spl.c 文件。
添加修改完相关代码目录和配置文件后,执行如下命令进行编译 U-boot:

34
第四章 移植引导加载程序 U-boot

$ make distclean
$ make tiny4412_defconfig
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
U-boot 编译完后,在源码根目录下生成了 u-boot-spl.bin 和 u-boot.bin 二进制文件。
至此,完成了在 U-boot 中添加了目标板的目录和配置文件。

4.4.2 使用目标板上的 LED 灯进行代码调试

在调试 U-boot 代码过程中,通常会使用目标板上的 LED 灯和串口打印输出来进


行调试。调试 U-boot 汇编源码时因为堆栈指针还未设置,无法运行 C 语言编写的代
码导致串口打印输出无法使用,通常在这种情况下需要借助开发板上的 LED 来进行
调试。本小节通过点亮 Tiny4412 核心板上的 LED 灯为后续调试 U-boot 代码做好准
备。
从《Tiny4412-1412-Schematic.pdf》原理图上可以看到板子上的四个 LED 硬件连
接如下图所示:

图 4-4 Led 灯原理图

Fig.4-4 The Schematic of Led

LED1~LED4 分 别 跟 Exyson4412 芯 片 的 GPM4_0~GPM4_3 引 脚 相 连 。 要 点 亮


Exynos4412 GPM4 管脚上的 LED 灯,需要设置 GPM4CON 和 GPM4DAT 寄存器。
LED 灯的代码添加在 arch/arm/cpu/armv7/start.S 文件的末尾:
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 691e5d3..4496f2f 100755
--- a/arch/arm/cpu/armv7/start.S

35
广东工业大学硕士学位论文

+++ b/arch/arm/cpu/armv7/start.S
@@ -47,6 +47,7 @@ save_boot_params_ret:
orr r0, r0, #0xc0 @ disable FIQ and IRQ
msr cpsr,r0
+ bl light_led
/*
* Setup vector:
* (OMAP4 spl TEXT_BASE is not 32 byte aligned.
@@ -63,6 +64,8 @@ save_boot_params_ret:
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
#endi
+ .globl light_led
+light_led:
+ ldr r0,=0x110002E0 @ set GPM4CON Register
+ ldr r1,=0x00001111
+ str r1,[r0]
+ ldr r0,=0x110002E4 @ set GPM4DAT Register
+@ mov r1,#0xFE @ light All led1 on
+@ mov r1,#0xFD @ light All led2 on
+@ mov r1,#0xFB @ light All led3 on
+@ mov r1,#0xF7 @ light All led4 on
+ mov r1,#0xF0 @ light All led on
+ str r1,[r0]
+ mov pc, lr
把 Samsung 提供的 sd_fuse 文件夹拷贝到 U-boot 根目录下。sd_fuse 文件夹下包
含了 Exynos4412 芯片启动所需的二进制固件 E4412_N.bl1.bin 和 SD 卡烧写脚本
sd_fusing.sh。
重新编译 U-boot 源码,在 spl 目录下生成 tiny4412-spl.bin 文件。通过 SD 卡烧
写脚本 sd_fusing.sh 把 E4412_N.bl1.bin 和 tiny4412-spl.bin 烧写到相应的 SD 卡位置。

36
第四章 移植引导加载程序 U-boot

把 SD 卡插到 Tiny4412 开发板的 SD 卡槽上,选择从 SD 卡启动,开发板上电后应


该可以看到点亮了相应的 LED 灯。

4.4.3 初始化 Exynos4412 芯片时钟

Exynos4412 芯片的时钟域如下图所示:

图 4-5 Exynos4412 芯片的时钟域

Fig.4-5 Exynos 4412 SCP Clock Domains

CPU_BLK:内含 Cortex-A9 MPCore 处理器、L2 cache 控制器、CoreSight。


CMU_CPU 用于给这些部件产生时钟 。
DMC_BLK:包含 DRAM 内存控制器、安全子系统、通用中断控制器。
LEFTBUS_BLK 和 RIGHTBUS_BLK:它们是全局的数据总线,用于在 DRAM
和其他子模块之间传输数据。
CMU_TOP:用于给这些模块产生时钟。
Exynos4412 有 3 个初始时钟源:
1、XRTCXTI 引脚:接 32KHz 的晶振,用于实时钟(RTC)。
2、XXTI 引脚:接 12M ~50 MHz 的晶振,用于向系统提供时钟,也可以不接。
3、XUSBXTI 引脚:接 24MHz 的晶振,用于向系统提供时钟。
在友善之臂 Tiny4412 的开发板中,XRTCXTI 上没有外接晶振,系统时钟来源是
XUSBXTI 引脚上接的 24MH 晶振,如下图所示:

37
广东工业大学硕士学位论文

图 4-6 Tiny4412 开发板的晶振连接

Fig.4-6 The Crystals connected of Tiny4412 Board

从原理图上可知, Tiny4412 开发板外接 24MHz 的晶振;通过锁相环(PLL)把 24MHZ


的频率提升为合适的频率供其他模块使用。
Exyson4412 主要的 PLL 有:APLL、MPLL、EPLL 和 VPLL、USB PHY 和 HDMI
PHY 。 APLL 用 于 CPU_BLK , 它 也 可 以 给 DMC_BLK 、 LEFTBUS_BLK 、
RIGHTBUS_BLK 和 CMU_TOP 提 供 时 钟 。 MPLL 用 于 给 DMC_BLK 、
LEFTBUS_BLK、RIGHTBUS_BLK 和 CMU_TOP 提供时钟。EPLL 主要给音频模块
提供时钟。VPLL 主要给视频系统提供 54MHz 时钟,给 G3D(3D 图形加速器)提供
时钟。USB PHY 给 USB 子系统提供 30MHz 和 48MHz 时钟。HDMI PHY 用于给
HDMI 接口产生 54MHz 时钟。
Exynos4412 芯片时钟体系相关的详细介绍介绍参考《Exynos4412 SCP_Users
Manual_Ver.0.10.00_Preliminary.pdf》的第七章节。把 Exyson4412 芯片主要的时钟模
块的频率设置为如下值:
APLL= 1400 MHz
MPLL=800 MHz
EPLL=96 MHz
VPLL=108 MHz
ARMCLK = 1400 MHz
ACLK_COREM0 = 350 MHz

38
第四章 移植引导加载程序 U-boot

ACLK_COREM1 = 188 MHz


PERIPHCLK = 1400 MHz
ATCLK = 214 MHz
SCLK_DMC = 400 MHz
ACLK_DMCD = 200 MHz
ACLK_DMCP = 100 MHz
ACLK_400_MCUISP = 400 MHz
ACLK_200 = 160 MHz
ACLK_100 = 100 MHz
ACLK_160 = 160 MHz
ACLK_133 = 133 MHz
时钟初始化关键代码请参考附录 B Exyson4412 时钟初始化关键代码。

4.4.4 初始化调试串口

在上一节我们初始化完成了 Exynos4412 的时钟,接下来把目标板的调试串口用


起来,通过串口打印输出可以看到更多的调试信息。

图 4-7 调试串口原理图

Fig.4-7 The Schematic of Debug Serial Port

从图 4-7 上我们可看出,Tiny4412 开发板的调试串口使用的 uart0。串口初始化


一般步骤为:
1、选择 UART 的时钟源;

39
广东工业大学硕士学位论文

2、设置 UART 对应的 GPIO 引脚为 UART 功能;


3、设置波特率:设置 UBRDIVn 寄存器、UFRACVALn 寄存器;
4、设置传输格式:设置 ULCONn 寄存器;
5、设置串口工作模式:设置 UCONn 寄存器;
6、设置 UFCONn 寄存器、UFSTATn 寄存器;
对应的代码修改参考附录 C Exyson4412 串口初始化关键代码。
重新编译 U-boot 代码,下载 tiny4412-spl.bin 文件到 SD 卡,目标板选择从 SD
卡启动后,目标板的 Com0 串口上会输出如下调试字符串:
UART DEBUG enable .... !!!

4.4.5 初始化内存拷贝 U-boot 到片外内存运行

Tiny4412 开发板原理图《Tiny4412-1412-Schematic.pdf》可以看出,Tiny4412 开
发板使用 2 片 K4B4G1646B-HCK 内存芯片并联组成了数据位为 32bit 1G 大小的内
存,内存芯片接在 Exynos4412 芯片的 DMC0 上,使用了一个 chip(chip0),内存地
址空间为 0x40000000-0x80000000。
内存初始化的关键代码参考附录 D Exyson4412 内存初始化关键代码。
Tiny4412 开发板上片外的 DDR 内存初始化完成之后,可以把启动设备上完整的
u-boot.bin 拷贝到片外 DDR 内存中去,并跳转到片外 DDR 内存中去执行完整的
U-boot 程序。
特别要注意启动设备的时钟要求,如果启动设备的时钟设置不正确,这些内置
函数可能无法正常工作。如果启动设备是 SD 卡或者是 eMMC 卡,要把 SD 卡、eMMC
卡的时钟设置为 20MHz 这些内置的拷贝函数才能正常工作。重新设置 mmc2 的时
钟频率为 20MHz,相应的代码修改如下:
diff --git a/arch/arm/mach-exynos/clock_init_exynos4412.c b/arch/arm/mach-ex-
ynos/clock_init_exynos4412.c
index cd70185..4617c8c 100644
--- a/arch/arm/mach-exynos/clock_init_exynos4412.c
+++ b/arch/arm/mach-exynos/clock_init_exynos4412.c
@@ -298,9 +298,9 @@ void system_clock_init(void)
* DOUTmmc3 = MOUTmmc3 / (ratio + 1) = 100 (7)

40
第四章 移植引导加载程序 U-boot

* sclk_mmc3 = DOUTmmc3 / (ratio + 1) = 50 (1)


* DOUTmmc2 = MOUTmmc2 / (ratio + 1) = 100 (7)
- * sclk_mmc2 = DOUTmmc2 / (ratio + 1) = 50 (1)
+ * sclk_mmc2 = DOUTmmc2 / (ratio + 1) = 20 (4)
*/
- set = MMC2_RATIO(7) | MMC2_PRE_RATIO(1) | MMC3_RATIO(7)
+ set = MMC2_RATIO(7) | MMC2_PRE_RATIO(4) | MMC3_RATIO(7)
|MMC3_PRE_RATIO(1);
对于 Tiny4412 开发板,SD 卡上存放 U-boot 代码的位置设置如下:

图 4-8 SD 卡布局

Fig.4-8 The Layout of SD Card

相应的代码修改如下:
diff --git a/arch/arm/mach-exynos/lowlevel_init.c b/arch/arm/mach-exynos/-
lowlevel_init.c
index 361727d..6a05fda 100644
--- a/arch/arm/mach-exynos/lowlevel_init.c
+++ b/arch/arm/mach-exynos/lowlevel_init.c
@@ -229,7 +229,10 @@ int do_lowlevel_init(void)
#endif
#endif
mem_ctrl_init(actions & DO_MEM_RESET);
+#ifndef TINY4412
tzpc_init();
+#endif
}
return actions & DO_WAKEUP;

41
广东工业大学硕士学位论文

diff --git a/include/configs/tiny4412.h b/include/configs/tiny4412.h


index 281838d..3a02f9e 100644
--- a/include/configs/tiny4412.h
+++ b/include/configs/tiny4412.h
@@ -102,17 +102,33 @@
#define CONFIG_SYS_MMC_ENV_DEV 0
#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */
#define RESERVE_BLOCK_SIZE (512)
-#define BL1_SIZE (16 << 10) /*16 K reserved for BL1*/
-#define CONFIG_ENV_OFFSET (RESERVE_BLOCK_SIZE + BL1_SIZE)
+#define BL1_SIZE (8 << 10) /* 8K reserved for BL1*/
+#define BL2_SIZE (16 << 10) /*16 K reserved for BL2/SPL*/
+#define CONFIG_ENV_OFFSET (RESERVE_BLOCK_SIZE + BL1_SIZE +
BL2_SIZE)
#define CONFIG_SPL_LDSCRIPT "board/samsung/common/exynos-uboot-spl.lds"
#define CONFIG_SPL_MAX_FOOTPRINT (14 * 1024)
#define CONFIG_SYS_INIT_SP_ADDR 0x02040000
#define COPY_BL2_SIZE 0x80000
#define BL2_START_OFFSET ((CONFIG_ENV_OFFSET +
CONFIG_ENV_SIZE)/512)
-#define BL2_SIZE_BLOC_COUNT (COPY_BL2_SIZE/512)
+#define BL2_SIZE_BLOC_COUNT (COPY_BL2_SIZE/512) /* u-boot size is
512K */
重新编译 U-boot 源代码,通过烧写脚本并把相应的 u-boot-spl.bin 和 u-boot.bin
文件烧写到 SD 卡。设置 Tiny4412 开发板从 SD 卡启动,启动后可以看到串口输出
如下信息:

42
第四章 移植引导加载程序 U-boot

图 4-9 串口输出信息

Fig.4-9 The Log of Debug Serial Port

调试串口输出图 4-9 的调试信息,说明片外内存初始化成功,并且 BL2 把 U-boot


代码从 SD 卡拷贝到片外内存中并在内存中执行。
到这里,已经把 U-boot 移植最核心的部分移植完成。

4.5 本章小结

本章的主要内容是移植 U-boot 到目标板。首先简单介绍了引导加载程序 U-boot,


分析了 Exyson4412 芯片的启动模式选择;其次对 U-boot 移植进行了详细的分析,
包括 U-boot 源码结构、配置和编译,分析了 U-boot 的启动流程,介绍了 U-boot 的
设备驱动模型;最后给出来将 U-boot-2016.11 移植到 Tiny4412 开发板上的详细实现
过程。

43
广东工业大学硕士学位论文

第五章 嵌入式 Linux 内核移植

5.1 Linux 内核相关介绍

Linux 是目前最受欢迎的符合 POSIX 标准的类 Unix 操作系统,最早是由 Linus


Torvalds 为提供自由免费的类 Unix 操作系统而开发出来的。Linux 是一个宏内核系
统,其设备驱动程序以模块化的形式编写,并可以在系统运行期间直接装载或卸载。
Linux 系统具有很高的稳定性和可靠性,可以根据自己的需要对 Linux 内核源码进
行修改和裁剪,Linux 支持 X86、ARM、MIPS、PowerPC 等多种体系结构的处理器,
具有完善的网络通信功能,支持几乎所有流行的文件系统,例如 ext2、ext3、ext4、
yaffs 等。

5.1.1 Linux 内核源码下载

Linux 内核源码可以在 https://www.kernel.org/网站下载。一般情况下使用是 Git


工具从 Linux 内核源代码仓库下载 Linux 内核源码仓库,方便在开发的过程中管理
源代码。通过如下命令下载 Linux 内核源码:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
下载完成后,在下载的目录文件夹下多出了一个 linux-stable 文件夹,这个文件
里面存放的就是 Linux 内核源码。接着执行下来命令:
$ cd linux-stable/
$ git checkout tags/v4.4.4 -b linux-4.4.4-tiny4412
执行完上面的命令后, Git 工具创建了 linux-4.4.4-tiny4412 这个新的分支,并把
Linux 内 核 v4.4.4 这 个 版 本 的 源 码 从 Linux 内 核 源 码 仓 库 checkout 出
linux-4.4.4-tiny4412 分支。后面的分析和移植就基于这个分支的 Linux 源码来展开。

5.1.2 Linux 内核源代码目录结构

Linux 内核源代码包括三个主要部分:
1、内核核心代码,包 Linux 系统的各个子系统和子模块。
2、其它非核心代码,例如库文件、固件集合、KVM(虚拟机技术)等。

44
第五章 嵌入式 Linux 内核移植

3、编译脚本、配置文件、帮助文档、版权说明等辅助性文件。
下图示使用 ls 命令看到的内核源代码的顶层目录结构如图 5-1 所示。

图 5-1 Linux 内核源码目录

Fig.5-1 The Linux Kernel Source Directory

主要目录描述如下:
include/ -- Linux 内核的头文件,主要提供给外部模块(例如用户空间代码)
使用。
kernel/ -- Linux 内核的核心代码。
mm/ -- 内存管理子系统代码。
fs/ -- 虚拟文件系统(VFS,Virtual File System)的代码。
net/ -- 网络相关代码,实现了各种常见的网络协议,如 TCP/IP 等。
ipc/ -- IPC(进程间通信)子系统代码。它包含了共享内存、信号量以及其他形
式 IPC 的代码。
arch/ -- 与体系结构相关的代码。
init/ -- Linux 系统启动初始化相关的代码。
block/ -- 块设备管理相关的代码。
sound/ -- 音频相关的驱动及其子系统代码。
drivers/ -- 设备驱动代码。
lib/ -- 内核中使用的库函数。
crypto/ -- 加密、解密相关的库函数。
security/ -- Linux 安全模型的代码,例如 SELinux。
virt/ -- 提供虚拟机技术(KVM 等)支持的代码。
usr/ -- 用于生成 initramfs 的代码。
firmware/ -- 存放第三方设备的固件。
samples/ -- 一些示例代码。

45
广东工业大学硕士学位论文

tools/ -- 一些常用工具,如性能剖析、自测试等。
Kconfig, Kbuild, Makefile, scripts/ -- 用于内核编译的配置文件、脚本等。
COPYING -- 版权声明。
MAINTAINERS -- 维护者名单。
CREDITS -- Linux 主要的贡献者名单。
REPORTING-BUGS -- Bug 上报的指南。
Documentation, README -- 帮助、说明文档。

5.1.3 Linux 内核的整体架构

Linux 内核只是 Linux 操作系统一部分,如图 5-2 所示。Linux 系统可以分为用


户空间和内核空间。用户空间包含了用户的应用程序、C 库,内核空间包括系统调
用、内核、以及与平台架构相关的代码。Linux 内核向下管理系统的所有硬件设备;
向上它通过系统调用向 Library Routine(例如 C 库)或者其它应用程序提供接口。

图 5-2 GNU/Linux 操作系统的基本体系结构

Fig.5-2 GNU/Linux Operating System's Basic Architecture

Linux 内核的整体架构如图 5-3 所示:

46
第五章 嵌入式 Linux 内核移植

图 5-3 Linux 内核的整体架构

Fig.5-3 Overall Architecture of the Linux Kernel

根据内核的核心功能,Linux 内核可以大概分为 5 个子系统,分别负责如下的功能:


1、进程管理、调度子系统(Process Scheduler),主要负责管理 CPU 的硬件资源,
使各个进程可以比较公平的方式使用 CPU 资源。
2、内存管理子系统(Memory Manager),主要负责管理内存资源,使各个进程
安全地使用机器的内存资源,提供虚拟内存机制让进程使用多于系统可用 Memory
的内存。
3、虚拟文件子系统(Virtual File System)。Linux 内核把 NAND Flash、Nor Flash
等存储设备、输入输出设备、显示设备等外设按照功能的不同,抽象为统一的文件
操作接口,将设备同对应的文件系统联系起来,这样就可以使用文件操作接口 open、
close、read、write 等函数来访问。
4、网络子系统(Network)。负责管理系统的网络设备,并实现许多网络标准协
议。
5、进程间通信子系统(Inter-Process Communication),主要负责 Linux 系统进
程之间的通信。

5.1.4 Linux 内核的配置和编译

Linux 内核的配置和编译由三个部分构成,它们分别是:
1、Makefile:定义了如何编译 Linux 内核文件;

47
广东工业大学硕士学位论文

2、配置文件:给用户提供配置选择的功能;
3、配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)
和配置用户界面(提供基于字符界面、基于 Ncurses 图形界面以及基于 Xwindows
图形界面的用户配置界面) [13]。
一般配置内核常用的命令有如下 4 种[14]:
1、make config:基于文本模式的交互式配置。
2、make menuconfig:基于文本模式的菜单型配置界面。
3、make oldconfig:使用已有的配置文件(.config),配置过程中会询问新增的
配置选项。
4、make xconfig:图形化的配置界面,需安装图形化系统。
其中 make menuconfig 是最常用的内核配置方式,在 Linux 内核源码根目录下执行:
$ make menuconfig ARCH=arm
命令出现 Linux 内核配置界面,如图 5-4 所示:

图 5-4 Linux 内核配置界面

Fig.5-4 The Linux Kernel Configuration Interface

在配置的过程中,使用键盘的上下键来选择相应的选项。空格键可以更改相应的选
项的属性:
[*]把此项编入系统内核
[M]把此项以驱动模块的形式编译。
[]不选择编译此项。
配置完成后根据提示保存,在 Linux 内核源码根目录下会生成一个隐藏的.config 文

48
第五章 嵌入式 Linux 内核移植

件,这个配置文件就包括 Linux 内核所有的配置信息。


Linux 内核源码提供了其支持的开发板配置文件,以 ARM 架构的处理器为例,
在内核源码根目录下的 arch/arm/configs 目录下存放了相应开发板的配置文件,配置
文件的命名方式为 xxx_defconfig(xxx 一般为 CPU 型号或者是开发板名称)。在 Linux
内核源码根目录执行 make xxx_defconfig 命令,根目录下会生成相应的.config 配置
文件。以编译 Exyson4210 处理器的 origen 开发板为例,其编译方法是在 Linux 内核
源码根目录执行下列命令:
$ make ARCH=arm origen_defconfig
$ make ARCH=arm uImage CROSS_COMPILE=arm-linux-gnueabi-
编译完成后,会在 Linux 内核源码根目录下的 arch/arm/boot 目录下生成 uImage 二
进制内核镜像。

5.2 ARM Linux 内核启动过程分析

U-boot 启动 Linux 内核是通过 bootm_headers_t images 这个数据结构来传递参数


的,这个结构体数据会存放在内存指定的位置。U-boot 会获取 Linux 内核、文件系
统和设备树的相关信息,然后把它们加载到指定的内存位置,设置好启动参后就跳
转到内核所在的地址开始执行。到这里,U-boot 的生命周期结束,Linux 内核开始
执行。
Linux 内核在启动过程中主要分成两个阶段:第一阶段是从 arch/arm/kernel-
/head.S 跳转到 start_kernel 函数之前的阶段,这个阶段主要由汇编语言实现。这个
阶段主要做的事情是:设置 CPU 为 SVC 模式,关闭所有中断;获取 CPU ID,提取
相应的 proc info;验证 tags 或者 dtb;创建临时内核页表的页表项;设置并使能 MMU。
第二阶段是执行 start_kernel 函数 [15]。
1、调用 setup_arch()函数进行与体系结构相关的初始化工作。setup_arch()函数
定义在 arch/arm/kernel/Setup.c,它首先对进行处理器内核部分的初始化,接着调用
bootmem_init()函数对 meminfo 结构进行内存结构的初始化,最后调用 paging_init()
函数开启 MMU,创建内核页表,映射物理内存和 IO 空间。
2、创建异常向量表和初始化中断处理函数。
3、初始化内核核心进程调度器和时钟中断处理机制。

49
广东工业大学硕士学位论文

4、设置串口控制台。串口的初始化工作在 U-boot 阶段已经完成了,ARM Linux


通过设置一个串口做为内核的控制台,可以在 Linux 内核启动过程中通过串口输出
信息了解系统的启动进程和状态 [19]。
5、初始化系统 cache,为动态内存分配,创建虚拟文件系统(VirtualFile System)
及页缓存等提供缓存。
6、初始化内存管理,检查内存大小以及内存的使用情况。
7、初始化系统的进程间通信机制(IPC)。
当完成以上所有的初始化工作后,start_kernel()函数会调用 rest_init()函数创建系
统的 init 进程完成内核的启动。Init 进程通过 U-boot 传递过来的命令行参数或者是
设备树提供的参数来挂载根文件系统,执行用户指定的命令。
初始化工作全部结束后,Linux 内核调用 cpu_idle()函数使系统处于闲置状态并
等待用户程序的执行。至此,整个 Linux 内核启动过程结束。

5.3 移植 Linux 内核到目标板

5.3.1 Linux 内核源码中添加目标板配置文件

移植使用了设备树的 Linux 内核,不用在内核源码目录 arch/arm/plat-xxx 和


arch/arm/mach-xxx 添加修改相应的板级硬件信息,内核从可以通过设备树文件节点
的 reg、interrupts 等属性得到硬件设备相关的信息。因此,移植引入设备树的 ARM
Linux 内核只需要添加相应的配置文件,而不用去大量修改内核源码目录下板级相
关文件,大大简化了 Linux 内核移植的工作。
Linux-4.4 的内核对 Exyson4 系列芯片的支持比较完善了,Exyson4412 芯片属于
Exyson4 系列,在移植的时候可以直接复用这些相关代码。在移植 Linux-4.4 内核到
目标板前,要在 Linux 内核源码下添加目标板的设备树文件和目标板的配置文件。
对 于 ARM 架 构 的 芯 片 , 设 备 树 文 件 存 放 在 Linux 内 核 源 码 根 目 录 下 的
arch/arm/boot/dts 目 录 下 , 目 标 板 配 置 文 件 存 放 在 Linux 内 核 源 码 根 目 录 下 的
arch/arm/configs 目录下。
设 备 树 文 件 直 接 复 用 内 核 源 码 根 目 录 下 的 arch/arm/boot/dts/exynos-
4412-tiny4412.dts 这 个 文 件 , 目 标 板 配 置 文 件 参 考 Linux 内 核 源 码 根 目 录 下 的
arch/arm/configs/exynos4_defconfig 这个文件。在 Linux 内核源码目录执行如下命令

50
第五章 嵌入式 Linux 内核移植

添加相应的配置文件:
$ cd arch/arm/boot/dts/
$ cp exynos4412-tiny4412.dts exynos4412-tiny4412SDK.dts
$ cp arch/arm/configs/exynos4_defconfig arch/arm/configs/tiny4412SDK_defconfig
通过修改 Linux 内核源码根目录下的 arch/arm/boot/dts/Makefile 文件,使内核在编译
过程中编译新添加的 exynos4412-tiny4412SDK.dts 文件,对应的修改如下:
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 30bbc37..0410e7f
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -115,6 +115,7 @@ dtb-$(CONFIG_ARCH_EXYNOS4) += \
exynos4412-origen.dtb \
exynos4412-smdk4412.dtb \
exynos4412-tiny4412.dtb \
+ exynos4412-tiny4412SDK.dtb \
exynos4412-trats2.dtb
dtb-$(CONFIG_ARCH_EXYNOS5) += \
exynos5250-arndale.dtb \

5.3.2 根据目标板硬件裁剪 Linux 内核

在上一节中,我们根据参考配置文件添加了移植目标板的配置文件,这一小节
根据目标板硬件修改 tiny4412SDK_defconfig 配置文件,裁剪 Linux 内核。在 Linux
内核源码目录执行命令:
$ make ARCH=arm tiny4412SDK_defconfig
$ make ARCH=arm menuconfig
在配置界面进行配置:

51
广东工业大学硕士学位论文

图 5-5 Tiny4412 开发板 Linux 内核配置界面

Fig.5-5 The Linux Kernel Configuration Interface of Tiny4412

配置完成后,修改 arch/arm/boot/dts/exynos4412-tiny4412SDK.dts 文件,在 chosen 中


增加了 bootargs 的设置:
chosen {
stdout-path = "/serial@13800000";
bootargs = "root=/dev/ram0 rw rootfstype=ext4 console=ttySAC0,115200
init=/linuxrc earlyprintk";
};
上面设置 bootargs 表示的意思是 Linux 系统使用的根文件系统是 Ramdisk,可读写,
文件系统类型是 ext4 格式,串口终端使用 ttySAC0,波特率是 115200,earlyprintk
用于打印内核启动早期的一些 log。
具体的修改请参考附录 E Linux 内核移植代码。修改完成后,执行命令:
$ make ARCH=arm uImage CROSS_COMPILE=arm-linux-gnueabi-
编译 Linux 内核。编译完成后,会在 Linux 内核源码根目录下的 arch/arm/boot 目录
下生成 uImage 二进制内核镜像,在 arch/arm/boot/dts/目录下会生成目标板上用的设
备树镜像文件 exynos4412-tiny4412SDK.dtb。

5.3.3 使用 U-boot 启动 Linux 内核

在 第 四 章 已 经 把 移 植 好 的 U-boot 烧 进 SD 卡 , 接 下 来 把 uImage 、 和
exynos4412-tiny4412SDK.dtb 拷贝进 SD 卡,目标开发板选择从 SD 卡启动,使其进
入 U-boot 命令行状态,如下图所示:

52
第五章 嵌入式 Linux 内核移植

图 5-6 U-boot 命令行状态

Fig.5-6 U-boot Command Line Status

输入 mmcinfo 命令查看下 SD/MMC 设备信息:

图 5-7 SD/MMC 设备信息

Fig.5-7 SD/MMC Device Information

在 U-boot 命令行输入下列命令启动 Linux 内核:


load mmc 0 0x40007000 uImage
load mmc 0 0x42000000 exynos4412-tiny4412SDK.dtb
bootm 0x40007000 - 0x42000000

53
广东工业大学硕士学位论文

a)

b)

图 5-8 Linux 内核启动信息

Fig.5-8 The Linux Kernel Boot Information

load mmc 0 0x40007000 uImage 是把 SD 卡上的 uImage 文件读到内存地址为


0x40007000 处;
load mmc 0 0x42000000 exynos4412-tiny4412SDK.dtb 是 把 SD 卡 上 的
exynos4412-tiny4412SDK.dtb 读到内存地址为 0x42000000 处;

54
第五章 嵌入式 Linux 内核移植

bootm 0x40007000 - 0x42000000 是告诉 u-boot 从 0x40007000 处启动内核,并告


诉内核设备树文件(*.dtb)的地址为 0x42000000。
如图 5-8 a)所示,U-boot 读取了 SD 卡上的 uImage 和 exynos4412-tiny4412SDK.dtb
设备树二进制文件到内存,并从指定的内存地址开始执行内核。内核执行到如图 5-8
b)时停止了,提示挂载不到根文件系统,因为 Linux 内核挂载不到根文件系统导致
的错误。因此,在下一章将构建 Linux 根文件系统。

5.4 本章小结

本章先介绍了 Linux 内核相关的知识,包括 Linux 内核下载、源代码目录结构、


整体架构和配置编译方法;接着介绍了 Linux 内核的启动流程,最后根据目标开发
板的硬件配置给出了 Linux 内核移植的详细方法和步骤。

55
广东工业大学硕士学位论文

第六章 嵌入式 Linux 根文件系统构建

6.1 嵌入式 Linux 文件系统概述

Linux 文件系统的根目录“/”位于 Linux 文件系统的目录结构的最顶层。根文件


系统通常存放于内存和存储介质中,Linux 系统启动后, Linux 内核会挂载一个设
备到根目录上,这个设备中的文件系统被称为根文件系统。根文件系统中存放了所
有的系统命令、系统配置以及其他文件系统的挂载点以及嵌入式系统使用的所有应
用程序和库 [15]
。Linux 系统启动时,第一个必须挂载的是根文件系统;若不能从指
定设备上挂载根文件系统,Linux 系统会出错而终止启动过程。
1、嵌入式 Linux 根文件系统目录
嵌入式 Linux 根文件系统中一般有如下的几个目录 [16]:
1)/bin 目录:该目录下存放所有用户都可以使用的基本命令。
2)/sbin 目录:该目录下存放的是只有管理员能够使用的系统命令。
3)/dev 目录:该目录下存放的是 Linux 特有的设备文件。
4)/etc 目录:该目录下存放着 Linux 系统各种配置文件。
5)/lib 目录:该目录下存放共享库文件。
7)/root 目录:该目录是根用户的目录,普通用户的目录是在/home 下的某个子
目录。
10)/proc 目录:该目录通常作为 proc 文件系统的挂接点。
11)/sys 目录: Linux 内核总线、设备以及驱动程序的虚拟文件系统目录。
12)/mnt 目录:该目录用作临时挂载某个文件系统的挂接点,一般用来临时挂
载光盘、硬盘。
13)/tmp 目录:该目录一般用于存放临时文件。
14)/usr 目录:该目录存放的是共享、只读的程序和数据。
15)/var 目录:该目录目录一般存放可变的数据,例如 log 文件,临时文件等。
2、嵌入式常用的文件系统介绍
在嵌入式 Linux 系统中,主要使用的存储设备可以分为 2 类,一类是使用基于
RAM 的存储设备(例如内存),另外一类是使用基于 ROM 的存储设备(例如 FLASH
56
第六章 嵌入式 Linux 根文件系统构建

存储器)。常用的基于存储设备的文件系统类型有:jffs2, yaffs2, ubifs, cramfs,


initramfs,ramdisk, ramfs/tmpfs,nfs 等。从大的方面可以分为基于 RAM 的文件系统
和基于 FLASH 的文件系统。不同的文件系统类型有不同的特点,要根据存储设备
的硬件特性、系统需求等来选择。
基于 RAM 的文件系统有 initramfs,ramdisk, ramfs/tmpfs,nfs 等。initramfs 文件
系统使用 cpio 包格式,它可以编译链接到系统中去,可以直接使用而不需要另外挂
接文件系统。ramdisk 文件系统是一种基于内存的虚拟文件系统,它使用内存中一部
分固定大小的内存当作硬盘的一个分区来使用。Ramfs/tmpfs 文件系统把所有的文件
都放在内存中,可以用 ramfs/tmpfs 来存储一些临时性或经常要修改的数据,这样可
以避免对 Flash 存储器的读写损耗,还可以提高数据读写速度 [17]。NFS 网络文件系
统用于在不同机器、不同操作系统之间通过网络共享文件,在嵌入式 Linux 系统的
开发调试阶段,可以在主机上建立基于 NFS 的根文件系统挂载到嵌入式设备上,这
样可以很方便地修改根文件系统的内容。
基于 FLASH 的文件系统主要有 jffs2, yaffs2, ubifs,cramfs 等。jffs2 文件系统是
基于哈希表的日志型文件系统,主要用于 NOR 型闪存,其特点是可读写的、支持
数据压缩、提供了崩溃/掉电安全保护和“写平衡”等;其缺点主要是当文件系统已满
或接近满时,使 jffs2 文件系统的运行速度大大降低。yaffs/yaffs2(Yet Another Flash
File System)文件系统是专为嵌入式系统使用 NAND 型闪存而设计的一种日志型文
件系统,自带了 NAND 芯片的驱动,并且提供了直接访问文件系统的 API,用户可
以通过 API 直接对文件系统进行操作。ubifs 文件系统是用在固态硬盘存储设备上,
相对于 yaffs/yaffs2 和 jffs2 文件系统来说,ubifs 文件系统在设计与性能更适合 MLC
NAND FLASH。Cramfs 文件系统是一种只读的压缩文件系统,其压缩比高达 2:1,
可以使用更低容量的 FLASH 设备存储相同的文件,降低嵌入式系统的成本。

6.2 嵌入式文件系统制作工具 Busybox 简介

Busybox 是一个开源项目,遵循 GPL v2 协议。BusyBox 是一个集成了一百多个


最常用 Linux 命令和工具的软件,例如 ls、cat 和 echo 等等;还包含了一些更大、
更复杂的工具,例 grep、find、mount 以及 telnet。有人将 BusyBox 称为 Linux 工具
里的瑞士军刀。

57
广东工业大学硕士学位论文

BusyBox 将许多具有共性的小版本的 UNIX 工具结合到一个单一的可执行文件,


使用动态链接的 Busybox 只有几百 K 大小,采用静态链接也只有 1M 左右。Busybox
可以替代大部分常用工具比如 GNU fileutils , shellutils 等工具,BusyBox 提供了
一个比较完善的环境,可以适用于任何小的嵌入式系统。
使用 Busybox 在创建根文件系统的时候需要在/dev 目录下创建必要的设备节点,
并且在/etc 目录下增加相应的配置文件;如果 Busybox 使用动态链接,那么还需要
再/lib 目录下包含相关的库文件。

6.3 制作嵌入式 Linux Ramdisk 文件系统

定制根文件系统的方法很多,最常用的是使用 Busybox 来构建。使用 Busybox


可以迅速方便地建立一套相对完整、功能丰富的文件系统,它集成压缩了 Linux 的
许多工具和命令,其中还包含了大量常用的应用程序。下面详细介绍有关 Busybox
定制根文件系统。

6.3.1 制作 Linux 根文件系统

1、建立根文件系统目录(rootfs)。在宿主开发机上建立 rootfs 目录及其子目录,


具体的命令如下:
$ mkdir /home/felix/rootfs
$ cd /home/felix/rootfs
$ mkdir root home bin sbin etc dev usr lib tmp mnt sys proc
$ mkdir usr/lib usr/bin
2、从 Busybox 官网 https://busybox.net/downloads/下载 Busybox 源代码并解压。
下载和解压 Busybox 源码的如下命令:
$ mkdir /home/felix/Busybox
$ cd /home/felix/Busybox
$ wget https://busybox.net/downloads/busybox-1.25.0.tar.bz2
$ tar -jxvf busybox-1.25.0.tar.bz2
3、Busybox 的配置和编译。执行如下命令进入 Busybox 配置界面:
$ make distclean
$ make defconfig
58
第六章 嵌入式 Linux 根文件系统构建

$ make menuconfig ARCH=arm


弹出配置界面,如图 6-1 所示:

图 6-1 Busybox 配置界面

Fig.6-1 Busybox Configuration Interface

在配置界面进行相应的配置。相关的配置如下:
选择 Busybox Settings--->Build Options--->
选中[*] Build Busybox as a static binary(no shared libs);
Cross Compiler prefix 配置为 arm-linux- gnueabi- (指定交叉编译器);
选择 Busybox Settings ---> Installation Options --->BusyBox installation prefix(在
里面输入 BusyBox 的安装目录,我是保存在/home/felix/rootfs 下);
选择 Busybox Settings ---> 选中[*] Don't use /usr。
配置完成后按照提示保存并退出。执行如下命令编译和安装 Busybox:
$ make
$ make install
4、把 Busybox 源码 etc 目录下的所有文件拷贝到/home/felix/rootfs/etc 目录下,
具体命令如下:
$ cp –raf /home/felix/busybox-1.25.0/examples/bootfloppy/etc/* /home/felix/-
rootfs/etc
5、修改配置文件。
5.1、修改 fstab 配置文件为:

59
广东工业大学硕士学位论文

5.2、修改 profile 文件为:

5.3、修改 inittab 文件为:

5.4、配置系统的 hostname。在 etc 目录下执行如下命令:


$ mkdir sysconfig
$ cd sysconfig
$ touch HOSTNAME
$ echo tiny4412 > HOSTNAME
5.5、配置 init.d/rcS 文件为:

60
第六章 嵌入式 Linux 根文件系统构建

并修改 init.d/rcS 文件权限为:


$ chmod 777 init.d/rcS
6、添加 dev 目录下的设备文件。dev 目录下必须有 console 和 null 这两个设备文
件,使用 mknod 来创建这两个设备文件。
$ sudo mknod -m 666 console c 5 1
$ sudo mknod -m 666 null c 1 3
完成上面六个步骤后,制作好的 Linux 根文件系统放在 rootfs 目录中。

6.3.2 制作 Ramdisk 文件系统

本节在上一节建立好的 Linux 根文件系统上制作 Ramdisk 文件系统。整个


Ramdisk 文件系统制作过程可以使用 mk_ramdisk.sh 脚本来完成, mk_ramdisk.sh 脚
本代码内容如下:

61
广东工业大学硕士学位论文

把 mk_ramdisk.sh 脚本放在/home/felix/目录下,执行如下命令执行该脚本:
$ cd /home/felix/
$ chmod 755 mk_ramdisk.sh
$ ./mk_ramdisk.sh
脚本执行完最后生成的 ramdisk.img 就是我们需要的 Ramdisk 文件系统了。

6.4 修改 U-boot 启动参数启动 Linux 内核

把 ramdisk.img 拷贝进 SD 卡,目标开发板选择从 SD 卡启动,使其进入 U-boot


命令行状态。设置 bootcmd 参数如图 6-2 所示,并保存 bootcmd 参数:

图 6-2 设置 bootcmd 参数

Fig.6-2 Set bootcmd Parameter

输入 boot 命令并按回车键,U-boot 会把 uImage、exynos4412-tiny4412SDK.dtb


和 ramdisk.img 加载到内存,并跳转到内存执行 Linux 内核,启动信息如图 6-3 所示:

62
第六章 嵌入式 Linux 根文件系统构建

图 6-3 Linux 内核启动信息

Fig.6-3 The Linux Kernel Boot Information

内核启动完成后,在串口终端输入 ls 命令,可以看到 Linux 根文件系统目录:

图 6-4 Linux 根文件系统目录

Fig.6-4 The Linux Root File System Directory

6.5 本章小结

本章介绍了嵌入式 Linux 根文件系统和根文件系统制作工具 Busybox 相关内容,


给出了制作 Ramdisk 文件系统的详细步骤,最后修改 U-boot 的启动参数成功启动了
新移植的 Linux 内核。

63
广东工业大学硕士学位论文

结论与展望

1.本文主要研究工作和结论
本文对移植引入设备树的 Linux 内核和 U-boot 到 ARM Cortex-A9 平台上进行较
为完整和深入的研究,给出了移植引入设备树的 Linux 内核和 U-boot 的具体方法和
详细步骤,并在 ARM Cortex-A9 开发板上通过实践得到了验证。
本文主要完成的工作如下:
1)、通过查阅文献材料,了解分析了嵌入式 Linux 内核移植研究的背景、意义
和现状以及嵌入式系统的发展现状和趋势,提出了在 ARM Cortex-A9 开发板上移植
引入设备树的 Linux 内核和 U-boot 的研究内容。
2)、详细研究设备树(Flattened Device Tree)的语法结构,及其在 U-boot 和 Linux
内核中的应用。
3)、搭建 Linux 系统移植开发环境。安装宿主开发机 Ubuntu 系统、ARM Linux
交叉编译环境和在移植过程中要使用到的开发工具以及相应的库函数。
4)、分析了 Exyson4412 芯片的启动模式选择,U-boot 源代码结构、配置、编译
以及其启动流程,分析了新版本 U-boot 的设备驱动模型,总结了 U-boot 移植的总
体思路,移植新版本的 U-boot(u-boot-v2016.11)到 ARM Cortex-A9 开发板上。
5)、介绍了 ARM Linux 内核的相关内容,移植新版本的 Linux 内核(Linux-4.4)
到 ARM Cortex-A9 开发板上。
6)、构建了 Linux 根文件系统,制作 Ramdisk 文件。在 ARM Cortex-A9 开发板
成功启动了新移植的 Linux 系统,完成了 Linux 内核移植的核心工作。
2.后续研究工作的展望
由于水平和时间有限,本文的研究工作还存在一些不足,需要在以下几个方面
做进一步的研究和完善:
1)、在 U-boot 移植阶段,完成了从 SD 卡上启动内核的移植工作,还可以继续
研究移植 U-boot 从 eMMC 中启动内核;在 U-boot 中移植 Exyson4412 USB 驱动,
使用 TFTP 来启动调试内核,可以免去了因为调试重复烧写 SD 卡的繁琐工作。
2)、Tiny4412 开发板自带了许多丰富的外设资源,例如 USB 摄像头、以太网卡、

64
结论与展望

LCD、HDMI 等。在接下来的工作中需要移植这些外设的驱动,添加 Linux 内核对


这些硬件资源的支持。
3)、移植图形用户界面 Qtopia。

65
广东工业大学硕士学位论文

参考文献

[1] http://elinux.org/images/c/cf/Power_ePAPR_APPROVED_v1.1.pdf.
[2] Grant Likely, Josh Boyer. A Symphony of Flavours: Using the device tree to describe
embedded hardware [R]. Ottawa, Canada: Linux Symposium, 2008.
[3] SUN. The Open Firmware Home Page (EB/OL]. htlp://playground.sun.com/-
1275/home.html,2005.
[4] 宋宝华. Linux 设备驱动开发详解:基于最新的 Linux 4.0 内核[M]. 机械工业出版
社, 2015.
[5]devicetree-specification-v0.1.https://www.devicetree.org/specifications/.
[6]邱文华,邱珍珍. 基于扁平设备树的 Linux 内核启动方式[J]. 现代计算机(专业
版),2009,(03):115-118.
[7] ARM Linux 3.x 的设备树 http://blog.csdn.net/21cnbao/article/details/8457546.
[8] 广州友善之臂计算机科技有限公司.友善之臂公司官方网站下载页面[EB/OL].
http://www.arm9.net/tiny4412.asp.
[9] YAGHMOUR K, MASTERS J, YOSSEF G B, et al. Building Embedded Linux
Systems[M].2nd ed. Sebastopol, CA: 0 ’Re illy Media, Inc., 2008.
[10]卞芸. ARM9 平台上的嵌入式 Linux 系统移植研究[D].重庆大学,2011.
[11] 王之磊,李临生 U-Boot 在 S3C2440 上移植和设置[J].工业控制计算机 ,2012.
[12] 广 州 友 善 之 臂 计 算 机 科 技 有 限 公 司 . 友 善 之 臂 公 司 官 方 网 站 下 载 页 面
[EB/OL].Tiny4412-1412-Schematic.pdf.
[13] 朱 龙 军 . 基 于 ARM 的 嵌 入 式 流 媒 体 客 户 端 的 研 究 与 设 计 [D]. 江 西 理 工 大
学,2010.
[14]王志强.基于嵌入式 Linux 和 GPRS 的船舶远程监控系统的设计和研究[D].烟台大
学,2015.
[15]张宇.埋地金属管道阴极保护电位无线采集 PDA 设计[D].北京化工大学,2010.
[16]张振江.智能与生态住宅无线监控系统的研究与设计[D].西安建筑科技大学,
2012.

66
参考文献

[17]夏婷.非压缩数字视频监控系统的交换控制研究[D].武汉理工大学,2008.
[18]王亚刚.嵌入式 Bootloader 机制的分析与移植[J].计算机工程, 2010, 36(6):
267-269.
[19]袁秋林. 基于 ARM9 平台的嵌入式 Linux 系统的移植开发及应用[D].西北师范大
学,2009.
[20]张霄.基于 ARM11 的嵌入式 linux 系统移植与实现[D].山东大学,2013.
[21]严海洋.基于 ARM 的智能家居系统的设计与实现[D].哈尔滨工业大学,2013 .
[22]聂和平.基于 ARM9 的嵌入式 Linux 系统移植与驱动开发[D].南京电大学,
2013.
[23]张霄.基于 ARM11 的嵌入式 linux 系统移植与实现[D].山东大学,2013.
[24]杨秀虎.基于 ARM+Linux 的嵌入式系统驱动原理的研究与应用开发[D].辽宁科
技大学,2015.
[25]Bin W, Zhao R Y, Ma H B. Embedded Linux Porting Based on ARM9 Hardware
Platform[J]. Applied Mechanics & Materials, 2013, 380-384:2871-2875.
[26]徐山峰,马立玲,王军政,夏宇. 基于 AT91RM9200 的 ARM Linux 的移植方法[J].
微计算机信息,2008,(14):116-118+181.
[27]Divya S, Kamal K. Embedded Linux Porting on ARM & RFID Implementation
Using ARM SoC[M]. LAP LAMBERT Academic Publishing, 2013.
[28] Eswarkumar K, Kamaraju M, Kumar Yadav A. Porting and BSP Customization of
Linux on ARM Platform[J]. International Journal of Computer Applications, 2013,
80(15):36-42.
[29]Bi C Y, Liu Y P, Wang R F. Research of key technologies for embedded Linux based
on ARM[C]// International Conference on Computer Application and System
Modeling. IEEE Xplore, 2010:V8-373 - V8-378.
[30]李胜琴, 许岩. 基于 ARM9 的嵌入式 linux 系统移植[J]. 中国科技信息, 2011,
24(7):116-117.
[31]刘云锋, 黄英, 何新鹏,等. 基于 ARM9 的嵌入式 Linux 系统移植[J]. 工业控制计
算机, 2011, 24(8):44-45.
[32]徐士强. 基于 ARM9 的嵌入式 Linux 系统的研究与应用[D]. 南京邮电大学, 2012.

67
广东工业大学硕士学位论文

[33]刘国秀, 王元伟, 徐建华,等. 基于 ARM 的嵌入式 linux 内核的裁剪与移植[J]. 电


子元器件应用, 2009(11):66-68.
[34] 路 青 起 , 席 丹 丹 . 嵌 入 式 Linux 系 统 移 植 [J]. 国 外 电 子 测 量 技 术 , 2014,
33(12):78-81.
[35]陶琳, 张亚楠, 杨新锋. 嵌入式 Linux 系统移植研究与实现[J]. 微型电脑应用,
2016, 32(12):12-14.
[36]马辉, 崔世聪. 基于 ARM 的嵌入式 Linux 操作系统移植[J]. 工程技术:全文版,
2016(10):00263-00263.
[37]李建祥. 嵌入式 Linux 系统开发入门宝典:基于 ARM Cortex-A8 处理器[M]. 清华
大学出版社, 2016.
[38]杨福刚. ARM Cortex-A9 多核嵌入式系统开发教程[M]. 西安电子科技大学出版
社, 2016.
[39]刘二钢. 一种构建嵌入式 Linux 根文件系统的方法[J]. 电子设计工程, 2016,
24(9):160-162.
[40]夏礼勇, 符秀辉. U-Boot 在 S3C2440 上的分析和移植[J]. 沈阳化工大学学报,
2016, 30(2):156-159.
[41]Wei Y. Structure and Function of the Device Tree[J]. Computer Development &
Applications, 2013.
[42]Zhang M, Lei Z, Xiao G, et al. Development of MPC8247 embedded Linux system
based on device tree[J]. Journal of Computer Applications, 2013, 33(5):1485-1488.
[43]史巧硕, 范东月, 柴欣,等. 嵌入式 Linux 根文件系统的构建与分析[J]. 计算机测
量与控制, 2015, 23(2):656-659.
[44]徐斌. 当前嵌入式 LINUX 分析与应用[J]. 电子制作, 2015(2).
[45] 谢 辉 . 嵌 入 式 Linux 系 统 在 ARM 处 理 器 中 关 键 技 术 分 析 [J]. 电 大 理 工 ,
2015(1):24-25.

68
攻读学位期间发表论文

攻读学位期间发表论文

[1] 罗名驹, 陈益民, 贾志文. 扁平设备树 FDT 在 ARM Linux 中的应用研究[J]. 单


片机与嵌入式系统应用, 2017, 17(3).

69
广东工业大学硕士学位论文

70
致 谢

致 谢

在我三年研究生求学生涯即将结束之际,在此向给予我帮助、支持和鼓励的老
师、同学和家人致以最诚挚的感谢。
首先,感谢我的研究生导师陈益民副教授。在研究生学习期间,陈老师渊博的
知识和严谨的科研作风指导我在科研的道路上不断前行;生活中陈老师平易近人,
给予我无微不至的关怀。在论文完成之际,陈老师百忙之中抽空细心帮我批改论文,
针对论文出现的问题,给我提出了许多宝贵的修改意见,使我的论文更加完善。在
此,谨向陈老师致以崇高的敬意和衷心的感谢。
感谢实验室的师兄师姐和师弟师妹们,感谢你们的帮助,和你们在一起度过了
三年快乐的研究生求学生涯。感谢同窗的小伙伴林捷鸿、贾志文、陈诗特、胡奇宇、
聂梦君、黎丹雨、张鹏琴给予我在学习、生活上的帮助。
感谢我的家人一直以来对我的关心、支持和鼓励,你们永远是我的精神支柱和
坚强的后盾,愿你们身体健康。
最后,感谢审阅本论文的教授、专家和学者们,谢谢您们的悉心审阅和批评指
正。

罗名驹
2017 年 5 月

71
广东工业大学硕士学位论文

附录 A U-boot 源码中添加目标板目录和文件代码

diff --git a/board/samsung/tiny4412/Kconfig b/board/samsung/tiny4412/Kconfig


new file mode 100644
index 0000000..954c391
--- /dev/null
+++ b/board/samsung/tiny4412/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_TINY4412
+config SYS_BOARD
+ default "tiny4412"
+
+config SYS_VENDOR
+ default "samsung"
+
+config SYS_CONFIG_NAME
+ default "tiny4412"
+
+config EXYNOS4412
+ bool
+endif
diff --git a/board/samsung/tiny4412/Makefile b/board/Samsung/tiny4412/-
Makefile
+hostprogs-y := tools/mktiny4412spl
+(obj)/tools/mktiny4412spl:HOSTCFLAGS:=(obj)/tools/mktiny4412spl:HOST
CFLAGS:=(filter-out -O2,$(HOSTCFLAGS))
else
+obj-y += tiny4412.o

72
附 录

endif
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index ce2a16f..c8bb811 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -56,6 +56,15 @@ config TARGET_TRATS2
config TARGET_ODROID
bool "Exynos4412 Odroid board"
+config TARGET_TINY4412
+ bool "Exynos4412 FriendlyARM Tiny4412 board"
+ select SUPPORT_SPL
+ select SPL
+ select EXYNOS4412
+ help
+ Support FriendlyARM Tiny4412 board based on Samsung
exynos4412
+ CPU: S5PC220[Samsung SOC on SMP Platform Base on ARM
CortexA9].
endchoice
endif
@@ -145,6 +154,7 @@ source "board/samsung/universal_c210/Kconfig"
source "board/samsung/origen/Kconfig"
source "board/samsung/trats2/Kconfig"
source "board/samsung/odroid/Kconfig"
+source "board/samsung/tiny4412/Kconfig"
source "board/samsung/arndale/Kconfig"
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 0cc6c32..ac47ab2 100644
--- a/arch/arm/mach-exynos/Makefile

73
广东工业大学硕士学位论文

+++ b/arch/arm/mach-exynos/Makefile
@@ -15,6 +15,7 @@ ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_EXYNOS5) += clock_init_exynos5.o
obj-$(CONFIG_EXYNOS5) += dmc_common.o dmc_init_ddr3.o
obj-$(CONFIG_EXYNOS4210)+= dmc_init_exynos4.o
clock_init_exynos4.o
+obj-$(CONFIG_EXYNOS4412)+= dmc_init_exynos4.o clock_init_exynos4.o
obj-y += spl_boot.o tzpc.o
obj-y += lowlevel_init.o
endif
diff --git a/arch/arm/mach-exynos/exynos4_setup.h b/arch/arm/mach-exynos/-
exynos4_setup.h
index 9f29d94..838e02c 100644
--- a/arch/arm/mach-exynos/exynos4_setup.h
+++ b/arch/arm/mach-exynos/exynos4_setup.h
@@ -440,6 +440,12 @@ struct mem_timings {
#define APB_SFR_ARBRITATION_CONF_VAL 0x00000001
#endif
+#ifdef TINY4412
+#define APB_SFR_INTERLEAVE_CONF_VAL 0x20001507
+#define APB_SFR_ARBRITATION_CONF_VAL 0x00000001
+#endif
#define INTERLEAVE_ADDR_MAP_START_ADDR 0x40000000
#define INTERLEAVE_ADDR_MAP_END_ADDR 0xbfffffff
#define INTERLEAVE_ADDR_MAP_EN 0x00000001
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 836a8c4..a654d74 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile

74
附 录

@@ -14,6 +14,7 @@ dtb-$(CONFIG_EXYNOS4) += exynos4210-origen.dtb \


exynos4210-universal_c210.dtb \
exynos4210-trats.dtb \
exynos4412-trats2.dtb \
+ exynos4412-tiny4412.dtb \
exynos4412-odroid.dtb
diff --git a/board/samsung/tiny4412/tools/mktiny4412spl.c b/board/samsung/-
tiny4412/tools/mktiny4412spl.c
index 3ed20ef..c3a3e29 100755
--- a/board/samsung/tiny4412/tools/mktiny4412spl.c
+++ b/board/samsung/tiny4412/tools/mktiny4412spl.c
@@ -13,11 +14,9 @@
#include <sys/stat.h>
#define BUFSIZE (16*1024)
-#define IMG_SIZE (16*1024)
-#define SPL_HEADER_SIZE 16
+#define IMG_SIZE ( (14*1024)- 4 )
#define FILE_PERM (S_IRUSR | S_IWUSR | S_IRGRP \
| S_IWGRP | S_IROTH | S_IWOTH)
-#define SPL_HEADER "S5PC210 HEADER "
/*
* Requirement:
* IROM code reads first 14K bytes from boot device.
@@ -37,7 +36,8 @@ int main(int argc, char **argv)
int ifd, ofd;
- unsigned int checksum = 0, count;
+ unsigned int checksum = 0;
+ unsigned int count = 0;
if (argc != 3) {

75
广东工业大学硕士学位论文

printf(" %d Wrong number of arguments\n", argc);


@@ -52,7 +52,7 @@ int main(int argc, char **argv)
}
ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC,
FILE_PERM);
- if (ifd < 0) {
+ if (ofd < 0) {
fprintf(stderr, "%s: Can't open %s: %s\n",
argv[0], argv[2], strerror(errno));
if (ifd)
@@ -63,12 +63,9 @@ int main(int argc, char **argv)
len = lseek(ifd, 0, SEEK_END);
lseek(ifd, 0, SEEK_SET);
- memcpy(&buffer[0], SPL_HEADER, SPL_HEADER_SIZE);
- count = (len < (IMG_SIZE - SPL_HEADER_SIZE))
- ? len : (IMG_SIZE - SPL_HEADER_SIZE);
+ count = (len < IMG_SIZE )? len : IMG_SIZE; //14K-4
- if (read(ifd, buffer + SPL_HEADER_SIZE, count) != count) {
+ if (read(ifd, buffer, count) != count) {
fprintf(stderr, "%s: Can't read %s: %s\n",
argv[0], argv[1], strerror(errno));
@@ -80,14 +77,11 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
- for (i = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)
- checksum += buffer[i+16];
- *(ulong *)buffer ^= 0x1f;
- *(ulong *)(buffer+4) ^= checksum;
- for (i = 1; i < SPL_HEADER_SIZE; i++)

76
附 录

- buffer[i] ^= buffer[i-1];
+ for(i = 0;i < IMG_SIZE;i++)
+ {
+ checksum += (unsigned char)(buffer[i]);
+ }
+ *(unsigned int*)(buffer+i) = checksum;

附录 B Exyson4412 时钟初始化关键代码

+ /*===set APLL related dividers(CMU_CPU)===*/


+ clr = APLL_RATIO(7) |CORE_RATIO(7)| CORE2_RATIO(7)|
+ COREM0_RATIO(7) | COREM1_RATIO(7) |
+ PERIPH_RATIO(7) | ATB_RATIO(7) | PCLK_DBG_RATIO(7) ;
+ set = APLL_RATIO(1) |CORE_RATIO(0) | CORE2_RATIO(0) |
+ COREM0_RATIO(3) | COREM1_RATIO(7)|
+ PERIPH_RATIO(0) | ATB_RATIO(6) | PCLK_DBG_RATIO(1) ;
+ clrsetbits_le32(&clk->div_cpu0, clr, set);
+ /* Set dividers for MOUThpm
+ clr = COPY_RATIO(7) | HPM_RATIO(7) | CORES_RATIO(7);
+ set = COPY_RATIO(6) | HPM_RATIO(0) | CORES_RATIO(5);
+ clrsetbits_le32(&clk->div_cpu1, clr, set);
+
+ /*======set MPLL related dividers(CMU_DMC)==== =*/
+ clr = DMC_RATIO(7) | DMCD_RATIO(7) | DMCP_RATIO(7) |
+ ACP_RATIO(7) | ACP_PCLK_RATIO(7) | DPHY_RATIO(7);
+ set = DMC_RATIO(1) | DMCD_RATIO(1) | DMCP_RATIO(1) |
+ ACP_RATIO(3) | ACP_PCLK_RATIO(1) | DPHY_RATIO(1);
+ clrsetbits_le32(&clk->div_dmc0, clr, set);
+ clr = C2C_RATIO(7) | C2C_ACLK_RATIO(7) | PWI_RATIO(15) |

77
广东工业大学硕士学位论文

+ G2D_ACP_RATIO(15) | DVSEM_RATIO(127) | DPM_RATIO(127);


+ set = C2C_RATIO(1) | C2C_ACLK_RATIO(1) | PWI_RATIO(7) |
+ G2D_ACP_RATIO(3) | DVSEM_RATIO(1) | DPM_RATIO(1);
+ clrsetbits_le32(&clk->div_dmc1, clr, set);
+
+ /*========set CMU_TOP related dividers======*/
+ clr = ACLK_400_MCUISP_RATIO(7) | ACLK_200_RATIO(7) |
ACLK_266_GPS_RATIO(7) |
+ ACLK_100_RATIO(15) | ACLK_160_RATIO(7) | ACLK_133_RATIO(7)
|ONENAND_RATIO(7);
+ set = ACLK_400_MCUISP_RATIO(1) | ACLK_200_RATIO(4) |
ACLK_266_GPS_RATIO(2) |
+ ACLK_100_RATIO(7) | ACLK_160_RATIO(4) |
ACLK_133_RATIO(5) |ONENAND_RATIO(1);
+ clrsetbits_le32(&clk->div_top, clr, set);
+ /*===========set CMU_LEFTBUS related dividers=========*/
+ clr = GDL_RATIO(7) | GPL_RATIO(7) ;
+ set = GDL_RATIO(3) | GPL_RATIO(1) ;
+ clrsetbits_le32(&clk->div_leftbus, clr, set);
+ /*========set CMU_RIGHTBUS related dividers==========*/
+ clr = GDR_RATIO(7) | GPR_RATIO(7) ;
+ set = GDR_RATIO(3) | GPR_RATIO(1) ;
+ clrsetbits_le32(&clk->div_rightbus, clr, set);

附录 C Exyson4412 串口初始化关键代码

diff --git a/arch/arm/dts/exynos4412-tiny4412.dts b/arch/arm/dts/exynos4412-tiny-


4412.dts
index 8822d52..a467250 100644

78
附 录

--- a/arch/arm/dts/exynos4412-tiny4412.dts
+++ b/arch/arm/dts/exynos4412-tiny4412.dts
@@ -14,73 +14,16 @@
model = "Tiny4412 based on Exynos4412";
compatible = "samsung,tiny4412", "samsung,exynos4412";
+ chosen {
+ stdout-path = "serial0";
};
+ aliases {
+ serial0 = "/serial@13800000";
+ console = "/serial@13800000";
};
- serial@13810000 {
+ serial0:serial@13810000 {
status = "okay";
};
};
diff --git a/arch/arm/mach-exynos/lowlevel_init.c b/arch/arm/mach-exynos/-
lowlevel_init.c
index 1e090fd..361727d 100644
--- a/arch/arm/mach-exynos/lowlevel_init.c
+++ b/arch/arm/mach-exynos/lowlevel_init.c
@@ -215,11 +215,17 @@ int do_lowlevel_init(void)
if (actions & DO_CLOCKS) {
system_clock_init();
#ifdef CONFIG_DEBUG_UART
#if (defined(CONFIG_SPL_BUILD) &&
defined(CONFIG_SPL_SERIAL_SUPPORT)) || \
!defined(CONFIG_SPL_BUILD)

79
广东工业大学硕士学位论文

+ #ifdef TINY4412
+ exynos_pinmux_config(PERIPH_ID_UART0,
PINMUX_FLAG_NONE);
+ #else
exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
+ #endif
debug_uart_init();
+ printascii("UART DEBUG enable .... !!!\n\r");
#endif
#endif
mem_ctrl_init(actions & DO_MEM_RESET);
diff --git a/configs/tiny4412_defconfig b/configs/tiny4412_defconfig
index 93917b9..19d0dda 100644
--- a/configs/tiny4412_defconfig
+++ b/configs/tiny4412_defconfig
@@ -24,6 +24,16 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_CONTROL=y
+CONFIG_DEBUG_UART=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_GPIO_SUPPORT=y
+CONFIG_DEBUG_UART_S5P=y
+CONFIG_DEBUG_UART_BASE=0x13800000
+CONFIG_DEBUG_UART_CLOCK=100000000

附录 D Exyson4412 内存初始化关键代码

diff --git a/arch/arm/mach-exynos/dmc_init_exynos4412.c b/arch/arm/-


mach-exynos/dmc_init_exynos4412.c
new file mode 100644

80
附 录

index 0000000..27f72cd
--- /dev/null
+++ b/arch/arm/mach-exynos/dmc_init_exynos4412.c
@@ -0,0 +1,254 @@
+#include "exynos4412_setup.h"
+#ifdef TINY4412
+struct mem_timings mem = {
+ .direct_cmd_msr = {
+ DIRECT_CMD1, DIRECT_CMD2, DIRECT_CMD3, DIRECT_CMD4
+ },
+ .timingref = 0x000000BB,
+ .timingrow = 0x6946654f,
+ .timingdata = 0x46460506,
+ .timingpower = 0x5200183c,
+ .zqcontrol = 0xE3854C03,
+ .control0 = 0x71101008,
+ .control1 = 0xe0000086,
+ .control2 = 0x00000000,
+ .concontrol = 0x0FFF301A,
+ .prechconfig = 0xff000000,
+ .memcontrol = 0x00302640, /* Tiny4412-1412 core board only use
chip0 */
+ .memconfig0 = 0x40C01333, /* ROW is 15bit */
+ .memconfig1 = 0x80C01333, /* DMC0 address up to 0x7FFFFFFF */
+ .dll_resync = FORCE_DLL_RESYNC,
+ .dll_on = DLL_CONTROL_ON,
+};
+#else
struct mem_timings mem = {

81
广东工业大学硕士学位论文

+#endif
static void dmc_init(struct exynos4_dmc *dmc)
{
+#ifdef TINY4412
+ writel(0x8000001F, &dmc->ivcontrol);
+#endif
}
diff --git a/arch/arm/mach-exynos/exynos4412_setup.h b/arch/arm/mach-exynos/-
exynos4412_setup.h
index a05301a..f0a032b 100644
--- a/arch/arm/mach-exynos/exynos4412_setup.h
+++ b/arch/arm/mach-exynos/exynos4412_setup.h
+#ifdef TINY4412
+/* Interleave: 2Bit, Interleave_bit1: 0x15, Interleave_bit0: 0x7 */
+#define APB_SFR_INTERLEAVE_CONF_VAL 0x20001507
+#define APB_SFR_ARBRITATION_CONF_VAL 0x00000001
+#endif
+#ifdef TINY4412
+#define TIMINGREF_VAL 0x000000BB
+#define TIMINGROW_VAL 0x4046654f
+#define TIMINGDATA_VAL 0x46400506
+#define TIMINGPOWER_VAL 0x52000A3C
+#else
#define TIMINGREF_VAL 0x000000BC
+#endif
#endif /*__EXYNOS4412_SETUP__ */
diff --git a/include/configs/tiny4412.h b/include/configs/tiny4412.h
index 36af8b1..281838d 100644
--- a/include/configs/tiny4412.h

82
附 录

+++ b/include/configs/tiny4412.h
@@ -3,6 +3,9 @@
+* FriendlyARM Tiny4412 SDK board hardware version:
+* core board : Tiny4412-1412
+* bottom board : Tiny4412/Super4412SDK 1506
@@ -21,11 +24,11 @@
-/* TINY4412 has 4 bank of DRAM */
-#define CONFIG_NR_DRAM_BANKS 4
+/* TINY4412-1412 core board has 8 bank of DRAM */
+#define CONFIG_NR_DRAM_BANKS 8
#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE
-#define SDRAM_BANK_SIZE (256 << 20) /* 256 MB */
+#define SDRAM_BANK_SIZE (128 << 20) /* 128 MB */

附录 E Linux 内核移植代码

diff --git a/arch/arm/boot/dts/exynos4412-tiny4412sdk.dts b/arch/arm/boot/dts/-


exynos4412-tiny4412sdk.dts
index 5504398..f932f53 100644
--- a/arch/arm/boot/dts/exynos4412-tiny4412sdk.dts
+++ b/arch/arm/boot/dts/exynos4412-tiny4412sdk.dts
@@ -21,6 +21,7 @@
chosen {
stdout-path = &serial_0;
+ bootargs = "root=/dev/ram0 rw rootfstype=ext4
console=ttySAC0,115200 init=/linuxrc";
};
memory@40000000 {
@@ -69,6 +70,23 @@

83
广东工业大学硕士学位论文

clock-frequency = <24000000>;
};
};
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mmc2_reg: regulator@0{
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "MMC2_VDD_32_33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpk2 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
};
&rtc {
@@ -77,8 +95,9 @@
&sdhci_2 {
bus-width = <4>;
- pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;
pinctrl-names = "default";
+ vmmc-supply = <&mmc2_reg>;
status = "okay";
};
diff --git a/arch/arm/configs/tiny4412sdk_defconfig b/arch/arm/configs/-

84
附 录

tiny4412sdk_defconfig
index c58f684..e0f9a51 100644
--- a/arch/arm/configs/tiny4412sdk_defconfig
+++ b/arch/arm/configs/tiny4412sdk_defconfig
@@ -8,8 +8,8 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_EXYNOS=y
-CONFIG_ARCH_EXYNOS3=y
-CONFIG_EXYNOS5420_MCPM=y
+CONFIG_ARCH_EXYNOS4=y
+# CONFIG_EXYNOS5420_MCPM is not set
CONFIG_SMP=y
CONFIG_BIG_LITTLE=y
CONFIG_NR_CPUS=8
@@ -48,7 +48,6 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_CFG80211=y
-CONFIG_RFKILL_REGULATOR=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y
@@ -57,18 +56,13 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y

85
广东工业大学硕士学位论文

CONFIG_CHR_DEV_SG=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=m
CONFIG_NETDEVICES=y
-CONFIG_SMSC911X=y
-CONFIG_USB_RTL8152=y
CONFIG_USB_USBNET=y
-CONFIG_USB_NET_SMSC75XX=y
-CONFIG_USB_NET_SMSC95XX=y
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
CONFIG_INPUT_EVDEV=y
@@ -77,13 +71,8 @@ CONFIG_KEYBOARD_CROS_EC=y
# CONFIG_MOUSE_PS2 is not set
CONFIG_MOUSE_CYAPA=y
CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ATMEL_MXT=y
-CONFIG_TOUCHSCREEN_MMS114=y
CONFIG_INPUT_MISC=y
-CONFIG_INPUT_MAX77693_HAPTIC=y
-CONFIG_INPUT_MAX8997_HAPTIC=y
CONFIG_KEYBOARD_SAMSUNG=y
-CONFIG_SERIAL_8250=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_SAMSUNG=y
CONFIG_SERIAL_SAMSUNG_CONSOLE=y
@@ -99,19 +88,6 @@ CONFIG_SPI=y
CONFIG_SPI_GPIO=y

86
附 录

CONFIG_SPI_S3C64XX=y
CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_WM8994=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_BATTERY_SBS=y
-CONFIG_BATTERY_MAX17040=y
-CONFIG_BATTERY_MAX17042=y
-CONFIG_CHARGER_MAX14577=y
-CONFIG_CHARGER_MAX77693=y
-CONFIG_CHARGER_MAX8997=y
-CONFIG_CHARGER_TPS65090=y
-CONFIG_SENSORS_LM90=y
-CONFIG_SENSORS_NTC_THERMISTOR=y
-CONFIG_SENSORS_PWM_FAN=y
-CONFIG_SENSORS_INA2XX=y
CONFIG_CPU_THERMAL=y
CONFIG_THERMAL_EMULATION=y
CONFIG_WATCHDOG=y
@@ -119,27 +95,10 @@ CONFIG_S3C2410_WATCHDOG=y
CONFIG_MFD_CROS_EC=y
CONFIG_MFD_CROS_EC_I2C=y
CONFIG_MFD_CROS_EC_SPI=y
-CONFIG_MFD_MAX14577=y
-CONFIG_MFD_MAX77686=y
-CONFIG_MFD_MAX77693=y
-CONFIG_MFD_MAX8997=y
-CONFIG_MFD_MAX8998=y
CONFIG_MFD_SEC_CORE=y
-CONFIG_MFD_TPS65090=y

87
广东工业大学硕士学位论文

CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_GPIO=y
-CONFIG_REGULATOR_MAX14577=y
-CONFIG_REGULATOR_MAX8997=y
-CONFIG_REGULATOR_MAX8998=y
-CONFIG_REGULATOR_MAX77686=y
-CONFIG_REGULATOR_MAX77693=y
-CONFIG_REGULATOR_MAX77802=y
-CONFIG_REGULATOR_S2MPA01=y
-CONFIG_REGULATOR_S2MPS11=y
-CONFIG_REGULATOR_S5M8767=y
-CONFIG_REGULATOR_TPS65090=y
-CONFIG_REGULATOR_WM8994=y
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y
@@ -149,7 +108,6 @@ CONFIG_USB_VIDEO_CLASS=m
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=m
CONFIG_VIDEO_S5P_FIMC=m
-CONFIG_VIDEO_S5P_MIPI_CSIS=m
CONFIG_VIDEO_EXYNOS_FIMC_LITE=m
CONFIG_VIDEO_EXYNOS4_FIMC_IS=m
CONFIG_V4L_MEM2MEM_DRIVERS=y
@@ -166,8 +124,6 @@ CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y

88
附 录

-CONFIG_DRM_NXP_PTN3460=y
-CONFIG_DRM_PARADE_PS8622=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_PLATFORM=y
CONFIG_BACKLIGHT_PWM=y
@@ -176,9 +132,6 @@ CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_SAMSUNG=y
-CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994=y
-CONFIG_SND_SOC_SMDK_WM8994_PCM=y
-CONFIG_SND_SOC_SNOW=y
CONFIG_SND_SIMPLE_CARD=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -205,21 +158,14 @@ CONFIG_LEDS_CLASS=y
CONFIG_LEDS_CLASS_FLASH=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_PWM=y
-CONFIG_LEDS_MAX77693=y
-CONFIG_LEDS_MAX8997=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_MAX8997=y
-CONFIG_RTC_DRV_MAX77686=y
CONFIG_RTC_DRV_S5M=y
CONFIG_RTC_DRV_S3C=y
CONFIG_DMADEVICES=y

89
广东工业大学硕士学位论文

CONFIG_PL330_DMA=y
CONFIG_CROS_EC_CHARDEV=y
-CONFIG_COMMON_CLK_MAX77686=y
-CONFIG_COMMON_CLK_MAX77802=y
-CONFIG_COMMON_CLK_S2MPS11=y
CONFIG_PM_DEVFREQ=y
CONFIG_DEVFREQ_GOV_PERFORMANCE=y
CONFIG_DEVFREQ_GOV_POWERSAVE=y
@@ -227,16 +173,10 @@ CONFIG_DEVFREQ_GOV_USERSPACE=y
CONFIG_ARM_EXYNOS_BUS_DEVFREQ=y
CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=y
CONFIG_EXTCON=y
-CONFIG_EXTCON_MAX14577=y
-CONFIG_EXTCON_MAX77693=y
-CONFIG_EXTCON_MAX8997=y
CONFIG_IIO=y
CONFIG_EXYNOS_ADC=y
-CONFIG_CM36651=y
-CONFIG_AK8975=y
CONFIG_PWM=y
CONFIG_PWM_SAMSUNG=y
-CONFIG_PHY_EXYNOS5250_SATA=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_AUTOFS4_FS=y
@@ -272,3 +212,30 @@ CONFIG_CRC_CCITT=y
CONFIG_FONTS=y
CONFIG_FONT_7x14=y
CONFIG_VIDEO_VIVID=m

90

You might also like