Professional Documents
Culture Documents
UDC: 密 级: 学 号:2111403006
广东工业大学硕士学位论文
(工学硕士)
罗名驹
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 架构平台具有参考价值和借鉴意义。
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.
目 录
摘 要 ................................................................................................................................. 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
广东工业大学硕士学位论文
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
VII
广东工业大学硕士学位论文
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 本课题研究现状
2
第一章 绪论
1.3 课题研究内容及章节安排
3
广东工业大学硕士学位论文
1.4 本论文的特点和创新点
1.5 本章小结
本章在查阅国内外参考文献的基础上,提出了研究移植引入设备树的 U-boot 和
Linux 内核移植到 ARM Cortex-A9 架构的 Samsung Exynos4412 芯片开发板的研究内
容,主要工作如下:
1.说明课题的研究背景和研究意义。
2.介绍了嵌入式 Linux 内核移植到 ARM 平台上的国内外研究现状。
3.对本文的主要研究内容以及组织框架做了一个简要的说明,为后面阐述 Linux
内核移植作准备。
4
第二章 ARM Linux 下的设备树简介
2.1 设备树概述
2.1.1 设备树组成和结构
2.1.2 设备树源文件
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 设备树源码编译器
2.1.4 设备树二进制文件
2.2 设备树的使用方法
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 本章小结
13
广东工业大学硕士学位论文
3.1 目标板硬件平台简介
Exyson4412 芯片性能参数:
1、Exyson4412 CPU 参数:采用 ARM Cortex-A9 内核,ARMv7 指令集、32nm 制
14
第三章 嵌入式 Linux 系统移植环境搭建
3.1.2 目标板硬件介绍
2、Tiny4412 底板介绍
开发板底板使用的是 Tiny4412SDK 1506 这个标准版底板,底板硬件资源特性如
下:
15
广东工业大学硕士学位论文
3.2 宿主机开发环境搭建
在嵌入式开发过程中有宿主机和目标机的角色之分。宿主机是执行编译、链接
嵌入式软件的计算机;目标机是运行嵌入式软件的硬件平台。嵌入式开发通常是在
16
第三章 嵌入式 Linux 系统移植环境搭建
宿主机上编写好程序,使用交叉编译工具生成目标板上可以执行的二进制代码,再
将编译好的二进制代码下载或者烧写到目标板指定的存储位置,目标板上电后可以
从指定的存储位置读取代码开始执行。
17
广东工业大学硕士学位论文
图 3-4 虚拟 PC 机界面
18
第三章 嵌入式 Linux 系统移植环境搭建
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 交叉工具链版本信息
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
广东工业大学硕士学位论文
22
第三章 嵌入式 Linux 系统移植环境搭建
3.3 本章小结
本章首先介绍了目标移植平台的硬件参数,然后详细阐述了嵌入式 Linux 系统
开发环境的搭建,包括 VMware 软件和 Ubuntu 系统的安装、交叉编译工具的安装
和其他在移植过程中需要使用的一些工具和相关函数库的安装。为后续嵌入式源代
码编译移植和调试准备好了开发环境。
23
广东工业大学硕士学位论文
在大部分嵌入式设备中,操作系统内核运行之前会先运行引导加载程序,它的
主要工作是初始化硬件设备,例如关闭芯片看门狗、屏蔽所有中断、禁用 MMU 和
缓存,初始化内存芯片,初始化输出显示设备等;规划好系统运行的内存空间,准
备好系统的运行环境;从启动设备上拷贝操作系统和文件系统到内存指定的地方,
跳转到内存指定的地方执行内核。U-boot 是嵌入式系统中最常使用的引导加载程序。
移植 U-boot 到新的目标板上,首先要对目标板上处理器芯片的启动方式、系统
时钟初始化、串口初始化、内存初始化以及目标板的内存地址空间分配有一个比较
清楚的认识,特别是要了解芯片的启动过程。
24
第四章 移植引导加载程序 U-boot
图 4-1 OM 引脚配置启动设备
25
广东工业大学硕士学位论文
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 格式的映像等工具。
27
广东工业大学硕士学位论文
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
广东工业大学硕士学位论文
端输入命令以及对命令进行处理。
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 设备。
33
广东工业大学硕士学位论文
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 中添加了目标板的目录和配置文件。
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
Exynos4412 芯片的时钟域如下图所示:
37
广东工业大学硕士学位论文
38
第四章 移植引导加载程序 U-boot
4.4.4 初始化调试串口
图 4-7 调试串口原理图
39
广东工业大学硕士学位论文
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
图 4-8 SD 卡布局
相应的代码修改如下:
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
广东工业大学硕士学位论文
42
第四章 移植引导加载程序 U-boot
图 4-9 串口输出信息
4.5 本章小结
43
广东工业大学硕士学位论文
Linux 内核源代码包括三个主要部分:
1、内核核心代码,包 Linux 系统的各个子系统和子模块。
2、其它非核心代码,例如库文件、固件集合、KVM(虚拟机技术)等。
44
第五章 嵌入式 Linux 内核移植
3、编译脚本、配置文件、帮助文档、版权说明等辅助性文件。
下图示使用 ls 命令看到的内核源代码的顶层目录结构如图 5-1 所示。
主要目录描述如下:
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 -- 帮助、说明文档。
46
第五章 嵌入式 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 所示:
在配置的过程中,使用键盘的上下键来选择相应的选项。空格键可以更改相应的选
项的属性:
[*]把此项编入系统内核
[M]把此项以驱动模块的形式编译。
[]不选择编译此项。
配置完成后根据提示保存,在 Linux 内核源码根目录下会生成一个隐藏的.config 文
48
第五章 嵌入式 Linux 内核移植
49
广东工业大学硕士学位论文
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 \
在上一节中,我们根据参考配置文件添加了移植目标板的配置文件,这一小节
根据目标板硬件修改 tiny4412SDK_defconfig 配置文件,裁剪 Linux 内核。在 Linux
内核源码目录执行命令:
$ make ARCH=arm tiny4412SDK_defconfig
$ make ARCH=arm menuconfig
在配置界面进行配置:
51
广东工业大学硕士学位论文
在 第 四 章 已 经 把 移 植 好 的 U-boot 烧 进 SD 卡 , 接 下 来 把 uImage 、 和
exynos4412-tiny4412SDK.dtb 拷贝进 SD 卡,目标开发板选择从 SD 卡启动,使其进
入 U-boot 命令行状态,如下图所示:
52
第五章 嵌入式 Linux 内核移植
53
广东工业大学硕士学位论文
a)
b)
54
第五章 嵌入式 Linux 内核移植
5.4 本章小结
55
广东工业大学硕士学位论文
57
广东工业大学硕士学位论文
在配置界面进行相应的配置。相关的配置如下:
选择 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
广东工业大学硕士学位论文
60
第六章 嵌入式 Linux 根文件系统构建
61
广东工业大学硕士学位论文
把 mk_ramdisk.sh 脚本放在/home/felix/目录下,执行如下命令执行该脚本:
$ cd /home/felix/
$ chmod 755 mk_ramdisk.sh
$ ./mk_ramdisk.sh
脚本执行完最后生成的 ramdisk.img 就是我们需要的 Ramdisk 文件系统了。
图 6-2 设置 bootcmd 参数
62
第六章 嵌入式 Linux 根文件系统构建
6.5 本章小结
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
结论与展望
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
广东工业大学硕士学位论文
68
攻读学位期间发表论文
攻读学位期间发表论文
69
广东工业大学硕士学位论文
70
致 谢
致 谢
在我三年研究生求学生涯即将结束之际,在此向给予我帮助、支持和鼓励的老
师、同学和家人致以最诚挚的感谢。
首先,感谢我的研究生导师陈益民副教授。在研究生学习期间,陈老师渊博的
知识和严谨的科研作风指导我在科研的道路上不断前行;生活中陈老师平易近人,
给予我无微不至的关怀。在论文完成之际,陈老师百忙之中抽空细心帮我批改论文,
针对论文出现的问题,给我提出了许多宝贵的修改意见,使我的论文更加完善。在
此,谨向陈老师致以崇高的敬意和衷心的感谢。
感谢实验室的师兄师姐和师弟师妹们,感谢你们的帮助,和你们在一起度过了
三年快乐的研究生求学生涯。感谢同窗的小伙伴林捷鸿、贾志文、陈诗特、胡奇宇、
聂梦君、黎丹雨、张鹏琴给予我在学习、生活上的帮助。
感谢我的家人一直以来对我的关心、支持和鼓励,你们永远是我的精神支柱和
坚强的后盾,愿你们身体健康。
最后,感谢审阅本论文的教授、专家和学者们,谢谢您们的悉心审阅和批评指
正。
罗名驹
2017 年 5 月
71
广东工业大学硕士学位论文
附录 A U-boot 源码中添加目标板目录和文件代码
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
附 录
75
广东工业大学硕士学位论文
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 时钟初始化关键代码
77
广东工业大学硕士学位论文
附录 C Exyson4412 串口初始化关键代码
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 内存初始化关键代码
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 内核移植代码
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