momo zone

调核人的blog

Monthly Archives: 五月 2012

kernel 开发的mail list

http://lwn.net

http://linux-mm.org

List name Description Web site / archive MLM address
Linux-MM memory management specific MARC majordomo@kvack.org
Linux-kernel main Linux kernel development list lkml.org majordomo@vger.kernel.org
kernelnewbies for people who want to learn hacking the Linux kernel Kernelnewbies ecartis@nl.linux.org

内核模块开发醒目 ~~ kernel 3.2 新增export.h

今天发现THIS_MODULE 宏不存在,原来是在linux/modules.h 中,先在被搬到了新增的export.h 里了。该头文件这样说道:

3 /*
  4  * Export symbols from the kernel to modules. Forked from module.h
  5  * to reduce the amount of pointless cruft we feed to gcc when only
  6  * exporting a simple symbol or two.
  7  *
  8  * If you feel the need to add #include <linux/foo.h> to this file
  9  * then you are doing something wrong and should go away silently.
 10  */
 11 
 12 /* Some toolchains use a `_' prefix for all user symbols. */

翻译如下:

导出内核符号到内核模块。减少因仅仅导出一两个内核符号而包含整个module.h ,减少gcc的编译负担 ,所以就从module.h分离出来了export.h。如果你想往export.h里面塞入一些东西,那么你应该是想错了,不要去动他。

LWN 上的介绍:

introduce export.h; reduce module.h usage

From: Paul Gortmaker <paul.gortmaker@windriver.com>
To: mingo@elte.hu, torvalds@linux-foundation.org
Subject: [RFC/PULL 00/11] introduce export.h; reduce module.h usage
Date: Thu, 28 Jul 2011 01:16:07 -0400
Message-ID: <1311830178-30314-1-git-send-email-paul.gortmaker@windriver.com>
Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org, linux-arch@vger.kernel.org
Archive-link: ArticleThread
I don't think there really is any rocket science or contentious stuff here.
It is a sensible cleanup that adds organization and speeds up compiles.
The RFC I'm hoping for is more about how/when we want to get this in tree.

The problem:
------------
	 The module.h header file contains a path to nearly every other
header, and it itself is implicitly used everywhere.  Such that if you
touch module.h and rebuild, it takes the same time as a completely clean
build.  We are feeding massive amounts of needless stuff to cpp on every
kernel build.  The "implicitly everywhere" problem is caused by common
header files (device.h, sock.h, etc) directly including module.h.

The solution:
-------------
	This also comes in two parts.  We can drastically reduce the
users of module.h by introducing an export.h -- so that every file
who isn't a module, but needs EXPORT_SYMBOL/THIS_MODULE, can instead
just use this lightweight header which in turn doesn't include any
others.  The "implicitly everywhere" can be solved by removing
module.h from all possible <linux/somefile.h> and replacing it with
a simple reference for "struct module". 

Solving the implicitly everywhere problem reveals lots of files who
were unknowingly capitalizing on having module.h present for its
contents, and contents of the files it in turn included.

Shown here in this RFC are the just the include/* patches which form
these two solutions.  What is *not* shown is the boring 150 or so
patches, all of the one-line variety, which deal with the fact that
people were implicitly taking advantage of module.h (and all its children
includes).  These all fall into one of these five mundane categories.

 1) adding module.h to files that were modular but were simply not
    including module.h because of its implicit presence everywhere.

 2) adding export.h to non-modular files that were not including module.h
    but were trying to use EXPORT_SYMBOL/THIS_MODULE macros.

 3) replacing module.h with export.h in non-modular files that are only
    trying to use EXPORT_SYMBOL/THIS_MODULE macros.

 4) adding in various other headers, like <linux/stat.h> that were simply
    implicitly present via happenstance of the module.h's sub-includes.

 5) deleting the <linux/module.h> from files who were including it but
    not doing anything at all related to modules.

Note that #3 and #5 don't show up as warnings/errors, I had to actively
hunt out those optimizations manually.  In total, all the one line
"fallout" changes add to this cleanup to give it this footprint:

 1148 files changed, 1263 insertions(+), 428 deletions(-)

[If I knew it was going to be that involved, I'd probably would have
 never undertaken to start this in the 1st place...]

I've kept these changes all grouped into arch and subsystem categories
in case people want to see this go in chunks via maintainer trees (as it
is much easier to combine things than try to "un-combine" things.)

For all 160 commits, the branch "module.h-split", available here:

	git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux.git

has the complete content.  I've put the header changes after all the
patches from the top 5 categories, so that people bisecting non related
issues at a later date don't get hit with a commit zone with build failures.

The original idea for this cleanup came from Ingo[1], and in that same
thread, I'd posted[2] preliminary data on my work-in-progress.  Also in the
thread, Ingo had some positive feedback (many thanks!) and benchmark
numbers[3], indicating that we really probably want to to go with this.

Since that discussion, I've spawned out to cover allyesconfig builds in
powerpc, sparc, arm, mips, x86, x86-64 in order to hunt down and squash
build failures caused by people assuming module.h content is present.

I am sure that some of the less common arch (DEC Alpha, etc.) may still
have some of these assumptions lingering in their arch specific drivers,
but I don't see fixing these outliers as they arise as an issue.

Anyway, unless there is considerable objection to what is here, I'd like
to have Linus simply pull this directly.  That is what Ingo recommended,
and also my personal preference.  But I'm OK with feeding it in chunkwise
via individual maintainer trees if people want that instead.

Thanks,
Paul.

[1] https://lkml.org/lkml/2011/5/23/76
[2] https://lkml.org/lkml/2011/5/27/459
[3] https://lkml.org/lkml/2011/5/28/60

奇怪 svn 版本的mplayer 编译错误了

今天发现之前编译的mplayer没有cdda 支持,找了一下发现svn默认不带cdda的库,需要手动装一下:libcdio++0 ,libcdio-devel。

接着奇怪的问题出现了,提示找不到netinet/sctp.h  我查了一下确实没有,只有内核目录include/net/sctp/ 中有。不过路径也不同啊。哦,我也许应该去make headers_install ,因为我最近刚刚升级了kernel。很不幸问题依旧。

算了不折腾了,我在config.mk 里面直接关闭sctp协议支持。不过我想得太简单了,ffmpeg子目录里的配置文件根本不看这个config.mk 所以直接提示缺少sctp支持。我回想了下最近的一次svn up 是在两周前,于是我尝试回滚代码。问题依旧,继续回滚。无论回滚多久问题依旧,我看了下代码,我想应该include <netinet/sctp.h> 应该不是最近才加的。无奈google一下 netinet/sctp.h  发现某人说要加libsctp-dev  ,赶紧zypper 一下,果然有lksctp-tools ,lksctp-tools-devel 两个包,装上再make 万事ok  。 我的妈啊,这也太坑爹了 ,我之前从来没有装过这个包,而且svn我都同步过,编译过无数次了,就这次有问题。

比minicom更好的ckermit

用minicom的都会遇到各种错乱,异常和怪异现象。换用ckermit吧问题少很多。

下载完ckermit rpm并安装,修改/root/.kermrc文件如:

set prompt Linux Kermit>
set line /dev/ttyS0
set speed 115200
set carrier-watch off
set handshake none
set flow-control none
robust
set file type bin
set file name lit
set rec pack 1000
set send pack 9024
set window 5
set protocol xmodem
set protocol zmodem

 

启动ckermit :  输入kermit进入命令模式。

接着在命令模式输入c 将连接设定过的串口设备,进入通讯模式。这里就是进入终端了。比minicom好多了,彩色图形也显示正常。窗口大小也比较稳定。

依次键入<Ctrl-\>  C 返回到命令模式,用send 命令可以把文件从本地传送到远程。

Kermit Xmodem Xmodem-1K Ymodem Ymodem-G Ymodem-1K Zmodem

Kermit Xmodem Xmodem-1K Ymodem Ymodem-G Ymodem-1K Zmodem

【背景】

在串口中传输文件,所用到的协议,常常有KermitXmodemYmodemZmodem等,对这些协议,单独看名字,就很容易混淆,搞不懂都是啥意思。所以,写此文,总结各自的特点,解释他们之间的区别和联系。

 

【常见的RS232串口中所用到的传输协议之间的区别和联系】

此处主要讨论RS232即串口应用中,用来传输数据或文件的协议,主要有这些:

KermitXmodemXmodem-1KYmodemYmodem-GYmodem-1KZmodem

下面简述各自的异同点。

协议名称 相同点 各自特性 说明 对应软件或命令
Kermit 都是常见的文件传输协议,主要应用于RS232串口应用中 计算机系统中的文件传输和管理协议。

特点:

1)文本文件和二进制文件传输

2)全双工,半双工(8 -bit),7-bit的串行连接;

3)协议对底层介质不做限制,跨平台性很好。

4)已在N多平台中实现了此协议,即用途相当地广泛。

Kermit名字的来源是来自Kermit the Frog from The Muppets (1)Uboot中的loadb;

 

XYZModem Xmodem Xmodem 一个简单的文件传输协议。将文件拆分成很多个固定大小的数据包,数据包大小是128字节,然后以一个数据包,一个数据包的形式发送数据。中间会带有一些额外信息,用于握手协议等方面,以保证得知接收方正确接收了数据包。

 

要点:

1)将文件拆分,以固定大小的数据包发送。

2)数据包大小Packet size=128Byte

1Xmodem最开始是在早期的BBS系统中很流行,因为其协议足够简单,很容易实现。

2)由于效率太低,导致其他很多人在此基础上去对其扩展,以提高性能。

3Chuck Forsberg收集了众多的扩展功能,以此形成Ymodem,但是由于没有很成功的实现,导致实际应用产生各种变体。

但是其后来设计了Zmodem,由于效果太好,导致完全取代了之前的各种Xmodem的变体,包括Ymodem

(1)PC Linux中的rx/sx

(2)嵌入式Linuxlrzsz

Xmodem-1K Ymodem-1K,详情参见Ymode-1K
Ymodem Ymodem Xmodem(和Modem7)的基础上开发出来的,本身协议和Xmodem是一样的,只是在文件传输开始之前,多加了个Block0,用于传输文件名,文件大小,时间戳等信息。 本来协议设计者
Chuck Forsberg
都设计了好多可选的特性,以便于此协议可以用到多种环境和平台中,然后再换个协议名称的。但是实际上实现了Ymodem的应用中,都只是支持了1KB的包大小和CRC模式,除此之外的其他一些特性,都没实现,所以后来就还是沿用了旧的Ymodem这一叫法。同时,也导致了现存的很多Ymodem互相不是很兼容。
(1)uboot中的loady命令;

(2)PC Linux中的rb/sb

(3)嵌入式Linuxlrzsz

Ymodem-1K 此协议是在,原先Ymodem的数据包大小是(同Xmodem协议相同的)128byte的基础上,改成了
Packet size=1024byte=1KB
原先Ymodem协议中,数据包大小为1KB,是个可选的设置项。此Ymodem-1K,作为Ymodem的变体,却没有实现Ymodem其他的一些特性,所以,最好是叫做XModem-1K
Ymodem-G Ymodem的变体,流数据传输,用于信号很好(error-free)的传输环境中。

其(1)取消了CR2)取消了,在发送下一个数据包之前,必须等待接受者的ACK

由于取消CRCACK等待,此协议理论上,速度会比Zmodem快,但是实际上用此此协议的很少。因为,在16550 UAT出现之前,很明显,此协议有个严重的问题,那就是缓存溢出(buffer overrun),即接受者来不及处理数据,你就接着发下一个数据包了。
Zmodem Xmodem发展而来,取代了Ymodem,算是Ymodem的终结者。

核心改进在于,引入了滑动窗口(sliding window)以提高性能。

其支持很多特性:

1)可重传机制;

2)发送者可自动开始传输;

3)扩展的32位的CRC校验;

4)可传输控制字符;

(1)PC Linux中的rz/sz

(2)嵌入式Linuxlrzsz

 

注释:

1.常见的Ymodem的实际是Ymodem-1K

虽然严格意义上说,Ymodem,数据表示128字节,但是很多具体Ymodem的实现,实际上是把Ymodem认为是1KB的数据包,即这类Ymodem的实现,虽然也叫Ymodem,但是实际上是Ymodem-1K,即:

常见的Ymodem == Ymodem-1K

 

例子:

1Windows XP自带的超级终端(Hyper Terminal)中的Ymodem,就是默认1KB的数据包大小。

2)而SecureCRT中的Ymodem默认是数据包是128字节,可以设置为128B1KB

 

2. lrzsz是嵌入式中常用的通过串口传输文件的工具,是PCLinux中的rz/sz的精简版。
【引用】

1. XMODEM

http://en.wikipedia.org/wiki/XMODEM

 

2. Ymodem

http://en.wikipedia.org/wiki/YMODEM

 

3. Zmodem

http://en.wikipedia.org/wiki/ZMODEM

 

4. Kermit

http://en.wikipedia.org/wiki/Kermit_(protocol)

 

5.
rz(1) – Linux man page

http://linux.die.net/man/1/rz

 

6. lrzsz: free x/y/zmodem implementation

http://ohse.de/uwe/software/lrzsz.html

EIA-232 ,RS-232 俗称的串口

serial –unit=0 –speed=115200 –word=8 –parity=no –stop=1
terminal –timeout=5 console serial
default 0
timeout 8
title GDB — openSUSE 12.1 – 3.1.0-1.3-desktop
    root (hd0,1)
    kernel /boot/vmlinuz-3.1.0-1.3-desktop-mod root=/dev/disk/by-id/ata-HTS541040G9SA00_MPBBP0X2JNDPTM-part2 showopts nmi_watchdog=0 kgdb=ttyS0,115200 kgdboc=ttyS0,115200  vga=0x31b kgdbwait s
    initrd /boot/initrd-3.1.0-1.3-desktop-mod
###Don’t change this comment – YaST2 identifier: Original name: linux-ttyS0###
title TTY — openSUSE 12.1 – 3.1.0-1.3-desktop
    root (hd0,1)
    kernel /boot/vmlinuz-3.1.0-1.3-desktop-mod root=/dev/disk/by-id/ata-HTS541040G9SA00_MPBBP0X2JNDPTM-part2 showopts console=tty0 console=ttyS0,115200n8 vga=0x31b
    initrd /boot/initrd-3.1.0-1.3-desktop-mod
minicom 中如果发现长宽不对可以用resize 重置,如果发现乱码可以用reset重置
设置串口控制器(硬件):
setserial

语 法:setserial [-abgGqvVz][设备][串口参数]
补充说明:setserial可用来设置串口或显示目前的设置。
参 数:
-a 显示详细信息。
-b 显示摘要信息。
-g 显示串口的相关信息。
-G 以指令列表的格式来显示信息。
-q 执行时显示较少的信息。
-v 执行时显示较多的信息。
-V 显示版本信息。
-z 设置前,先将所有的标记归零。
常用方法:
1.在/etc/rd.d/目录下编写脚本,进行驱动文件与串口芯片的关联
2.在/dev/目录下执行:setserial -a -g ttyS* 查看所有的扩展串口设备链接情况

关于baud_base和speed 看下这段(引自Serial-HOWTO):

How speed is set in hardware: the divisor and baud_base

Speed is set by having the serial port’s clock change frequency. But this change happens not by actually changing the frequency of the oscillator driving the clock but by “dividing” the clock’s frequency. For example, to divide by two, just ignore every other clock tick. This cuts the speed in half. Dividing by 3 makes the clock run at 1/3 frequency, etc. So to slow the clock down (meaning set speed), we just send the clock a divisor. It’s sent by the serial driver to a register in the port. Thus speed is set by a divisor.

If the clock runs at a top speed of 115,000 bps (common), then here are the divisors for various speeds (assuming a maximum speed of 115,200): 1 (115.2k), 2 (57.6k), 3 (38.4k), 6 (19.2k), 12 (9.6k), 24 (4.8k), 48 (2.4k), 96 (1.2k), etc. The serial driver sets the speed in the hardware by sending the hardware only a “divisor” (a positive integer). This “divisor” divides the “maximum speed” of the hardware resulting in a slower speed (except a divisor of 1 obviously tells the hardware to run at maximum speed).

There are exceptions to the above since for certain serial port hardware, speeds above 115.2k are set by using a very high divisor. Keep that exception in mind as you read the rest of this section. Normally, if you specify a speed of 115.2k (in your communication program or by stty) then the serial driver sets the port hardware to divisor 1 which sets the highest speed.

Besides using a very high divisor to set high speed, the conventional way to do it is as follows: If you happen to have hardware with a maximum speed of say 230.4k (and the 230.4k speed has been enabled in the hardware), then specifying 115.2k will result in divisor 1. For some hardware this will actually give you 230.4k. This is double the speed that you set. In fact, for any speed you set, the actual speed will be double. If you had hardware that could run at 460.8k then the actual speed would be quadruple what you set. All the above assumes that you don’t use “setserial” to modify things.

Setting the divisor, speed accounting

To correct this accounting (but not always fix the problem) you may use “setserial” to change the baud_base to the actual maximal speed of your port such as 230.4k. Then if you set the speed (by your application or by stty) to 230.4k, a divisor of 1 will be used and you’ll get the same speed as you set.

If you have very old software which will not allow you to tell it such a high speed (but your hardware has it enabled) then you might want to look into using the “spd_cust” parameter. This allows you to tell the application that the speed is 38,400 but the actual speed for this case is determined by the value of “divisor” which has also been set in setserial. I think it best to try to avoid using this kludge.

There are some brands of UARTs that uses a very high divisor to set high speeds. There isn’t any satisfactory way to use “setserial” (say set “divisor 32770”) to get such a speed since then setserial would then think that the speed is very low and disable the FIFO in the UART.

Crystal frequency is higher than baud_base

Note that the baud_base setting is usually much lower than the frequency of the crystal oscillator since the crystal frequency of say 1.8432 MHz is divided by 16 in the hardware to get the actual top speed of 115.2k. The reason the crystal frequency needs to be higher is so that this high crystal speed can generate clock ticks to take a number of samples of each bit to determine if it’s a 1 or a 0.

Actually, the 1.8432 MHz “crystal frequency” may be obtained from a 18.432 MHz crystal oscillator by dividing by 10 before being fed to the UART. Other schemes are also possible as long as the UART performs properly.

设置串口终端属性:
stty
该程序设置spped ,特殊终端符号等。注意和setserial 的区别。
最常用的用法,获得指定串口的tty设置:stty -a -F /dev/ttyS0
设置tty速度 stty 115200 -F /dev/ttyS0
当使用stty命令而出现一些混乱或者更糟的是,使用一个程序而使终端设置完全混乱了时怎么办?要回到“现实”,试试下面的命令:
stty sane
如果击键变得混乱时,试着用〈CTRL+j〉来把命令括起来,输入〈CTRL+j〉的顺序是先按下CTRL再键入j键。
<ctrl+j> ctty sane <ctrl+j>
minicom ctrl+z 无效的解决方法:
启动时加参数 minicom -m 将用ESC -> z 取代<Ctrl-z>