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

   2016-10-04 0
核心提示:1. 前言对Linux kernel工程师来说,最依赖的工具非printk莫属(不多解释,大家都懂)。因此,在Linux kernel移植的初期阶段,如果能够尽快地实现printk功能,将会为后续的工作带来极大的帮助。在众多可用作printk输出的终端里面(串口、屏幕、USB、网络、等等

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架构)

 
标签: Makefile
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 《Linux内核Makefile分析》之 auto.conf, auto.
    转自: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
    02-09
  • Linux下的自动化构建工具之make/makefile的用法详解
    Linux下的自动化构建工具之make/makefile的用法
    目录一、make和makefile的区别二、makefile的原理1、make的原理详解2、临时文件的清理3、文件的三个时间三、makefile的推导规则四、实现一个进度条1、缓冲区问题2、实现倒计时程序3、进度条的实现一、make和makefile的区别make是一个命令,makefile是一个文件
  • 沁恒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, 如
    02-07
  • Linux 下 Make 命令实例讲解
    Linux 下make命令是系统管理员和程序员用的最频繁的命令之一。管理员用它通过命令行来编译和安装很多开源的工具,程序员用它来管理他们大型复杂的项目编译问题。本文我们将用一些实例来讨论 make 命令背后的工作机制。Make 如何工作的对于不知道背后机理的人
    01-06 Makefile
  • Linux 用Makefile编译C代码
    Linux 用Makefile编译C代码
    在Linux里写C语言代码一般用gcc编译,如果是一些小的程序可以使用gcc命令编译,但是当我们写一个大的项目的时候,我们总会把头文件,主函数,子函数等分别放到一个文件里,这样可以让代码看起来没有那么长,在排错的时候会更方便一点。可是问题又来了,那么多
    01-06 Makefile
  • OpenWrt上用C来写一个Helloworld
    陆续用OpenWrt已经有5年多了, 一直以来都没有勇气用OpenWrt写原生的C程序.OpenWrt本身是维护了一些菜谱(recipe), 表现形式是Makefile. 它里面定义了包名/描述/类别/上游等等信息.make menuconfig的时候, 会先把package/目录里的所有包都扫描一遍, 生成总体的M
  • 如何编写 makefile(上)
    在unix环境下编写或者阅读一个C项目,如果不会makefile,将寸步难行。因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需
    12-11 Makefile
  • Linux Makefile编写 详述
    Linux Makefile编写 详述
    我之前总结了gcc的用法,那么在实际工作中,每次用gcc会很麻烦,尤其是一些大型项目,有很多的目录结构,这个时候我们就需要编写Makefile文件,然后在实际工作中,用make来编译大型的项目,相信搞过Android开发的一定对make,make install,make clean不陌生
    12-01 Makefile
  • Linux AutoTools工具 详述
    Linux AutoTools工具 详述
    我们前面分析了Makefile的编写,其实一个大的项目,如果手工去写Makefile的话会比较累,那么我们可以用AutoTools的一系列工具来生成Makefile Linux Makefile编写 详述 http://www.linuxidc.com/Linux/2016-11/137506.htm 大家在Linux中下载的任何源码包都需要
  • u-boot学习笔记(一)————浅析Makefile
    u-boot学习笔记(一)————浅析Makefile
    u-boot移植难度最大的地方莫过于适配,你得看懂芯片英文手册,看得懂电路图还有熟悉各种汇编和寄存器…对硬件读图能力和软件编程能力要求都很高,先抛开u-boot的硬件功能不谈,基本上任何一个C语言项目的编译的入口点 Makefile ,所以磨刀不误砍柴工对 Makefi
点击排行