[转]ALSA 0.9.0 HOWTO — 基本PCM音频

最近在写一个LINUX下的播放器,在做音频输出的时候想到了ALSA-LIB,这是LINUX下音频输出的一个库,差不多是事实标准了.所以我找了这么一篇HOWTO作为参考.为了加深理解,我把其中最重要也是大家最常用到的回放(PLAYBACK)部分的文字翻译了一遍.由于本人尚未通过英语4级,译文难免有大把错误,还请众位看官不吝指正.

ALSA 0.9.0 HOWTO — 基本PCM音频

作者: Matthias Nagorni
译者: Kevin Lei
转载请注明出处:http://blog.csdn.net/kevinleicn/

1. 介绍

这个HOWTO计划提供一个简短的介绍,使用ALSA 0.9.0写一个简单的音频应用程序.

Section2解释了PCM音频最基本的函数.如果你删除其中的解释文本,那么最后你会得到一个极小的PCM回放程序. Section3简短地讨论了一些PCM截获函数.

在Section4 你将学习怎么为ALSA音序器写一个简单的客户端.这一章节基于seqdemo.c这个例子,一个可以接收MIDI事件并且表示大多数重要的事件类型的程序.Section5演示ALSA MIDI音序器怎样被用于"路由"MIDI事件,从一个输入端口到一些输出端口.这一段基于midiroute.c这个例子.

Section6 使PCM回放和MIDI输入联结起来,并且解释了迷你合成器–miniFMsynth.c.这一章节引入基于回调的音频回放,就像Paul Davis在linux-audio-dev邮件列表里建议的那样.Section7对基于ALSA音序器队列的MIDI调度提供一个短小的介绍,基于 miniArp.c这个例子.

推荐你也看看doxygen生成的ALSA库函数参考.

编译一个ALSA应用程序:

只要用-lasound参数并且确保你已包含了
#include <alsa/asoundlib.h>

2. 基本PCM音频

为ALSA 0.9.0写一个简单的PCM应用程序我们首先需要一个PCM设备的句柄.然后我们必须指定同时可供回放或截获的PCM流的方向.我们同样必须提供一些关于我们想要使用的设置选项的信息,比如缓冲区大小,采样率,PCM数据格式等.所以,首先我们声明:

/* Handle for the PCM device */
snd_pcm_t *pcm_handle;

/* Playback stream */
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;

/* This structure contains information about */
/* the hardware and can be used to specify the */
/* configuration to be used for the PCM stream. */
snd_pcm_hw_params_t *hwparams;

最重要的ALSA PCM设备接口是"plughw"和"hw"接口. 如果你使用"plughw"接口,你不需要很在意声卡硬件.如果你的声卡不支持你指定的采样率或采样格式,你的数据将自动被转换.这同样适用于声道的访问类型和号码.对于"hw"接口,你必须检查你的硬件是否支持你想要使用的设置选项.

/* Name of the PCM device, like plughw:0,0 */
/* The first number is the number of the soundcard, */
/* the second number is the number of the device. */
char *pcm_name;

然后我们初始化变量并分配一个hwparams结构:

/* Init pcm_name. Of course, later you */
/* will make this configurable ;-) */
pcm_name = strdup("plughw:0,0");

/* Allocate the snd_pcm_hw_params_t structure on the stack. */
snd_pcm_hw_params_alloca(&hwparams);

现在我们可以打开PCM设备:

/* Open PCM. The last parameter of this function is the mode. */
/* If this is set to 0, the standard mode is used. Possible */
/* other values are SND_PCM_NONBLOCK and SND_PCM_ASYNC. */
/* If SND_PCM_NONBLOCK is used, read / write access to the */
/* PCM device will return immediately. If SND_PCM_ASYNC is */
/* specified, SIGIO will be emitted whenever a period has */
/* been completely processed by the soundcard. */
if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0) {
fprintf(stderr, "Error opening PCM device %sn", pcm_name);
return(-1);
}

在我们可以往声卡写PCM数据之前,我们必须指定访问类型,采样格式,采样率,声道号码,周期数目以及周期大小.首先,我们以声卡的全部设置选项空间来初始化hwparams结构.

/* Init hwparams with full configuration space */
if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
fprintf(stderr, "Can not configure this PCM device.n");
return(-1);
}

关于合适的设置选项的信息,能使用命名了的函数的一个集合来获得.

snd_pcm_hw_params_can_<capability>
snd_pcm_hw_params_is_<property>
snd_pcm_hw_params_get_<parameter>

绝大多数重要的参数的可用性,换句话说,访问类型,缓冲区大小,声道号码,采样格式,采样率,以及周期数目,可以以函数命名的一个集合来检验.

snd_pcm_hw_params_test_<parameter>

如果"hw"接口被使用,这些查询函数尤其重要.设置选项空间能以一个函数命名的集合限制在某一设置选项

snd_pcm_hw_params_set_<parameter>

例如,我们假设声卡可以被设置为16位,Little Endian数据的立体声回放,44100Hz采样率.相应地,我们限制设置选项空间匹配于这个设置选项:

int rate = 44100; /* Sample rate */
int exact_rate; /* Sample rate returned by */
/* snd_pcm_hw_params_set_rate_near */
int dir; /* exact_rate == rate –> dir = 0 */
/* exact_rate < rate –> dir = -1 */
/* exact_rate > rate –> dir = 1 */
int periods = 2; /* Number of periods */
snd_pcm_uframes_t periodsize = 8192; /* Periodsize (bytes) */

访问类型指定了哪一个多声道数据储存在缓冲区的方法.对于交错访问,缓冲区里的每一个帧为声道容纳连续的采样数据.对于16位立体声数据,这意味着缓冲区以字为单位为左右声道交错地容纳采样数据.对于非交错访问,每一个周期为第一个声道容纳所有采样数据接着是第二个声道的采样数据.

/* Set access type. This can be either */
/* SND_PCM_ACCESS_RW_INTERLEAVED or */
/* SND_PCM_ACCESS_RW_NONINTERLEAVED. */
/* There are also access types for MMAPed */
/* access, but this is beyond the scope */
/* of this introduction. */
if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
fprintf(stderr, "Error setting access.n");
return(-1);
}

/* Set sample format */
if (snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE) < 0) {
fprintf(stderr, "Error setting format.n");
return(-1);
}

/* Set sample rate. If the exact rate is not supported */
/* by the hardware, use nearest possible rate. */
exact_rate = rate;
if (snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_rate, 0) < 0) {
fprintf(stderr, "Error setting rate.n");
return(-1);
}
if (rate != exact_rate) {
fprintf(stderr, "The rate %d Hz is not supported by your hardware.n
==> Using %d Hz instead.n", rate, exact_rate);
}

/* Set number of channels */
if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2) < 0) {
fprintf(stderr, "Error setting channels.n");
return(-1);
}

/* Set number of periods. Periods used to be called fragments. */
if (snd_pcm_hw_params_set_periods(pcm_handle, hwparams, periods, 0) < 0) {
fprintf(stderr, "Error setting periods.n");
return(-1);
}

缓冲区尺寸的单元依赖于函数.一些时候是字节,一些时候是必须指定的帧的数目.一个帧是对所有声道的采样数据数组.对于16位立体声数据,一个帧的长度是4个字节.

/* Set buffer size (in frames). The resulting latency is given by */
/* latency = periodsize * periods / (rate * bytes_per_frame) */
if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize * periods)>>2) < 0) {
fprintf(stderr, "Error setting buffersize.n");
return(-1);
}

如果你的硬件不支持2的N次方的缓冲区大小,你可以使用snd_pcm_hw_params_set_buffer_size_near函数.这个函数工作起来与snd_pcm_hw_params_set_rate_near相似.现在我们为PCM设备申请由pcm_handle指向的设置选项.这同样也将准备好PCM设备.

/* Apply HW parameter settings to */
/* PCM device and prepare device */
if (snd_pcm_hw_params(pcm_handle, hwparams) < 0) {
fprintf(stderr, "Error setting HW params.n");
return(-1);
}

在PCM设备被设置以后,我们可以开始对其写PCM数据.第一个写访问将开始PCM回放.对于交错写访问,我们使用函数:

/* Write num_frames frames from buffer data to */
/* the PCM device pointed to by pcm_handle. */
/* Returns the number of frames actually written. */
snd_pcm_sframes_t snd_pcm_writei(pcm_handle, data, num_frames);

对于非交错访问,我们将必须使用函数:

/* Write num_frames frames from buffer data to */
/* the PCM device pointed to by pcm_handle. */
/* Returns the number of frames actually written. */
snd_pcm_sframes_t snd_pcm_writen(pcm_handle, data, num_frames);

在PCM回放开始之后,我们必须确保我们的应用程序发送足够的数据到声卡缓冲区.否则,将发生缓冲区欠载.当这样一个缓冲区欠载发生以后,snd_pcm_prepare将被调用.一个简单的立体声锯齿波能以这样的方式生成:

unsigned char *data;
int pcmreturn, l1, l2;
short s1, s2;
int frames;

data = (unsigned char *)malloc(periodsize);
frames = periodsize >> 2;
for(l1 = 0; l1 < 100; l1++) {
for(l2 = 0; l2 < num_frames; l2++) {
s1 = (l2 % 128) * 100 – 5000;
s2 = (l2 % 256) * 100 – 5000;
data[4*l2] = (unsigned char)s1;
data[4*l2+1] = s1 >> 8;
data[4*l2+2] = (unsigned char)s2;
data[4*l2+3] = s2 >> 8;
}
while ((pcmreturn = snd_pcm_writei(pcm_handle, data, frames)) < 0) {
snd_pcm_prepare(pcm_handle);
fprintf(stderr, "<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>n");
}
}

如果我们想中止回放,我们既可以使用snd_pcm_drop,也可以使用snd_pcm_drain.第一个函数将立即中止回放并丢弃未回放的帧.后一个函数将在回放完所有帧后中止回放.

/* Stop PCM device and drop pending frames */
snd_pcm_drop(pcm_handle);

/* Stop PCM device after pending frames have been played */
snd_pcm_drain(pcm_handle);

(全文完)

参考链接:

原文
http://www.suse.de/~mana/alsa090_howto.html

Linux音频编程指南
http://www-128.ibm.com/developerworks/cn/linux/l-audio/

A Tutorial on Using the ALSA Audio API
http://www.equalarea.com/paul/alsa-audio.html

The ALSA library API reference
http://www.alsa-project.org/alsa-doc/alsa-lib/

编辑者: kevinleicn (06-08-15 19:05)

Read: 960

如何在Linux下实现设备的配置(上)

级别: 初级

于辰涛 (scu_yct@263.net), 软件工程师, 联想(北京)电脑公司

2001 年 8 月 01 日

本文是 《如何在Linux下实现硬件的自动检测》的姊妹篇。将为您介绍在进行了设备检测,通过设备信息文件获得了设备对应的驱动程序,工作参数等信息后,如何对于几种最常见的设备进行配置、生成正确的配置脚本,以使设备正常工作。

Linux下设备的配置过程是指在检测到设备类型、设备当前工作参数等信息之后,使用这些信息来配置设备的驱动程序,工作方式等,(设备的检测过程参见 《如何在Linux下实现硬件的自动检测》)。要完成这样的任务,需要做两方面的工作:

其一是需要一个详尽的设备信息文件,这个文件描述了设备标识、与设备标识对应的设备驱动程序、设备配置参数(设备选项)、设备设置的详细描述、设备配置方法描述、设备对应的别名、设备的主设备号等信息。

现在的Linux内核中使用kmod来完成设备模块的自动加载,它的一般工作机制是:在第一次引用设备模块时,内核使用系统命令/sbin/modprobe加载这个设备模块。为了使这种机制正常工作,您首先需要使用depmod -a建立表述模块之间依赖关系的文件modules.dep,然后在/etc/modules.conf中设置正确的设备别名(关于/etc/modules.conf的详细介绍参见本文 附录A),如果还需要设置设备对应的参数。举例来说,在设置网卡时网卡的驱动程序是ne2k-pci,网卡的设备别名是eth0,则在文件/etc/modules.conf中加入别名alias eth0 ne2k-pci,就设置了ne2000兼容的PCI网卡,这样当有程序要尝试访问网络时,内核会自动加载网卡驱动程序ne2k-pci。

其二是需要根据设备的类型,以及安装的Linux系统版本(不同的Linux发行版对于同一设备的配置脚本文件存在差异),设置设备对应的配置脚本文件。

配置键盘

1.1 配置键盘的设备模块

对于我们常见的键盘一般有三种类型,其一为老式的五针键盘,其二为ps/2键盘,其三是usb鼠标。对于前两种键盘,一般现在的Linux发行版都把它们需要的设备模块打包入内核,所以无需进行附加的模块插入操作,键盘就能够正常工作。而对于usb类型的键盘,一般而言,要使它正常工作必须先插入对应的设备模块。

对于usb类型的键盘,您若是要通过手动加载模块的方式使其工作,必须首先插入usb桥接器模块,然后您还必须插入键盘模块usbkbd.o,以及keybdev.o,这样usb键盘才能够正常工作。此时,运行的系统命令:

/sbin/modprobe usbkbd
/sbin/modprobe keybdev

对于2.2.x系列的内核若要内核的kmod在需要时自动加载则必须在/etc/modules.conf文件中设置别名usb-interface,它对应您所使用的桥接器模块。例如,当桥接器的类型为UHCI时,在/etc/modules.conf中加入设备别名:
alias usb-interface usb-uhci

对于2.4.x系列的内核,此设备别名则变为:
alias usb-controller usb-uhci
在设置了此别名之后,系统启动时会自动进行usb设备检测。当检测过程发现连结的设备是系统支持的,那么系统会自动插入所需的模块。

1.2 键盘配置文件

键盘的配置文件/etc/sysconfig/keyboard,它的内容很简单,可选配置项为KEYTABLE(随着发行版本的不同这个文件的内容会有所差异,但是这个字段是最重要的)。例如,当设置KEYTABLE = "us"时,表示系统使用美式键盘。

然后,为了正确的使用键盘上的功能键,您还需要调用命令dumpkeys生成文件/etc/sysconfig/console/default.kmap。
/usr/bin/dumpkeys > /etc/sysconfig/console/default.kmap
这个文件描述了键盘的键盘扫描码和加入键盘修饰之后的键盘的相应的键盘扫描码。

同样,为了键盘能在X系统环境下正常工作,您可能也需要在X系统下对键盘进行设置,这时您就必须使用xmodmap来设置正确的键盘映射。例如,
/usr/X11R6/bin/xmodmap /usr/share/xmodmap/xmodmap.fr
设置您的X系统下的键盘为法语键盘。

在正确的配置了/etc/sysconfig/keyboard文件之后,X系统的配置程序会根据此文件的信息配置X中关于键盘配置的小节。当此文件内容不正确或者是此文件不存在时,X系统是无法启动和配置的。


回页首

配置鼠标

2.1 鼠标的基本信息

Linux支持四种不同的总线鼠标硬件接口:Inport(Microsoft),Logitech,PS/2和ATI-XL。2.4内核也支持IBM PC110数字化板和Apple Desktop鼠标。

  • Inport mice
    Inport mice包含大多数旧类型的微软鼠标。Inport mice通常连接到主板的接口卡上。假如鼠标线连接头是圆的,有9针,则可能是Inport mice。
  • Logitech mice
  • PS/2 mice
  • ATI combo video/mice
  • IBM PC110 palmtop digitizer
  • Apple Desktop Mouse
  • Hybrid Mice

对于鼠标协议,大多数总线鼠标使用BusMouse协议,一些古老的Logitech鼠标使用MouseSystems协议,而一些更老的微软鼠标使用Logitech协议。PS/2鼠标总是使用PS/2协议。

不同类型的鼠标对应的设备文件:

表2-1

接口类型 设备 主设备号 次设备号
Logitech /dev/logibm 10 0
PS/2 /dev/psaux 10 1
Inport /dev/inportbm 10 2
ATI-XL /dev/atibm 10 3
USB mouse /dev/input/mice 13 63

创建对应设备的命令:

mknod /dev/logimm   c 10 0
mknod /dev/psaux c 10 1
mknod /dev/inportbm c 10 2
mknod /dev/atibm c 10 3
mknod /dev/input/mice c 13 63

在创建了鼠标对应的设备文件之后,因为现在很多程序都使用/dev/mouse作为缺省的鼠标设备文件,所以为了使鼠标正常工作你还要创建一个符号连接 /dev/mouse指向真实的鼠标设备文件。例如,对于ps/2鼠标,/dev/mouse指向/dev/psaux,对于usb鼠标, /dev/mouse/指向/dev/input/mice,对于串口鼠标/dev/mouse指向/dev/ttyS0。对于不同的linux发行版本,这些文件可能有所不同,上述介绍主要是基于Redhat发布的配置。

对于现在最常见的三种鼠标:串口鼠标、PS/2鼠标和USB鼠标而言,由于对PS/2鼠标支持一般都打在内核中,所以您也不需要在鼠标工作之前插入设备模块。但对于其他的两种鼠标,插入模块的操作一般是必须的。对于串口鼠标而言,您必须先插入模块serial.o,

/sbin/modprobe serial

成功的插入模块之后,如果串口鼠标支持 即插即用的串口协议,您可以从串口(/dev/ttyS*)读到鼠标的类型信息,然后由此信息,完成鼠标的配置文件。对于USB鼠标,为了使其正常工作,您必须先插入模块usbmouse.o和mousedev.o

/sbin/modprobe usbmouse
/sbin/modprobe mousedev

同样,为了使鼠标驱动程序能够自动加载,您也需要在/etc/modules.conf文件中创建usb-interface(usb-controller)别名。

2.2 鼠标配置文件

正确配置鼠标必须生成配置文件/etc/sysconfig/mouse,它包括下列选项:MOUSETYPE、XMOUSETYPE、FULLNAME、 XEMU3、DEVICE。该鼠标配置文件也是X配置文件中鼠标配置节的基础。如果没有这个文件,很多X配置程序将无法工作。

MOUSETYPE=
配置鼠标的类型,包括ps/2、Busmouse、imps2、netmouse、Microsoft、Logitech、MouseMan、MMHitTab、MouseSystems、pnp、logim、ms3、MMSeries等。

XMOUSETYPE=
X系统下配置的鼠标的类型,包括MouseMan、IntelliMouse、MMSeries、MMHittab、Logitech、MouseMan、Microsoft、MouseSystems、PS/2、BusMouse等。

FULLNAME=
描述鼠标设备的全名。例如,对于普通PS/2鼠标,其全名为PS/2|Standard。

XEMU3=
是否仿真三键鼠标,可选参数为yes或no。

DEVICE=
描述鼠标对应的设备文件。例如。对于普通PS/2鼠标,设备文件为psaux。

2.3 鼠标的配置技巧

通过gpm能在命令行方式下使用鼠标。这样在控制台方式下,就可以使用鼠标进行剪贴等操作了。例如,对于ps/2鼠标,它的配置方式是:
gpm -t ps/2 -m /dev/psaux
如果不指定-m选项,那么系统会去查找文件/dev/mouse。

鼠标移动不规则可能是因为对鼠标设置了错误的协议。如新的Logitech鼠标不使用Logitech协议,而用微软协议(MouseMan)。如果您的鼠标移动不规则,那您可能首先需要尝试更换一下MouseType(XMouseType)指定的值。
在X系统下,您如果需要更换鼠标的左、右键,那么可以执行xmodmap -e "pointer = 3 2 1"。


回页首

网卡配置过程

3.1 配置网卡的设备模块

按照总线类型来分,现在的以太网卡主要有PCI网卡、ISA网卡和PCMCIA网卡。为使这些网卡正常工作,要在/etc/modules.conf中设置设备别名eth0,以及要传递给驱动程序的设备参数。这样内核在需要使用驱动程序时,会由内核服务kmod使用系统命令modprobe(insmod)自动装载需要的设备模块。

在配置网卡时,如果此网卡能够自动检测,那么您只需要通过设备标识,在设备描述信息文件中查得它对应的设备驱动程序,然后再由此信息配置网卡。但是这种方法对于普通isa总线的ne2000兼容网卡就不适合了,因为它们在设计时一般不满足isapnp规范,因此无法读出它们的设备信息。但是这种类型的网卡一般使用ne作为设备驱动程序,但是为使其正常工作还须指定io地址和占用的irq。

例如,对于ne2000兼容的isa网卡,比如DE220X,它们的驱动程序为ne。此时要使这种网卡正常工作,需要在/etc/modules.conf文件中加入:

alias eth0 ne
options ne io=0x300 irq=5

一般而言,对于这种网卡,只有指定了正确的I/O地址空间,网卡才能正常工作。这个地址是和此网卡在DOS下使用的端口地址完全相同的。如果端口地址0x300上不能找到网卡,那么您可以试试0x240等其他地址。

3.2 网卡配置文件

要正确的配置网卡必须生成如下脚本文件,/etc/sysconfig/network,/etc/sysconfig/network- scripts/ifcfg-eth0(对于只有一个网卡时,多个网卡为ifcfg-eth1、ifcfg-eth2以此类推)和/etc/hosts。若您还需要配置域名解析服务,那么还要生成文件/etc/resolv.conf。

对于/etc/sysconfig/network脚本文件,最常用的可设置项包括NETWORKING,FORWARD_IPV4,HOSTNAME, DOMAINNAME,GATEWAY,GATEWAYDEV。注意:在没有配置网卡时,也要设置此文件,以使得本机的回环设备(lo)能够正常工作,此设备是很多linux内部通讯的基础。

NETWORKING=
表示系统是否使用网络,一般设置为yes。如果设为no,则不能使用网络,而且很多系统服务程序将无法启动。

FORWARD_IPV4=
表示是否支持ipv4的自动转发。一般在只有一块网卡时,设置此项为false。

HOSTNAME=
设置本机的主机名,这里设置的主机名要和/etc/hosts中设置的主机名对应。

DOMAINNAME=
设置本机的域名。

GATEWAY=
设置本机连接的网关的IP地址。例如,网关为10.0.0.2

GATEWAYDEV=
与此网关进行通讯时,所使用的网卡设备别名。例如,当使用了一块网卡,并连接了网关时,此时的值为eth0。

缺省没有网卡时的设置为:

       NETWORKING="yes"
FORWARD_IPV4="false"
HOSTNAME="localhost.localdomain"
DOMAINNAME="localdomain"

/etc/sysconfig/network-scripts/ifcfg-*,描述网络接口的信息。每个不同的网络接口对应不同的文件。例如, ifcfg-eth0对应第一块网卡eth0可能出现的配置信息。常见的配置选项包括DEVICE、BOOTPROTO、IPADDR、NETMASK、 NETWORK、BROADCAST、ONBOOT。

DEVICE=
描述网卡对应的设备别名,例如ifcfg-eth0的文件中它为eth0。

BOOTPROTO=
设置网卡获得ip地址的方式,可能的选项为static,dhcp或bootp,分别对应静态指定的ip地址,通过dhcp协议获得的ip地址,通过bootp协议获得的ip地址。

IPADDR=
如果设置网卡获得ip地址的方式为静态指定,此字段就指定了网卡对应的ip地址。

NETMASK=
网卡对应的网络掩码。

NETWORK=
网卡对应的网络地址。

BROADCAST=
对应的子网广播地址。

ONBOOT=
系统启动时是否设置此网络接口,设置为yes时,系统启动时激活此设备。

/etc/resolv.conf,系统生成这个文件进行域名解析。否则,安装过程的反向名查询无法工作。可能出现的选项:
searchdomainName指定的域名
nameserverdnsServer 域名服务器,可以指定多个。
/etc/hosts,将主机名列表加入此文件。


回页首

Modem配置过程

对于Modem的配置过程而言,我们现在一般使用kppp进行拨号,使用这个程序整个拨号过程将变得非常简单。因此本文就不再介绍使用pppd和chat 进行的手工拨号过程了。本文仅介绍一下如何设置基本的设备驱动模块和底层设备文件的配置。在配置这些文件之后,您就可以使用kppp拨号了。

4.1 外置Modem

在配置外置Modem时,因为大部分的Modem都是通过串口连接到计算机上的,所以在配置Modem之前,您必须插入串口驱动模块serial.o。在成功插入串口通讯模块之后,这时只要将设备/dev/modem连接到相应的串口设备上就可以了。例如,在/dev/ttyS0(对应Windows下的 COM1)上连接了Modem,则建立连接:
ln -sf /dev/ttyS0 /dev/modem

在这之后,外置的串口modem就可以正常工作了。您可以通过使用minicom向串口发送AT命令,来检测和配置modem的工作方式。经常使用的命令:

表 4-1

AT命令 命令描述
ATDT(ATDP) 使用语音(脉冲)进行拨号
ATZ 复位调制解调器
ATH 挂起电话
ATI0 返回调制解调器的状态
ATI1 执行ROM校验和检查并返回值
ATI2 验证ROM校验,返回OK或ERROR
ATI3 返回ROM部件的软件版本号。
ATI4 查询调制解调器的状态信息,包括波特率、奇偶校验位长度,字长度、拨号方式、寄存器状态等信息。
ATI5 查询调制解调器的ram中的状态信息。
ATI6 查询调制解调器的链路状态信息,包括已传送(接收、丢失)的字符数、传送的数据块数目、链路连接状态、最后一次拨号时间等。
ATI7 获得配置的序言文件,此文件描述的信息包括:modem支持的通讯协议,Fax版本号,EPROM的版本号。
ATI8 获得连接时间
ATI9 获得调制解调器的描述名称

例如,对于一款联想射雕外置式Modem,在启动minicom之后,输入ATI9的返回值为:
(1.0AKY1010\ModemAKY101056K DATA FAX VOICE MODEM)FF

4.2 内置的Linmodem

Linmodem 是winmodem的Linux实现。关于Linmodem的进一步信息您可以访问www.linmodems.org。现在的Linmodem一般都是 PCI类型的,您也可以通过PCI检测过程,获得设备设备描述信息。在获得描述信息之后,您可以比较一下您的Modem是否属于下面列出的Modem类型。现在支持的Linmodem包括:

Linmodem为了在某种程度上和外置调制解调器的编程接口一致,所以一般都要生成一个仿真的串口设备。为了生成这些设备文件,一般可以使用命令mknod。

  • Lucent LT:
    mknod /dev/ttyS14 c 62 78
  • PCTel:
    mknod /dev/ttyS15 c 62 79
  • Esscom:
    mknod /dev/esscom c 127 1。esscom用户希望连接/dev/ttyS14到/dev/esscom,以使得仅识别ttyS*的ppp拨号程序能正常使用。

    chgrp uucp /dev/ttyS14
    chmod 666 /dev/ttyS14
    可允许非根用户使用此服务拨号。
    ln -s /dev/devicefile /dev/modem

    您也可以使用setserial,修改串口配置,比如设置串口的波特率,同样也可以设置/etc/serial.conf设置串口的工作参数。
    setserial -agv /dev/ttyS*


回页首

声卡配置过程

5.1 内核声卡驱动程序的配置

现在正在使用的声卡主要有PCI和ISA两种。在Linux系统下,对这两种类型声卡的配置过程实际上是生成配置文件/etc/modules.conf,建立正确的设备别名和声卡设备驱动程序的对应关系。在正确的设置驱动模块之后,使用混音器程序设置声卡的输出音量。

若您的声卡是ISA PnP类型的,那么如果这块声卡在dos(windows)系统下也工作良好,那么您可以先记住声卡的工作参数,包括IRQ、DMA和I/O。一般而言,在Linux系统下应该使用和DOS下一样的参数。

如果您不知道它的工作参数,您可以通过/proc/isapnp获得声卡的配置空间,它包括dma、ioport和irq等信息。然后您可以通过检查 /proc/interrupts,/proc/ioports和/proc/dma文件获知系统中空闲的irq、ioports和dma等信息,由此您可以选择合适的声卡配置参数。

在2.4.x内核中,实现了ISA PnP支持,同时一部分声卡驱动程序现在也支持无需使用isapnp工具完成自动检测和配置了。关于声卡设备的详细信息您也可以查看内核文档/usr/src/linux/Documentation/sound/中的文件。

对于PCI声卡而言,它们的驱动程序包含了自动检测过程,所以您只需要插入正确的驱动模块,声卡一般就能正常工作了。

在声卡模块被第一次引用时,内核会要求加载相应的驱动模块。与声卡模块对应的设备别名是sound-slot-0(0表示系统中的一个声卡,以此类推)。例如,在/etc/modules.conf中加入:
alias sound-slot-0 esssolo1
就配置了ESS Solo-1声卡。这条语句表示在需要声卡时,自动加载模块esssolo1。

有时加载了sound-slot-0对应的设备模块之后,并不能使声卡的所有功能生效。这时设备就会请求访问sound-service-0-n别名。n代表了不同的设备:

表 5-1

编号 对应的设备
0 混音器(Mixer)
2 MIDI
3,4 DSP

这时就要求您设置正确的声卡服务模块别名,这样声卡才能够正常工作。声卡对应的设备文件:

表 5-2

设备文件名 设备描述
/dev/audio 正常连接到/dev/audio0
/dev/audio0 sun工作站兼容的声音设备(仅部分实现,不支持sun ioctl接口,仅支持u-law编码)
/dev/audio1 第二个声音设备(安装多个声卡时使用)
/dev/dsp 正常连接到/dev/dsp0
/dev/dsp0 第一个数字采样设备
/dev/dsp1 第二个数字采样设备
/dev/mixer 正常连接到/dev/mixer0
/dev/mixer0 第一个声音混音器
/dev/mixer1 第二个声音混音器
/dev/music 高级序列化接口
/dev/sequencer 底层MIDI,FM和GUS存取
/dev/sequencer2 正常连接到/dev/music
/dev/midi00 第一个原MIDI端口
/dev/midi01 第二个原MIDI端口
/dev/midi02 第三个原MIDI端口
/dev/midi03 第四个原MIDI端口
/dev/sndstat 显示声音驱动程序的状态

pc扬声器提供下列设备:

/dev/pcaudio            等价于/dev/audio
/dev/pcsp 等价于/dev/dsp
/dev/pcmixer 等价于/dev/mixer

您可以直接将声音文件送入对应的设备,比如,将.au声音文件通过将其送入/dev/audio中播放,原始采样也可被送入/dev/dsp。

cat sample.su > /dev/audio

但是这样做一般效果较差,播放时应采用play命令。对于wavplay和vplay(snd-util包)会以最好的效果播放wav文件,但是它们不能识别微软adpcm压缩的wav文件。若手动设置争取正确的参数之后,splay用于播放大多数声音文件。

读/dev/audio和/dev/dsp返回的采样数据可以重定向到一个文件。vrec可以使这个过程更容易。可能需要一个混音器程序选择适当的输入设备。

5.2 ALSA声卡驱动程序的配置

对于声卡驱动程序,除了内核自带的驱动程序之外,您还可以使用Advanced Linux Sound Architecture(ALSA,http://www.alsa-project.org/)提供的驱动程序。它支持一系列主流声卡,同时它和内核的声音结构互相兼容,在某种程度上,可以说是内核的声卡驱动模块的补充。

ALSA的声卡驱动程序的一般命名规则是snd-card-<soundcard>。soundcard代表不同类型的声卡。例如,对于所有的16位Soundblaster声卡,它们对应的驱动程序模块为snd-card-sb16。

若与需要linux内核声音驱动的向后兼容性,您还需要两个模块snd-pcm-oss和snd-mixer-oss。对于amixer设置的多个混音器,它们都是针对不同的设备的。比如CD通道的设置是针对CD播放器的。而很多应用程序,如象mpg123,xmms,realplayer,都要依赖 PCM通道的设置。MIC代表麦克风。不同的Gain部分对于不同的使用能提供特别的增益。

缺省情况下ALSA静音所有的输出。为了获得声音,必须解除主音量和PCM音量的静音。

amixer -c 0 sset 'Master',0 100%,100% unmute
amixer -c 0 sset 'PCM ',0 100% unmute

选项包括mute,unmute,capture,nocapture,rec,norec,数字或left:right。amixer不带参数运行时,返回声卡上所有通道的设置情况。

为了在每次插入声卡驱动模块时,都打开静音,您可以在/etc/modules.conf加入下列语句:

post-install snd-card-sb16 amixer -c 0 sset 'Master',0 100%,100% unmute && amixer -c 0 sset 'PCM ',0 100% unmute

在成功插入了alsa声卡模块之后,系统会出现/proc/asound目录,这个目录描述了声卡的工作情况,以及创建的设备文件。

在您加载snd-pcm-oss设备模块之后,你也能使用与oss兼容的方式存取声卡,这时如下的映射会被完成:

表 5-3

ALSA设备 OSS设备 次设备号
/dev/snd/pcmC0D0 /dev/audio0(/dev/audio) 4
/dev/snd/pcmC0D0 /dev/dsp0(/dev/dsp) 3
/dev/snd/pcmC0D1 /dev/adsp(/dev/adsp) 12
/dev/snd/pcmC1D0 /dev/audio1 20
/dev/snd/pcmC1D0 /dev/dsp1 19
/dev/snd/pcmC1D1 /dev/adsp1 28
/dev/snd/pcmC2D0 /dev/audio2 36
/dev/snd/pcmC2D0 /dev/dsp2 35
/dev/snd/pcmC2D1 /dev/adsp2 44

对于/dev/mixer设备,要加载snd-mixer-oss,可以保证和老的oss混音器的兼容性。如果您插入了上述设备之后,声音系统仍无法正常工作,您可以运行snddevices命令,建立正确的设备文件。

由于为使ALSA正常工作,需要设置大量的设备别名,下面就给出一个/etc/modules.conf的例子,它能够完成ESS Solo1声卡的自动配置工作。其他的ALSA设备的设置也基本与此声卡相同。

# 设置ALSA设备的主设备号,它固定为116

alias char-major-116 snd

# 设置OSS设备的主设备号,它固定为14,这使得ALSA复用OSS设备

alias char-major-14 soundcore

# ALSA设备别名

alias sound-card-0 snd-card-es1938

# OSS设备别名

alias sound-slot-0 sound-card-0

# 安装不同的声卡服务

alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias snd-minor-oss-12 snd-pcm-oss

# 运行amixer命令,打开声音输出

post-install snd-card-es1938 amixer -c 0 sset 'Master',0 100%,100% unmute && amixer -c 0 sset 'PCM ',0 100% unmute

待续

关于作者

于辰涛,联想(北京)电脑公司软件工程师。目前主要从事Linux系统安装程序的开发工作,主要研究兴趣是操作系统的工作机制和开发底层系统程序。您可以通过电子邮件 scu_yct@263.net 跟他联系。

Read: 651

[转]摄像头在Linux操作系统中的驱动方法v0.1b

作者:北南南北
来自:LinuxSir.Org
摘要:本文主要内容是摄像头(WebCam)在Linux操作系统中的驱动方法;本文是以源码码编译的方法来安装驱动程序的;虽然能把摄像驱动起来,但缺少好的视频聊天程序。看来只能一步一步的来了。希望就在眼前; 本文正在修正中…..请指点,谢谢~~

目录



+++++++++++++++++++++++++++++++++++++++++++++
正文
+++++++++++++++++++++++++++++++++++++++++++++


1、摄像头(Webcam)驱动说明;

摄像头在Windows的驱动极为容易,最多是点几下鼠标,没有什么太大的难度。但在Linux中,驱动起来是有点困难,这并不是说Linux多高雅。只能说开发商唯利是图,没有好处的事,他们的确不怎么积极。Linux 的用户比较少,所以他们也不把用户当回事。

目前看来摄像头(Webcam)在 Linux 中驱动基本成熟,缺少的是应用程序的支持,比如即时通讯工具支持视频的好程序比较少。有些芯片组是没有任何问题,在国内,大多摄像头的芯片组是Z- Star,也有显示为Vimmicro(和Z-Star是同样的芯片)的。在Fedora 5.0或SuSE 10.x中,已经支持了很多摄像头,应该说即插即用。对于我们来说,是不是即插即用,那是另一回事,只有幸运儿才有这个的福气。如果您的摄像头接上还是用不了,那您就有必要看一下我写的这个文档了。

本文操作环境: Fedora Core 5.0 。由于大部份是用源码包编译 ,所以还是有通用性的;


1.1 摄像头在Linux中是如何支持的;

在 Linux中,硬件的驱动程序,都是由内核支持的;目前比较新内核版本也集成了一些的摄像头驱动。就是Fedora、SuSE最新版本所支持的内核也是来自由 kernel.org 。所以支持也是极为正常的。内核对硬件的支持分为内置于和外挂模块两种方便。对于摄像头来说,大多是模块支持的;


1.2 摄像头(Webcam)驱动网址;

http://mxhaard.free.fr

目前最新版本的摄像头驱动,已经到了 spca5xx-20060501.tar.gz 版本;您可以在上面的地址下载;


2、驱动摄像头详细过程;


2.1 查看摄像头型号;

我们用用到 lshal 工具,在老版本的Linux是没有这个工具的。在最新版本的Linux都有这个工具;

[root@localhost ~]# lshal |grep WebCam
   info.product = 'ZC0303 WebCam' (string)
   usb_device.product = 'ZC0303 WebCam' (string)

上面这个命令是列出系统硬件设备,然后从输出中,提取WebCam字样的信息。这说明这个摄像头是ZC0303芯片组的;如果想更详细的,就用下面的命令,找到带有ZC0303 WebCam设备的详细信息,就把所有USB设备都列出来;

[root@localhost ~]# lshal |grep usb

然后就找 ZC0303字样的设备 ,那一大段都要仔细的看;

也可以这样的方法;

[root@localhost ~]# lshal  -s |grep usb
usb_device_0_0_0000_00_1d_0
usb_device_0_0_0000_00_1d_0_if0
usb_device_4fc_3_noserial
usb_device_4fc_3_noserial_if0
usb_device_4fc_3_noserial_if0_logicaldev_input
usb_device_4fc_3_noserial_usbraw
usb_device_0_0_0000_00_1d_0_usbraw
usb_device_0_0_0000_00_1d_1
usb_device_0_0_0000_00_1d_1_if0

usb_device_ac8_303b_noserial
usb_device_ac8_303b_noserial_if0
usb_device_ac8_303b_noserial_usbraw
usb_device_ac8_303b_noserial_video4linux

usb_device_0_0_0000_00_1d_1_usbraw
usb_device_0_0_0000_00_1d_2
usb_device_0_0_0000_00_1d_2_if0
usb_device_0_0_0000_00_1d_2_usbraw
usb_device_0_0_0000_00_1d_7
usb_device_0_0_0000_00_1d_7_if0
usb_device_0_0_0000_00_1d_7_usbraw

我们看到带有video4linux字样的,他的设备号是 usb_device_ac8_303b_noserial_video4linux字样的,在其前面还有几个差不多的编号的设备。比如 usb_device_ac8_303b_noserial。我们就先查这个设备,大多数这样的一组相似的设备号,查第一个就能知道是什么设备。于是用。。

[root@localhost ~]# lshal -l -u usb_device_ac8_303b_noserial
udi = '/org/freedesktop/Hal/devices/usb_device_ac8_303b_noserial'
   info.udi = '/org/freedesktop/Hal/devices/usb_device_ac8_303b_noserial' (string)
   linux.subsystem = 'usb' (string)
   linux.hotplug_type = 1 (0x1) (int)
   usb_device.bus_number = 3 (0x3) (int)
   usb_device.can_wake_up = false (bool)
   usb_device.is_self_powered = false (bool)
   usb_device.version_bcd = 272 (0x110) (int)
   usb_device.speed_bcd = 4608 (0x1200) (int)
   usb_device.linux.device_number = 2 (0x2) (int)
   usb_device.num_ports = 0 (0x0) (int)
   usb_device.max_power = 160 (0xa0) (int)
   usb_device.device_revision_bcd = 256 (0x100) (int)
   info.product = 'ZC0303 WebCam' (string)
   usb_device.product = 'ZC0303 WebCam' (string)
   info.vendor = 'Z-Star Microelectronics Corp.' (string)
   usb_device.vendor = 'Z-Star Microelectronics Corp.' (string)
   usb_device.product_id = 12347 (0x303b) (int)
   usb_device.vendor_id = 2760 (0xac8) (int)
   usb_device.device_protocol = 0 (0x0) (int)
   usb_device.device_subclass = 0 (0x0) (int)
   usb_device.device_class = 255 (0xff) (int)
   usb_device.num_interfaces = 1 (0x1) (int)
   usb_device.num_configurations = 1 (0x1) (int)
   usb_device.configuration_value = 1 (0x1) (int)
   usb_device.linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-1' (string)
   info.linux.driver = 'usb' (string)
   info.bus = 'usb_device' (string)
   info.parent = '/org/freedesktop/Hal/devices/usb_device_0_0_0000_00_1d_1' (string)
   linux.sysfs_path_device = '/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-1' (string)
   linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-1' (string)


这回应该详细了吧。看上面的设备是哪个厂出品的?

usb_device.vendor_id = 2760 (0xac8) (int)
usb_device.product_id = 12347 (0x303b) (int)
info.product = ‘ZC0303 WebCam’ (string)
info.vendor = ‘Z-Star Microelectronics Corp.’ (string)
usb_device.product_id = 12347 (0x303b) (int)

在Gnome桌面环境下,还用hal-gnome软件包工具可用;您可以通过下面的方式来安装此软件包

[root@localhost ~]# yum install hal-gnome

然后运行hal-device-manager工具;

[root@localhost ~]# hal-device-manager

点鼠标查看摄像头的详细信息还是没有问题吧。

关于hal的相关知识:《Fedora Core 4.0 HAL配置即插即用移动存储(USB及1394)的实践》


2.2 根据摄像头信息到驱动网站对号入座;

请参见: http://mxhaard.free.fr/spca5xx.html

请注意:这两个最重要的信息,也驱动网址摄像头芯片所对应地址对号入座,如果这张列表上没有摄像头,可能您得等一等了。不过也不是绝对的,给开发者捐赠一个不被支持的摄像头,肯定能解决。驱动开发者有捐赠主页,不妨捐一个看看。

usb_device.vendor_id = 2760 (0xac8) (int)
usb_device.product_id = 12347 (0x303b) (int)

比如我的这款摄像头,在其网站上,显示为支持。


2.3 摄像头驱动的选择;

spca5xx-20060501.tar.gz


对于Fedora Core 5.0 4.0 摄像头驱动RPM包:

其实在Fedora Core 5.0 中已经有这款驱动的RPM包了,但我尝试后发现根本不能用。如果您也想尝试RPM包,请到下面的网址去下载;或用YUM在线安装也行,不过得设置YUM的源;请参考:《关于Fedora Core 5.0 通过Yum在线升级说明》

http://mirrors.ircam.fr/pub/atrpms/fc5-i386/atrpms/RPMS.testing

如果是Fedora 4.0的,就到下面的地址去下载;

http://mirrors.ircam.fr/pub/atrpms/fc4-i386/atrpms/RPMS.testing/

首先:要看自己的内核版本,然后再下载;

[root@localhost ~]# uname -r -i

其次:下载软件包选择;

下载spca5xx开头的,要安装两个包左右,一个是 spca5xx-kmdl,另一个是 video4linux-kmdl,还有一个是 video4linux-kernheaders。根据软件包的时间、版本、内核版本对照下载安装。这方面不能说的太多。自己试试看,我是没有成功。


2.4 下载并编译内核;

由于RPM包安装上也不可用,所以我采用的是源码包安装的方法,当然因为我用的是比较新的内核,2.6.16.19。所以这个文档就是通用性了。源码包安装大多都差不多。所以其它发行版本也可以做为参考。


2.41 下载内核;

我测试摄像头所用的内的内核版本是 2.6.16.19;

linux-2.6.16.19.tar.bz2

下载内核配置文件:

我从Slackware的FTP上,找到了2.6.16.19的配置文件。请到这里下载;kernel261619.txt


2.42 编译内核;

第一步:解压内核软件包;

[root@localhost ~]# tar jxvf linux-2.6.16.19.tar.bz2
[root@localhost ~]# mv linux-2.6.16.19 /usr/src

把下载下来的内核配置文件改名复制到 /usr/src/linux-2.6.16.19

[root@localhost ~]# cp kernel261619.txt /usr/src/linux-2.6.16.19/.config

第二步:编译内核;

[root@localhost ~]# cd /usr/src/linux-2.6.16.19/
[root@localhost linux-2.6.16.19]# make
[root@localhost linux-2.6.16.19]# make modules_install
[root@localhost linux-2.6.16.19]# make install

第三步:查看/boot/grub/menu.lst文件;

一般的情况下,make install 安装内核后,系统会把启动写入GRUB的配置文件。/boot/grub/menu.lst。您可以看到有类似如下的一段;

title Fedora Core (2.6.16.19)
         root (hd0,6)
         kernel /boot/vmlinuz-2.6.16.19 ro root=LABEL=/1 rhgb quiet
         initrd /boot/initrd-2.6.16.19.img

对于其它发行版本,您可以修改menu.lst文件。修改方法,请参见:《系统引导管理器GRUB,为初学者指南》


2.5 编译摄像头驱动程序;

在编译摄像头驱动的前题是,我们要用2.6.16.19这个内核来启动系统,然后在 2.6.16.19内核系统环境下编译摄像头驱动;


2.51 下载摄像头驱动;

http://mxhaard.free.fr

spca5xx-20060501.tar.gz


2.52 解压编译;

再说一点,可能在编译的过程中需要各种开发库和或开发工具之类的,比如gcc、make、automake等,您要懂得自己把这些东西安装上;少什么就安装什么吧。

[root@localhost ~]# tar zxvf spca5xx-20060501.tar.gz
[root@localhost ~]# cd spca5xx-20060501
[root@localhost spca5xx-20060501]# make
[root@localhost spca5xx-20060501]# make install
[root@localhost spca5xx-20060501]# depmod -a
[root@localhost spca5xx-20060501]# modprobe spca5xx

看看驱动模块挂载好了没有?

[root@localhost spca5xx-20060501]# lsmod |grep spca5xx
spca5xx 659920 0
videodev 7040 1 spca5xx

我们再查看一下设备/dev/video0是否存在?

[root@localhost spca5xx-20060501]# ls -lh /dev/video0
crw------- 1 beinan root 81, 0 06-08 09:33 /dev/video0


3、摄像头应用程序 SpcaView;


3.1 SpcaView 软件包,包括一组工具;

spcaview工具是用来纪录数据流,也能用来播放数据;
spcaserv 是流媒体服务器;
spcacat 简单图片的抓取工具;

SpcaView 下载和安装;

下载地址:

http://mxhaard.free.fr/spca50x/Download ,我下载的是目前这个版本:spcaview-20051212.tar.gz

依赖关系;

此软件依赖 libsdl,要先安装它才行,下载地址:http://www.libsdl.org ,我下载的是:SDL-1.2.10.tar.gz

http://www.libsdl.org/download-1.2.php

[root@localhost ~]# tar zxvf SDL-1.2.10.tar.gz
[root@localhost ~]# cd SDL-1.2.10
[root@localhost SDL-1.2.10]# ./configure ; make ;make install

安装SpcaView:

[root@localhost ~]# tar zxvf spcaview-20051212.tar.gz
[root@localhost ~]# cd spcaview-20051212
[root@localhost spcaview-20051212]# make ; make install

配置可执行程序的路径:

可执行的工具被安装到 /usr/local/bin目录中,所以我们还要配置一下用户的环境变量PATH 。配置命令执行路径,在当前用户家目录下的.bashrc文件中加入下面的一行;

export PATH=".:/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/X11R6/bin"

然后运行如下命令;

[root@localhost ~]# source .bashrc

关于路径的配置,请参考:《Linux 命令及可执行程序路径的设置》《关于Linux 文件系统中路径的理解》


3.2 通用spcaview来测试摄像头;

[root@localhost ~]# spcaview -d /dev/video0 -f jpg -s 320x240

如果您想看的图像分辨率,可以调整 -s后面的参数,比如 640×480

如果抓取数据流,尝试用下面的命令,比如我们把抓取的数据流存在一个linuxsir.org.avi文件中;如果想播放,就用mplayer就行,xine也可以。

[root@localhost ~]# spcaview -f yuv -o linuxsir.org.avi

看一下图吧:

更多的帮助: http://mxhaard.free.fr/sview.html


4 即时通讯工具;

即时通讯工具在 Linux 视频下比较少,其中有aMSN,不过aMSN虽然能简单的应用,但如果您的机器是接在路由器或防火墙之后,还要配置端口转发。由于我的路由器功能比较差,所以没有发现有哪块配端口转发。不过在公司内部局域网和同事聊天还是能用看到对方的。Mercury 也是MSN的客户端,需要Java虚拟机支持,安装起来有点麻烦。我在Fedora 5.0 Core 中没有安装成功。如果您想安装尝试,请自行安装一下。如果有问题,咱们再交流;


4.1 aMSN ;

主页:http://amsn.sourceforge.net

aMSN 支持视频,不过在路由器或防火墙后的计算机需要配置路由器。我和公司同事聊天测试,无需配置路由器。由于我的路由器功能比较简单,还没有找到相应的选项。看两张图吧;—— 2006.06.08 北南南北;

今天(2006.06.10),我换了一个路由器,总算把这个问题测试成功了;在路由器上找到 有ip forward 类似的选项,要把 6890 – 6900转发到您所用的计算机上上的端口上,协议是TCP/UDP。比如我用的计算机的IP地址是:192.168.1.3;我的路由器上有NAT 选项,我在NAT中的防火墙规则中设置的。也就是把 来自WAN的数据流,协议TCP/UDP ,端口 6890 – 6900,转发到 192.168.1.3 机器上的 6890 – 6900。—— 2006.06.08 北南南北;


4.2 Mercury (MSN客户端)

主页: http://www.mercury.to


4.3 Gaimvv ;

主页: http://gaim-vv.sourceforge.net

Gaim-vv 包含支持YahooMessager 视频功能;目前Gaimvv已停止开发,据说在未来的Gaim 2.x中要做为重点开发;Gaim-vv效果还是不错的,遗憾的是只支持 YahooMessager 视频。我测试了 Gaim-vv 的YahooMessager 视频,性能还比较不错,对系统资源占用相对来说较少。


5、未尽事宜;


6、关于本文;

前年为了测试在Linux下是否能用摄像头,买了一个摄像头,由于没有驱动,被迫放弃。那个摄像头也没用几次就报废了。白白费掉一百多RMB。这次又去电子城,顺便弄回一只,这次的运气应该比上次要好的多,毕竟能驱动起来。虽然在Linux 中支持摄像头的程序不太多,我感觉只所以出现这样的情况,就是因为摄像头的驱动程序太少了。这次一个法国的老兄出手了,据说能N多芯片的。。。。。。。这是一个开头,并不是结局。好事在后头呢;


7、更新日志;

2006.06.08 0.1b 完成正文;


8、参考文档;

http://mxhaard.free.fr


Read: 539

Linux系统环境变量

Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。

Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。

常见的环境变量

对于PATH和HOME等环境变量大家都不陌生。除此之外,还有下面一些常见环境变量。

◆ HISTSIZE是指保存历史命令记录的条数。

◆ LOGNAME是指当前用户的登录名。

◆ HOSTNAME是指主机的名称,许多应用程序如果要用到主机名的话,通常是从这个环境变量中来取得的。

◆ SHELL是指当前用户用的是哪种Shell。

◆ LANG/LANGUGE是和语言相关的环境变量,使用多种语言的用户可以修改此环境变量。

◆ MAIL是指当前用户的邮件存放目录。

◆ PS1是基本提示符,对于root用户是#,对于普通用户是$。PS2是附属提示符,默认是“>”。可以通过修改此环境变量来修改当前的命令符,比如下列命令会将提示符修改成字符串“Hello,My NewPrompt :) ”。
# PS1=" Hello,My NewPrompt :) "
Hello,My NewPrompt :)

除了这些常见的环境变量,许多应用程序在安装时也会增加一些环境变量,比如使用Java就要设置JAVA_HOME和CLASSPATH等,而安装五笔输入法会增加环境变量"XMODIFIERS=@im=fcitx"等。

定制环境变量

环境变量是和Shell紧密相关的,用户登录系统后就启动了一个Shell。对于Linux来说一般是bash,但也可以重新设定或切换到其它的 Shell。环境变量是通过Shell命令来设置的,设置好的环境变量又可以被所有当前用户所运行的程序所使用。对于bash这个Shell程序来说,可以通过变量名来访问相应的环境变量,通过export来设置环境变量。下面通过几个实例来说明。

1. 显示环境变量HOME
$ echo $HOME
/home/terry

2. 设置一个新的环境变量WELCOME
$ export WELCOME="Hello!"
$ echo $WELCOME
Hello!

3. 使用env命令显示所有的环境变量
$ env
HOSTNAME=terry.mykms.org
PVM_RSH=/usr/bin/rsh
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000

4. 使用set命令显示所有本地定义的Shell变量
$ set
BASH=/bin/bash
BASH_VERSINFO=([0]="2"[1]="05b"[2]="0"[3]="1"[4]="release"[5]="i386-redhat-linux-gnu")
BASH_VERSION=2.05b.0(1)-release
COLORS=/etc/DIR_COLORS.xterm
COLUMNS=80
DIRSTACK=()
DISPLAY=:0.0

5. 使用unset命令来清除环境变量

set可以设置某个环境变量的值。清除环境变量的值用unset命令。如果未指定值,则该变量值将被设为NULL。示例如下:
$ export TEST="Test…" #增加一个环境变量TEST
$ env|grep TEST #此命令有输入,证明环境变量TEST已经存在了
TEST=Test…
$ unset $TEST #删除环境变量TEST
$ env|grep TEST #此命令没有输出,证明环境变量TEST已经存在了

6. 使用readonly命令设置只读变量

如果使用了readonly命令的话,变量就不可以被修改或清除了。示例如下:
$ export TEST="Test…" #增加一个环境变量TEST
$ readonly TEST #将环境变量TEST设为只读
$ unset TEST #会发现此变量不能被删除
-bash: unset: TEST: cannot unset: readonly variable
$ TEST="New" #会发现此也变量不能被修改
-bash: TEST: readonly variable

7. 用C程序来访问和设置环境变量

对于C程序的用户来说,可以使用下列三个函数来设置或访问一个环境变量。

◆ getenv()访问一个环境变量。输入参数是需要访问的变量名字,返回值是一个字符串。如果所访问的环境变量不存在,则会返回NULL。

◆ setenv()在程序里面设置某个环境变量的函数。

◆ unsetenv()清除某个特定的环境变量的函数。

另外,还有一个指针变量environ,它指向的是包含所有的环境变量的一个列表。下面的程序可以打印出当前运行环境里面的所有环境变量:
#include <stdio.h>
extern char**environ;
int main ()
{
char**var;
for (var =environ;*var !=NULL;++var)
printf ("%s n ",*var);
return 0;
}

还可以通过修改一些相关的环境定义文件来修改环境变量,比如对于Red Hat等Linux发行版本,与环境相关的文件有/etc/profile和~/.bashrc等。修改完毕后重新登录一次就生效了。

Read: 650

[转]TCP/IP 网络基础(v 0.2b)

作者:北南南北
来自:LinuxSir.Org
赞助: pandonny、etony、Linuxfish ……..
简介:本文简要的讲了讲TCP/IP的一点基础,包括TCP/IP网络模型;网络分类及切割,以及服务和端口等基础知识;需要声明的是,我并不懂TCP/IP的原理,我只是写一点比较表面的东西。

此文正在修正中,希望高手指点和补充。谢谢~


目录



++++++++++++++++++++++++++++++++++++++++++++++++++++
正文
++++++++++++++++++++++++++++++++++++++++++++++++++++


1、TCP/IP 概述;

TCP/IP 实际上并不是一个协议,而是一组协议,它包括IP、TCP、UDP、ICMP、ARP等;


1.1 什么是IP、ARP、ICMP、UDP;

IP (Internet Protocol),网际协议;IP是TCP/IP 的最底层,高层协议都要转化为IP包,IP包含了源地址和目的地址,路由决策也发生在IP层;

ARP (Address Resolution Protocol) ,地址解析协方,把IP地址转换为硬件物理地址,比如我们所用的网卡的物理地址,类似aa:bb:cc:dd:ee:ff。

ARP Short for Address Resolution Protocol, a network layer protocol used to convert an IP address into a physical address (called a DLC address), such as an Ethernet address. A host wishing to obtain a physical address broadcasts an ARP request onto the TCP/IP network. The host on the network that has the IP address in the request then replies with its physical hardware address.

There is also Reverse ARP (RARP) which can be used by a host to discover its IP address. In this case, the host broadcasts its physical address and a RARP server replies with the host’s IP address.

ICMP (Internet Control Message Protocol),网际报文协议;它包括了数据包的错误、控制等相关信息。比如ping 命令就是利用ICMP来测试一个网络的连接情况的工具;

Short for Internet Control Message Protocol, an extension to the Internet Protocol (IP) defined by RFC 792. ICMP supports packets containing error, control, and informational messages. The PING command, for example, uses ICMP to test an Internet connection

TCP (Transmission Control Protocol),传输控制协议。TCP运行在IP之上,是基于数据流连接和面向的协议,应用程序把数据要经过TCP/IP的分割成若干包,这样数据就以字节流发送和接收,到达目的地后,TCP/IP 再按顺序进行组装。TCP/IP 要保证机器与机器之间的连接的可靠性,还要有纠错。TCP是否被选择,取决于应用程序或服务;

TCP is one of the main protocols in TCP/IP networks. Whereas the IP protocol deals only with packets, TCP enables two hosts to establish a connection and exchange streams of data. TCP guarantees delivery of data and also guarantees that packets will be delivered in the same order in which they were sent.

UDP (User Datagram Protocol) ,用户数据报协议 ,象TCP一样运行在IP之上,是基于数据报或分组的协议,UDP/IP 可以直接发送和接收数据报文,而不必做验证,这一点与TCP/IP 不同。TCP是否被选择,取决于应用程序或服务;

Abbreviated UDP, a connectionless protocol that, like TCP, runs on top of IP networks. Unlike TCP/IP, UDP/IP provides very few error recovery services, offering instead a direct way to send and receive datagrams over an IP network. It’s used primarily for broadcasting messages over a network.


1.2 TCP/IP 网络模型;

TCP/IP 的网络模型是如图所示;


2、IP地址、网络类型、网络切割;

TCP/IP 网络的每台计算机都至少有一个(一个计算机有多个网卡是存在的)合法的IP地址,IP地址把此计算机和网络的其它计算机区别开来。由于IP地址分为两部份,一部份代表网络,另一部份代表主机。如果想把一个网络和另一个网络区分开来,就涉及到网络切割。


2.1 IP 地址概说;

IP地址是标识主机在网络中的位置,象是一个门牌号一样。所有IP都经过 Internet Assigned Numbers Authority (IANA)分配。IP地址是由四个字节组成,格式 为A:B:C:D,比如 192.168.1.1 。LinuxSir.Org 的IP是多少?ping LinuxSir.Org 就知道了。

IP都经过 Internet Assigned Numbers Authority (IANA)分配。一般的情况下,IANA只和各国政府机构、学会、ISP、或IDC公司交涉。咱们用的IP地址,都是IDC或ISP提供的。比如 LinuxSir.Org 的地址是由网通提供的。我用的ADSL,是铁通提供的。

IP 地址是由四个字节组成,格式 A.B.C.D,每个字节又是由8位二进制数字组成,也就是这样的格式 xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx 。在A:B:C:D中,前1到3位,可以用来识别网络,其余部份就用来表示网络上的主机。

         A       .          B       .        C        .       D   
xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx

地址中哪几位用来识别网络,哪几位用来识别主机,是通过网络掩码来实现的。网络掩码也是一个四字节的数,如果换算成二进制的数字,对应网络部份为1,而主机部份为0。

比如掩码为 255.255.255.0 ,换算成二进制就是 11111111.11111111.11111111.11111111.00000000 。

      A .        B .  C  . D
255 . 255 . 255 . 0
11111111.11111111.11111111.00000000
|-----网络部份----|主机部份|

这表示的意思是网络中的所有主机的IP地址的前三位必须是相同的,也就是A.B.C是相同的,最后一位是主机位,主机位的不同,就把网络中的计算机区分开来。比如 192.168.1.1 和192.168.1.2 是不同的主机。

在 255.255.255.0 这个网络中,从理论上来说,应该有256台主机,但事实上却不是这样。

网络地址和广播地址:

每个网络都有一个网络地址和广播地址,网络地址是把此网区别于彼网的标识,主机部份为0,(二进制),而广播地址的主机部份全为1。

比如192.168.1.0/24的网络。按理论来说,IP地址应该从192.168.1.0到192.168.1.255 ,网络最多有主机数应该有256台,但因为网络地址占用了192.168.1.0,广播地址占用了 192.168.1.255 ,所以在192.168.1.0/24的网络中,最多只能容纳254台机器。

Address:   192.168.1.0           11000000.10101000.00000001 .00000000
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111 .00000000
Wildcard: 0.0.0.255 00000000.00000000.00000000 .11111111
=>
Network: 192.168.1.0/24 11000000.10101000.00000001 .00000000 (Class C)
Broadcast: 192.168.1.255 11000000.10101000.00000001 .11111111
HostMin: 192.168.1.1 11000000.10101000.00000001 .00000001
HostMax: 192.168.1.254 11000000.10101000.00000001 .11111110
Hosts/Net: 254 (Private Internet RFC 1918)


2.2 网络分类;

IANA把网络进行分类,分类如下:


2.21 A类网络:

A类网络部份为8位(二进制),主机部份为24位(二进制)。

         A       .           B     .             C    .     D
xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
|>网络部份<|---->主机部份<--------------|

地址的第一个字节,范围从1到127 ;比如 IP地址 126.1.12.0 就归属于A类网络的地址。


2.22 B类网络:

B类网络部份为16位(二进制),主机部份为16位(二进制)。

         A       .         B        .        C        .   D    
xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
|---->网络部份<-----|-----主机部份<-----|

地址的第一个字节,范围是128-191 ;比如 IP地址 129.13.1.0 就归属于B类网络。


2.23 C类网络:

C类网络部份为24位(二进制),主机部份为8位(二进制)。

         A       .         B        .        C        .   D    
xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
|----------网络部份---------| -主机部份 -|

地址的第一个字节,范围是192-223;比如 IP地址193.1.21.0 就归属于C类网络。


为了简单一点,我们用表格列出:

IP地址的第一个字节       归属网络

1-127 A类
128-191 B类
192-223 C类


2.24 保留地址;

为了保证一些网络能有永远不能接上Internet 上(或通过NAT才能接到Internet),这些地址用于私有网络,比如我们所用的本地网地址 192.168.1.0/24网络就是。下面的一些网络地址是私有的,只能通过NAT转换为公网地址才能访问Internet 。

地址范围              网络类

10.0.0.0-10.255.255.255 A类
172.16.0.0-172.31.255.255 B类
192.168.0.0-192.168.255.255 C类
127.0.0.1-127.255.255.255 回环地址

其中回地址表示数据包的发送和接收都在同一台主机,如果想让一个程序只能在本机上运行,就用这个地址。回环地址一般是用127.0.0.1 。在Linux中,用ifconfig lo就能看到了。


2.3 网络切割;

大型网络可以划分为几个小的网络,这些小的网络被称为子网。划分大型网络地址块为一些小的子网,可以从主机部份进行切分,这样就能形成一个一个的子网。子网掩码可以用来构建超网,例如:192.168.1.2 掩码: 255.255.254.0,也可写成192.168.0.0/23,23代表子网掩码中连续“1”的个数。还可以进行子网划分,例如: 192.168.1.130 掩码: 255.255.255.240,也可写成192.168.1.130/28网络,即:网络ID为192.168.1.128,主机ID为2。

切割网络还要知道十进制到二进制的相互换算,这是比较麻烦的。用笔来算是有点难为人。不过我们可以用一个脚本工具来算。

网络切割脚本下载 ,请点击: 网络切割计算器

下载后要解压;

#tar zxvf ipcalclinuxsir.pl.tar.gz
# chmod 755 ipcalc.pl
# ./ipcalc.pl

可以指定单个IP和掩码来判断网络,比如:

[root@localhost ~]# ./ipcalc.pl 192.168.1.4/255.255.255.0

Address: 192.168.1.4 11000000.10101000.00000001 .00000100
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111 .00000000
Wildcard: 0.0.0.255 00000000.00000000.00000000 .11111111
=>
Network: 192.168.1.0/24 11000000.10101000.00000001 .00000000 (Class C)
Broadcast: 192.168.1.255 11000000.10101000.00000001 .11111111
HostMin: 192.168.1.1 11000000.10101000.00000001 .00000001
HostMax: 192.168.1.254 11000000.10101000.00000001 .11111110
Hosts/Net: 254 (Private Internet RFC 1918)

值得注意的是:同一个IP地址,由于掩码不同,此IP地址可能属于不同的网络。所以掩码的设置对于主机来说十分重要。

IP地址:192.168.1.2 掩码: 255.255.254.0,属于192.168.0.0/23网络;

Address:   192.168.1.2           11000000.10101000.0000000 1.00000010
Netmask: 255.255.254.0 = 23 11111111.11111111.1111111 0.00000000
Wildcard: 0.0.1.255 00000000.00000000.0000000 1.11111111
=>
Network: 192.168.0.0/23 11000000.10101000.0000000 0.00000000 (Class C)
Broadcast: 192.168.1.255 11000000.10101000.0000000 1.11111111
HostMin: 192.168.0.1 11000000.10101000.0000000 0.00000001
HostMax: 192.168.1.254 11000000.10101000.0000000 1.11111110
Hosts/Net: 510 (Private Internet RFC 1918)

IP地址:192.168.1.2 掩码: 255.255.255.0,属于192.168.1.0/24网络;

Address:   192.168.1.2           11000000.10101000.00000001 .00000010
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111 .00000000
Wildcard: 0.0.0.255 00000000.00000000.00000000 .11111111
=>
Network: 192.168.1.0/24 11000000.10101000.00000001 .00000000 (Class C)
Broadcast: 192.168.1.255 11000000.10101000.00000001 .11111111
HostMin: 192.168.1.1 11000000.10101000.00000001 .00000001
HostMax: 192.168.1.254 11000000.10101000.00000001 .11111110
Hosts/Net: 254 (Private Internet RFC 1918)


3、 路由和网关;

3.1 路由,此网和彼网沟通的纽带;

在同一个网段之间(网络ID相同),主机可以互相通讯,比如同一网段的主机相互沟通不需要路由,比如 192.168.1.2和192.168.1.3之间的沟通就不需要路由。如果两个不同的网络(网络ID不同)需要通讯,比如 192.168.1.0/24网络的主机和192.168.2.0/24内的主机相互沟通,那么需要路由器(或者网关)来指明数据包的“传输路径”来实现这一目的。

常用的做法是用一台多穴主机来作网关(多个网络接口,分别连着外网与内网),使得内网计算机通过网关访问Internet。在linux里面一般用 iptables做NAT(网络地址转换)来实现网关功能,如果充当网关的机器有一个固定IP,我们可以使用SNAT(源网络地址转换);如果充当网关的机器是拨号上网,也就是IP不固定,那么一般我们用MASQUERADE,它可以动态的识别网关的地址。当然,固定ip也是可以用MASQUERADE 的,但是系统资源要耗费大一些。

比如LinuxSir.Org 服务器托管在IDC机房中,机房要为我们提供IP地址、掩码、网关。

在Linux 中,查看本地机的路由是通过route命令来实现的,比如:

[root@localhost ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 * 255.255.255.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0

此主机的默认路由就是192.168.1.1 ,至于更多的配置路由的细节,我们将在以后的章节加以讨论。

网关;


4 、服务和端口;

在一台计算机运行的操作系统,如果这台计算机是连接在网络中的,它一定得有一个IP地址。在网络上使用 ip 来标示一个点,也可以理解为标示一台主机。如果您的计算机分配了两个ip 比如你启用了两块网卡,在网络上就认为这是不同的两个主机。在这台计算机上可能运行着很多的服务。

端口则是用来标示特定主机的特定服务,比如linuxsir的 www 服务要用 ip:80 来标示。

比如 LinuxSir.Org 的服务器上有FTP、SSH、WWW、IRC等服务,这些服务都用的是一个IP地址。为了能把这些服务运行起来,我们指定了WWW服务器用的是80端口。FTP服务器用的是 21端口等。这块好象不难理解。

查看Linux服务和端口的字典文件位于 /etc/services ,它 是一个字典文件, 并不用来分配端口。其内容有如下类似的:

ftp 20/tcp 注:传输命令
ftp 21/tcp 注:传输数据
ssh 22/tcp
telnet 23/tcp

有些服务一般是采用默认端口,比如 ftp服务器默认端口是21,ssh服务器端认端口是22,telnet默认端口是23 。当然您可以改变服务的默认端口,以增强系统的安全性;我们在以后的教程中,会涉及到此方面的内容。


5、套接字接口;

套接字接口是进程之间相互通信的网络连接接口。


6、关于本文;

这一节主要讲的是TCP/IP的基础知识,我写这些内容实在是眼高手低。在写的过程中向Pandonny、etoy 、Linuxfish等弟兄请教,才勉强把初稿写出来。至于是不是对的,我不敢说,还是请高手指点吧。有的地方的确需要补充,但又不知道如何下手。

本来五十米的竞赛中,我最快能跑到6.7秒,但现在要求自己跑到6秒,实在是超出我的能力。所以这也是最痛苦的一篇文档。再一次请教求高手指教。

如果说哪有现成的文档,就近抄来,我看没有必要了。现成的文档是多,但做为这个系列文档,我还是希望能出在LinuxSir.Org 上,用最简单的话把比较深奥的理念条理化、清晰化。对于一般用户来说,只要了解一点基础就够了,没有必要知道TCP/IP的所有东西。

还是那句话,学为所用,用为所学。洋为中用,旧文今用,但得更造一下。

谢谢;


7、致谢;

本文得到了pandonny、etoy、Linuxfish 等三位弟兄的帮助,在此致谢;

Read: 667