分享好友 系统运维首页 频道列表

X-012-kernel-serial early console的移植

Linux系统  2016-10-04 12:260

1. 前言

对Linux kernel工程师来说,最依赖的工具非printk莫属(不多解释,大家都懂)。因此,在Linux kernel移植的初期阶段,如果能够尽快地实现printk功能,将会为后续的工作带来极大的帮助。

在众多可用作printk输出的终端里面(串口、屏幕、USB、网络、等等),串口终端(也即串口驱动)无疑是实现起来最简单一种,因此也是嵌入式linux开发过程中(特别是早期阶段)最普遍使用的。

但是,受限于Linux TTY框架的复杂性 [1] ,长久以来,在Kernel移植的初期阶段(各种功能都不ready,缺乏有效的调试手段),快速的实现serial driver也是一个不小的挑战。不过,随着serial subsystem中的early console功能的出现,这种状况得到了极大的改善。

本文将借助“X Project” kernel的开发过程,介绍serial early console功能的移植过程。

注1:博客中“Linux TTY子系统 ”的分析正在缓慢推进,不过还未涉及console、serial subsystem、earlycon等模块。因此我一直在纠结先写理论(分析),还是先写实践(移植说明)。结论是先写本文,理由是:虽然earlycon功能涉及到TTY子系统的复杂知识,如console driver、tty driver、serial driver等等,但从移植的角度看,我们可以什么都不懂。这种优雅的抽象和封装,是优秀软件(如Linux kernel)所必需具备的特性,也是我们软件人需要竭力追求的神圣目标。

2. 移植步骤

2.1 串口驱动

early console是linux serial subsystem的一个子功能,因此需要依附于具体平台的serial driver之下(放心,本文不涉及任何串口驱动的知识)。以“X Project” 所使用的bubblegum-96平台为例,我们需要在“drivers/tty/serial/”下新建一个serial driver,并修改kernel serial subsystem的Kconfig和Makefile文件,将其添加到kernel的编译系统中, 步骤如下:

1)新建serial driver

touch drivers/tty/serial/ owl-serial.c

其中“owl”是bubblegum-96平台所使用SOC的代号,大家可以根据实际情况,使用和自己平台匹配的名称。

2)修改drivers/tty/serial/Kconfig和drivers/tty/serial/Makefile,将新建的serial driver加入到编译框架中

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig

index 13d4ed6..bbf4b69 100644

--- a/drivers/tty/serial/Kconfig

+++ b/drivers/tty/serial/Kconfig

@@ -1624,6 +1624,14 @@ config SERIAL_MVEBU_CONSOLE

and warnings and which allows logins in single user mode)

Otherwise, say 'N'.

+config SERIAL_OWL

+       tristate "Actions OWL serial port support"

+       depends on ARCH_OWL

+       select SERIAL_CORE

+       select SERIAL_CORE_CONSOLE

+       help

+         If you have a machine based on an Actions OWL CPU you

+         can enable its onboard serial ports by enabling this option.

endmenu

config SERIAL_MCTRL_GPIO

diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile

index 8c261ad..3f75d73 100644

--- a/drivers/tty/serial/Makefile

+++ b/drivers/tty/serial/Makefile

@@ -91,6 +91,7 @@ obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o

obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o

obj-$(CONFIG_SERIAL_STM32)     += stm32-usart.o

obj-$(CONFIG_SERIAL_MVEBU_UART)        += mvebu-uart.o

+obj-$(CONFIG_SERIAL_OWL)       += owl-serial.o

我们为新建的serial driver指定了“SERIAL_OWL”配置项,该配置项依赖ARCH_OWL [2]。 与此同时,我们需要选中“SERIAL_CORE”和“SERIAL_CORE_CONSOLE”两个配置项,以支持earlycon功能。

3)配置kernel,开启TTY、serial等功能,并使能我们新加入的serial driver

cd ~/work/xprj/build
make kernel-config

#选中如下的配置项
Device Drivers  --->
Character devices  --->
[*] Enable TTY
Serial drivers  --->
[*] Actions OWL serial port support

完成后make kernel重新编译即可。

2.2 early console的移植

实现early console的移植过程非常简单,包括:

1)实现一个early console的setup接口,并调用serial core提供的注册接口(EARLYCON_DECLARE)将其注册到kernel中,如下:

int __init earlycon_owl_setup(struct earlycon_device *device, const char *opt)

{

/* TODO */

uart5_base = early_ioremap(UART5_BASE, 4);

device->con->write = earlycon_owl_write;

return 0;

}

EARLYCON_DECLARE(owl_serial, earlycon_owl_setup);

其中“owl_serial”是early console的名称,earlycon_owl_setup是开始使用之前的初始化接口,需要在这个初始化接口中做两件事情:

进行一些必要的初始化,如例子中的寄存器map;

为printk输出制定一个write接口----earlycon_owl_write。

注2:“EARLYCON_DECLARE”是实现early console的一种方法,另外我们也可以使用device tree的方式,为了不增加复杂度,本文就不提及相关的实现了。

注3:为了简单,early console和u-boot [3] 使用相同的串口,并且使用相同的配置,因此不需要额外的初始化操作。

注4:虽然配置不变,我们还是需要访问串口寄存器输出字符串,因此需要map相应的IO地址,由于early console需要在很早的时候使用,此时mm还没有初始化,因此我们可以用early_ioremap [4] 进行map。

2)earlycon_owl_write的实现

console输出需要字符串处理,可以借用serial core的标准接口----uart_console_write:

static void earlycon_owl_write(struct console *con, const char *s, unsigned n)

{

/* TODO */

uart_console_write(NULL, s, n, owl_serial_putc);

}

我们需要做的就是提供一个字符输出的API----owl_serial_putc,具体可参考代码以及“ X-004-UBOOT-串口驱动移植(Bubblegum-96平台) [3] ”中有关的描述。

3)移植完成后重新编译kernel即可

3. early console的使用

移植完成后,可以通过kernel的命令行参数,告诉kernel在启动的时候使用该early console,参数的格式如下:

earlycon= owl_serial

其中“earlycon”是关键字,“ owl_serial ”是early console的名字。

命令行参数可以通过u-boot传入,为了测试方便,可以暂时加到kernel的配置项中 [5] ,如下:

#

# Boot options

#

-CONFIG_CMDLINE=""

+CONFIG_CMDLINE="earlycon=owl_serial"

以上改动具体可参考下面的patch:

https://github.com/wowotechX/linux/commit/1285ab5e6e5c5bb263a1d715fe04cca2d217bd98

4. 参考文档

[1] Linux TTY framework(2)_软件架构

[2] X-009-KERNEL-Linux kernel的移植(Bubblegum-96平台)

[3] X-004-UBOOT-串口驱动移植(Bubblegum-96平台)

[4]Fix-Mapped Addresses

[5] Linux kernel内核配置解析(5)_Boot options(基于ARM64架构)

查看更多关于【Linux系统】的文章

展开全文
相关推荐
反对 0
举报 0
评论 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
《Linux内核Makefile分析》之 auto.conf, auto.conf.cmd, autoconf.h【转】
转自:http://blog.sina.com.cn/s/blog_87c063060101l25y.html转载:http://blog.csdn.net/lcw_202/article/details/6661364  在编译构建性目标时(如 make vmlinux),顶层 Makefile 的 $(dot-config) 变量值为 1 。在顶层 Makefile 的 497-504 行看到:?1234

0评论2023-02-09755

沁恒CH32V003(二): Ubuntu20.04 MRS和Makefile开发环境配置
沁恒CH32V003(二): Ubuntu20.04 MRS和Makefile开发环境配置Ubuntu20.04 MRS和Makefile开发环境配置. 使用 MounRiver Studio Community IDE 进行开发是比较简单的一种方式, 前往http://mounriver.com/download下载 MounRiver_Studio_Community_Linux_V130, 如

0评论2023-02-07897

Linux 下 Make 命令实例讲解
Linux 下make命令是系统管理员和程序员用的最频繁的命令之一。管理员用它通过命令行来编译和安装很多开源的工具,程序员用它来管理他们大型复杂的项目编译问题。本文我们将用一些实例来讨论 make 命令背后的工作机制。Make 如何工作的对于不知道背后机理的人

0评论2017-01-06106

OpenWrt上用C来写一个Helloworld
陆续用OpenWrt已经有5年多了, 一直以来都没有勇气用OpenWrt写原生的C程序.OpenWrt本身是维护了一些菜谱(recipe), 表现形式是Makefile. 它里面定义了包名/描述/类别/上游等等信息.make menuconfig的时候, 会先把package/目录里的所有包都扫描一遍, 生成总体的M

0评论2016-12-23139

如何编写 makefile(上)
在unix环境下编写或者阅读一个C项目,如果不会makefile,将寸步难行。因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需

0评论2016-12-11114

使用pelican心得
####前言最近在用pelican借用GitHub Pages搭建我的小明明s Github, 总结了些心得####写好Makefileruby有rake,但是python的好像没什么好用的,还是用Makefile,简单粗暴.先看用的help:@echo 'Makefile for a pelican Web site ' @echo ' ' @echo 'Usage: ' @e

0评论2016-11-22129

MicroPython 升级至 1.8.6
micropython 升级到1.8.6版本。主要更新:v1.8.6ESP8266 port uses SDK 2.0, has more heap, has support for 512k devicesThis release brings some code size reductions to the core as well asmore tests and improved coverage which is now at 94.3%.Th

0评论2016-11-13155

每日一博 | 解析 Makefile 文件的构建规则
Makefile 编辑一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一

0评论2016-10-3181

Makefile隐含规则
Makefile两个隐含规则;将所有的name.o的依赖自动推导为name.c并使用规则$(CC) -c $(FLAGS) $(CPPFLAGS)得到目标。这个规则中只有-c是隐含规则中有的,后面两个变量是留给用户使用的,如果-c不够用,可以通过设置他们来改变这条隐含规则,有了这条隐含规则,下

0评论2016-10-1793

被忽视的另一个vmlinux
在x86平台,编译完内核后用find命令搜vmlinux,你可以看到有两个同名的文件。./vmlinux./arch/x86/boot/compressed/vmlinux当我第一次见到的时候,也是有点吃惊的。要不是这么多年在江湖行走,也不会这么淡定。谁会用到他其实之前我们就见到过了,不过当时并

0评论2016-10-13191

根目录vmlinux的编译过程
编译过内核的话,一般都会看到在根目录下有个文件vmlinux,这个就是通常所说的内核了。但是用了这么久,倒是从来没看过是怎么编译出来的。那今天我们就来探索一下。那些七大姑八大姨们一切的一切都是make读取makefile编译链接的,就好像孙悟空逃不出如来佛祖

0评论2016-10-1390

HEVC学习笔记11-gem5跑HM
IntroductionHEVC学习笔记系列目录GEM5是一款模块化的离散事件驱动全系统模拟器,它结合了M5和GEMS中最优秀的部分,是一款高度可配置、集成多种ISA和多种CPU模型的体系结构模拟器。M5是由Michigan大学开发的一款开源的多处理机模拟器,受到了业内的广泛关注,

0评论2016-10-0194

实践:GNU构建系统
在上一篇概念:GNU构建系统和Autotool,我对GNU构建系统从用户视角和开发者视角分别进行了阐述。本篇从我的实践总结的角度,并阐述如何从头开始规划一个基于GNU构建系统的项目。事实上,随着开发者对跨平台认知的深入和完善,才能逐渐掌握GNU构建。注意:本文

0评论2016-09-2973

Makefile构建前端项目
Make是GNU下的构建自动化工具,用于从源文件构建可执行程序和程序库。 由Makefile定义构建依赖关系,运行Make时这些依赖会递归地展开。 可以说Make和Bash是Linux下生存的必备技能,当然还需要一款你热爱的编辑器。Make还会检查文件修改时间来判断是否需要执行

0评论2016-09-29124

更多推荐