2009年2月18日星期三

gst看一下2

set_state能发送给管道中所有元件的change_state函数
每个元件的change_state函数中都会调用parent_class的change_state,
playbin--(parent)-->playbasebin
playbasebin--(parent)-->pipeline
pipeline--(parent)-->bin
最上一级是bin,看bin的change_state函数,

while (!done) {
gpointer data;

switch (gst_iterator_next (it, &data)) {
case GST_ITERATOR_OK:
{
GstElement *child;

child = GST_ELEMENT_CAST (data);

/* set state and base_time now */
ret = gst_bin_element_set_state (bin, child, base_time, current, next);
把bin里的元件一个个取出来发送set_state命令,这样所有元件都会改变状态了

gstclock获得时钟的3种方式
1 systemclock系统时钟
2 音频设备 基于采样率而知道的时钟
3 网络包中包含的时钟信息

我只看过systemclock, gstclock->gstsystemtclock->g_get_current_time->gettimeofday->(system call)

音视频时间同步到系统时间
并不是音频和视频谁同步谁,而是大家都跟系统时间同步
NS...B...B...EOS NS=new segment
C.running_time = absolute_time - base_time (系统)
B.running_time = (B.timestamp - NS.start)/NS.abs_rate + NS.accum (元件)
同步就是让B,C的running_time相等, B等待
base_time从NEW_SEGMENT事件发出为基准,比如seek后就是NEW SEGMENT

_class_init给klass挂函数指针

gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gstbasesink_class = (GstBaseSinkClass *) klass;
把一个klass转换为3种数据结构,可以的原因是一级级都是数据结构的第一个成员,传进来的kclass是最大的数据结构,往小转当然可以

struct _GstBaseAudioSink {
GstBaseSink element;

struct _GstBaseSink {
GstElement element;

struct _GstElement
{
GstObject object;

状态变迁
NULL-->READY
1 probe device
2 open device

READY-->PAUSED
1 激活pad,返回ASYNC,然后起stream thread线程才把状态改变的事情做完,直到sink pad收到first buffer,阻塞住,这时才真正算状态改变完,用get_state可以查询到
2 管道running_time归零
3 如果是live source返回NO_PREROLL,不产生数据(live source是即使暂停也会产生数据的源,比如net和camera)

PAUSED-->PLAYING (大部分元件忽略这个状态)
1 管道选择时钟分发到每个子元件,也就是同步时钟只发生在PLAYING时
2 管道把clock running_time计算出来的base_time分发到每个子元件(change_state时)
3 sink衬垫不再阻塞buffer/event,开始render数据
4 live source开始产生数据

PLAYING-->PAUSED (大部分元件忽略这个状态)
1 如果sink此时无buffer在手一定要等收到buffer才能完成状态改变。看上面的READY->PAUSED也是sink在进入PAUSED前一定要有buffer,为了PLAYING时不至于让用户等待前面的一小撮时间
2 EOS事件无效,但到PLAYING时会repost
3 sink把preroll上的所有等待都解除阻塞
4 live source停止产生数据

PAUSED-->READY
1 sink解除阻塞preroll,元件解除阻塞设备
2 chain和get_range 返回WRONG_STATE,(buffer相关的函数)
3 pad使无效(deactivate),stream thread停止
4 sink忘记所有的协商格式(negotiation caps)

READY-->NULL
1 close device
2 删除所有动态建立的pads

2009年2月16日星期一

gst看一下1

1. 目录结构
gstreamer-0.10.21 目录
gst 核心文件,实现gst元件工厂等功能
plugins gstreamer-0.10.21提供的元件
lib 不可被应用调用的元件,但他是某些元件的parent class
pkgconfig install tools 都是make install需要拷贝的东西
po 各种语言的翻译文件
tests 测试gstreamer-0.10.21的元件

gst-plugins-base-0.10.21 目录
gst base提供的元件
gst-libs base提供的元件的parent class,应用不可用的元件
ext 需要额外源码库的元件
sys 系统相关的元件(x11,v4l)这2个window就没有

2.细数元件
看gst有哪些元件就看哪些文件调用了gst_element_register
grep -nr 'gst_element_register' --include=*.c ./

gstreamer的元件统一注册,别的元件基本都是单独注册
static struct _elements_entry _elements[] = {
{"capsfilter", GST_RANK_NONE, gst_capsfilter_get_type},
{"fakesrc", GST_RANK_NONE, gst_fake_src_get_type},
{"fakesink", GST_RANK_NONE, gst_fake_sink_get_type},
#ifdef HAVE_SYS_SOCKET_H
{"fdsrc", GST_RANK_NONE, gst_fd_src_get_type},
{"fdsink", GST_RANK_NONE, gst_fd_sink_get_type},
#endif
{"filesrc", GST_RANK_PRIMARY, gst_file_src_get_type},
{"identity", GST_RANK_NONE, gst_identity_get_type},
{"queue", GST_RANK_NONE, gst_queue_get_type},
{"filesink", GST_RANK_PRIMARY, gst_file_sink_get_type},
{"tee", GST_RANK_NONE, gst_tee_get_type},
{"typefind", GST_RANK_NONE, gst_type_find_element_get_type},
{"multiqueue", GST_RANK_NONE, gst_multi_queue_get_type},
{NULL, 0},
};

3.playbin(只说playbin播放视频的情况)
playbin元件算是整合的元件,内部建立工厂管道,用到很多元件。

3.1元件流程图
filesrc --> (typefind) -->decodebin -->|--> abin (audioconvert-->audioresample-->volume-->osssink)
··························································|--> vbin (identity-->ffmpegcolorspace-->videoscale-->fbdevsink)

3.2代码分析
应用程序建立playbin元件后就调用get_element_set_state将playbin设置为NULL,READY,PAUSED,PLAYING, 在READY-->PAUSED时候(GST_STATE_CHANGE_READY_TO_PAUSED),playbin就把管道建立起来了

gst_play_base_bin_change_state
|----setup_source
|----|----gen_source_element 建立source元件,也就是filesrc
|----|----|----if (play_base_bin->suburi) setup_subtitle 如果playbin的suburi属性被设置了就配置字幕元件
|----|----|----gst_element_make_from_uri
|----|----|----|----get_element_factories_from_uri_protocol根据字符串头uri协议search_by_entry确定工厂类型,比如file://则建立filesrc
|----|----|----gst_element_factory_create根据确定的工厂类型建立元件(filesrc)

|----|----analyse_source分析源是否是raw数据/有动态pad/有输出pad再做相应处理
|----|----|----几种情况都会走到group_commit
|----|----|----|----GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin)->
setup_output_pads 也就是gstplaybin.c的setup_sinks

|----|----|----|----|----有音频需要可视化调用gen_vis_element
|----|----|----|----|----有音频不需要可视化调用gen_audio_element
|----|----|----|----|----有视频调用gen_video_element

|----|----make_decoder
|----|----|----gst_element_factory_make("decodebin", NULL)建立decodebin元件
|----|----gst_element_link (play_base_bin->source, decoder)把filesrc和decodebin链接起来

3.3 playbin目录
目录是gst-plugins-base-0.10.21/gst/playback/
原本看着文件挺多,不过是2套playbin,其中一套是非稳定版本playbin2,所以其实真正要看的文件不多 。
gstplayback.c注册playbin和playbin2
playbin用到的C文件有(主要是playbin, playbasebin, decodebin)
gstplaybin.c
gstplaybasebin.c
gstdecodebin.c
gststreaminfo.c
gststreamselector.c
gstplaymarshal.c

playbin2用到的C文件有(与playbin,playbasebin, decodebin等价的是playbin2,playsink, decodebin2)
gstplaybin2.c
gstplaysink.c
gstdecodebin2.c
及剩下的一些文件,gsturidecodebin.c和gstdecodebin2.c也是非稳定版本

3.4 playbin元件用到的parent class

filesrc的parent_class是basesrc,从下面可以看出来,
GST_BOILERPLATE_FULL (GstFileSrc, gst_file_src, GstBaseSrc, GST_TYPE_BASE_SRC,
_do_init);

当用户调用set_state时对应内部change_state, 会调用该元件的parent class的change_state。basesrc就像是filesrc的基类

osssink的parent_class是audiosink,从下面可以看出来,
osssink_type = g_type_register_static (GST_TYPE_AUDIO_SINK, "GstOssSink", &osssink_info, 0);

osssink只是做跟底层相关的工作,音频的逻辑层还是在audiosink和它的parent audiobasesink里面,他们再调用osssink的函数指针做具体读写声卡的操作

3.5 元件的parent class
因为change_state会分发到管道中的每个元件,元件的change_state里都会调用它parent_class的change_state,所以不免想看看playbin的parent_class
struct _GstPlayBin {
GstPlayBaseBin parent;

struct _GstPlayBaseBin {
GstPipeline pipeline;

playbin-->playbasebin-->pipeline已经到管道了

2009年1月16日星期五

在板子上使用交换分区

1. 内核勾上swap选项,
General setup --->[*] Support for paging of anonymous memory (swap) (y)
2.编译busybox时要有swapon命令
3.做交换分区文件8M
dd if=/dev/zero of=swapfile bs=1M count=8 //建立一个8M空文件
mkswap swapfile //格式化
sync //确保写进去了
4.把文件拷到板子上,添加到swap(如果文件在nfs上,执行swapon会出错)
swapon swapfile

添加以后可以在/proc/meminfo看到swap信息,

2009年1月7日星期三

(转){nfs:server is not responding,still trying} 解决办法

原文地址:http://hi.baidu.com/rjz78/blog/item/a3e6e7ee6276512e2cf53447.html

描述:我在arm上通过NFS共享文件时出现下面的错误提示
nfs:server is not responding,still trying

原因分析:NFS 的默认传输协议是 UDP,而PC机与嵌入式系统通过UPD交互时就会出现严重的网卡丢包现象。

解决方法:在客户端改用TCP协议,使用下面的命令,

#mount -t nfs -o nolock -o tcp 192.168.1.161:/opt /opt

(转)Fedora 启动过程

原文地址:http://blog.chinaunix.net/u/22418/showart_1356101.html

在 Intel i386 体系结构下,不同发行版本的 Linux 的启动过程有很多相似之处。

  • bios 读取位于第一个扇区(硬盘或光盘的主引导记录,简称 MBR)的 Linux 内核加载器。
  • 内核加载器加载内核。新的发行版本使用的大多是 2.6 系列的内核,不过 2.4 系列的内核仍然得到广泛的应用。
  • 运行 Init 进程并执行多个脚本。

如果从硬盘启动 Linux,内核加载器(Intel 兼容体系结构)主要使用的是 Lilo 或 Grub。如果从光盘引导 Linux,比如:Live CD 或安装盘,则常选择 Syslinux 作为内核加载器。

在配置文件 /etc/lilo.conf/boot/grub/grub.conf 中你可以设置:

  • 内核加载器安装在哪里(主引导记录还是单个分区的引导记录)。
  • 指定系统根文件系统(/)所在的分区。
  • 内核 image 和 initrd 的路径。

你可以配置启动不同的操作系统(Linux 或是其它的操作系统)和不同版本的内核。

每一个发行版本的 Linux 内核都源自 Linus Torvalds 内核,但是可能会具有不同的版本机制,或由版本的维护者加入的非 Linus 补丁。

你可以重新并编译安装官方的内核代码或不同发行版本的内核源码包。

Unix 系统启动的第一个进程总是 Init 进程,它的配置文件总是 /etc/inittab。分析 /etc/inittab 和所有被它 source 的脚本,你就可以完全地了解系统的启动过程。

Linux/Unix 的主要区别大多是 shell(初始化)脚本的不同。

很多的 Linux 发行版使用 Unix System V 的启动方法。基于 rc 脚本,根据不同的运行级别启动 /etc/init.d/ 下相应的脚本。

RedHat

/etc/rc.d/rc.sysinit

由 init 进程调用,它设置和执行所有的系统初始化函数,并 source /etc/sysconfig/* 目录下的配置文件。

/etc/rc.d/functions

被其它系统脚本使用的通用函数。

/etc/rc.d/*

所有系统服务的启动和关闭脚本。系统启动时根据用户指定的运行级别执行 /etc/rc#runlevel.d/(“#runlevel”为运行级别,一般为 1,3,5)目录下的脚本文件。
注意:/etc/rc#runlevel.d/ 目录下的脚本只是到 /etc/rc.d/ 目录下的脚本的一个链接。


Fedora - 启动过程


Fedora 采用 RedHat 的方式来启动系统。

Boot Loader

Fedora 使用 Grub 作为启动加载器,所有的配置文件和二进制文件都在 /boot/grub/ 目录下,grub.conf 包含所有的配置信息(/boot/grub/menu.lst 和 /etc/grub.conf 都是指向它的链接),/boot/grub/splash.xpm.gz 是 grub 启动时的默认背景图片。

Kernel

主要的二进制文件为 /boot/vmlinuz-version,系统符号(System Map)文件为 /boot/System.map-version,启动时初始化内存的文件为 /boot/initrd-version。当前内核的完整配置文件为 /boot/config-version。

内核模块位于 /lib/modules/version 目录下。

Init

/etc/inittab 有一个规定,mingetty 优先于运行级别 1 启动(所以单用户模式下不需要密码就可以直接使用 root shell)。不论什么运行级别,系统执行的第一个初始化脚本都是 /etc/rc.d/rc.sysinit,然后执行 /etc/rc#runlevel.d 目录下的脚本启动各种系统服务。

系统配置文件大多放在 /etc/sysconfig/ 下,在启动阶段被加载(sourced)。

/etc/rc.d/rc.sysinit 负责各种各样的启动工作,顺序如下

  • 根据 /etc/initlog.conf 和 /etc/syslog.conf 的设置,使用 initlog 来记录运行情况。
  • 如果使用 DEVFS,就启动 devfsd 服务。
  • 设置 hostname,hosttype 并加载(source) /etc/sysconfig/network
  • 挂载 procfs 和 sysfs 到 /proc 和 /sys 目录下
  • 检查 SeLinux 状态
  • 加 载(source) /etc/init.d/functions,该脚本包含被其它脚本用到的通用 shell 函数,包括:daemon(),killproc(),pidofproc(),status(),echo_success()(绿色的 OK),confirm()等等,并加载(source)其它重要的系统配置文件:/etc/sysconfig/i18n, /etc/sysconfig/init 等。
  • 设置系统默认字体。
  • 打印熟悉的 “Welcome to ...” 标志
  • 运行图形化的启动程序 rhgb,更改 /usr/share/rhgb 目录下的图片可以定制启动界面。
  • 根据 /etc/sysctl.conf 的设置来配置内核
  • 根据 /etc/sysconfig/clock 文件的参数来设置系统时钟
  • 根据 /etc/sysconfig/keyboard 的设置来配置键盘布局,改变 /etc/sysconfig/keyboard 文件的设置来定制文本模式下的键盘设定。
  • 初始化 ACPI 设定
  • 初始化 USB 控制器和 HID 设备
  • 查看 /fastboot,/fsckoptions,/forcefsck 和 /.autofsck 文件并加载(source) /etc/sysconfig/autofsck 来决定是否及如何进行文件系统检查。
  • 检查磁盘配额
  • 根据 /etc/isapnp.conf 初始化 ISA PNP 设备。
  • 以读写方式挂载根文件系统
  • 如果启用则启动逻辑卷管理(LVM)
  • 激活交换空间(swap)
  • 使用 /etc/modules.conf 中指定的参数来加载内核模块
  • 启动 raid(MD)设备
  • 如果存在 /.unconfigured 标志文件,则运行系统第一次启动必须的配置。
  • 删除 /,/var/lock,/var/run 目录下的标志文件,删除 rpm 数据库文件(/var/lib/rpm/__db*)和 /tmp 目录下的各种文件。
  • 初始化串口,SCSI 磁带,USB 存储器,Firewire
  • hdparm 程序根据 /etc/sysconfig/harddisks* 文件的配置开启硬盘优化。
  • 如果存在网络配置文件,则激活默认网络配置。

完成上述步骤后,系统进入默认的运行级别并激活 /etc/rc#runlevel.d/ 目录下的服务。

最后,系统将执行 /etc/rc.local 脚本。在这里,用户可以方便地添加希望在系统启动时运行的命令。

2008年12月25日星期四

gst-ffmpeg

/home/gstreamer/gst-ffmpeg-0.10.6
./configure --host=arm-linux --prefix=/home/gstreamer/install --enable-shared CFLAGS=-I/home/gstreamer/install/include/ LDFLAGS="-L/home/gstreamer/install/lib -lbz2 -lamrwb -lamrnb" --with-ffmpeg-extra-configure="--prefix=/home/gstreamer/install --enable-cross-compile --enable-gpl --disable-network --disable-ipv6 --disable-vhook --disable-mpegaudio-hp --enable-pthreads --disable-parsers --arch=armv4l --disable-muxers --disable-encoders --disable-stripping --host-cc=arm-linux-gcc --disable-armv6 --disable-armv5te --disable-armvfp --disable-ffmpeg --enable-static --enable-shared --cross-prefix=/usr/local/arm/3.4.1/bin/arm-linux- ARCH_ARMV4L=y --enable-libamr-nb --enable-libamr-wb --enable-libxvid --enable-nonfree"

/home/gstreamer/amrnb-7.0.0.2
echo ac_cv_func_malloc_0_nonnull=yes >> arm.cache
echo ac_cv_file__bin_bash=yes >> arm.cache
./configure --host=arm-linux --prefix=/home/gstreamer/amrnb-7.0.0.2/../install --cache-file=arm.cache

/home/gstreamer/amrwb-7.0.0.3
echo ac_cv_func_malloc_0_nonnull=yes >> arm.cache
echo ac_cv_file__bin_bash=yes >> arm.cache
./configure --host=arm-linux --prefix=/home/gstreamer/amrwb-7.0.0.3/../install --cache-file=arm.cache

/home/gstreamer/xvidcore/build/generic
./configure --host=arm-linux --prefix=/home/gstreamer/install

How to install FFmpeg with MP3 and AMR support

http://www.mattiouz.com/blog/2007/07/02/how-to-install-ffmpeg-with-mp3-and-amr-support/

2008年12月20日星期六

编译gstreamer相关

把编译完的配置从config.log里拷出来,去掉双引号了,记得加上

gstreamer统一目录是/home/gstreamer,编译后统一安装在/home/gstreamer/install文件夹里,所以设置pkgconfig就只用设置一个地址
export PKG_CONFIG_LIBDIR=/home/gstreamer/install/lib/pkgconfig

然后开始编译
/home/gstreamer/gstreamer-0.10.21/

$ ./configure --disable-nls --disable-static --enable-binary-registry --disable-loadsave --with-html-dir=/tmp/dump --prefix=/home/gstreamer/gstreamer-0.10.21/../install --host=arm-linux LDFLAGS=-L/home/gstreamer/install/lib/ -L/home/gstreamer/install/lib/ -lglib-2.0 -lgio-2.0 -lgobject-2.0 -lgthread-2.0 -lgmodule-2.0 -lxml2 CFLAGS=-I/home/gstreamer/install/include/ -I/home/gstreamer/install/include/glib-2.0/ -I/home/gstreamer/install/lib/glib-2.0/include

/home/gstreamer/gst-plugins-base-0.10.21/
$ ./configure --host=arm-linux --prefix=/home/gstreamer/gst-plugins-base-0.10.21/../install --disable-static --with-html-dir=/tmp/dump CFLAGS=-I/home/gstreamer/install/lib/glib-2.0/include -I/home/gstreamer/install/include/glib-2.0 -I/home/gstreamer/install/include/liboil-0.3/liboil -I/home/gstreamer/install/include/gstreamer-0.10/gst -I/home/gstreamer/install/include/gio-unix-2.0/gio -I/home/gstreamer/install/include/libxml2/libxml LDFLAGS=-L/home/gstreamer/install/lib/ -L/home/gstreamer/install/lib/gstreamer-0.10 -L/home/gstreamer/install/lib/python2.5/site-packages --with-pkg-config-path=/home/gstreamer/install/lib/pkgconfig --disable-x --disable-xvideo --disable-xshm --disable-gnome_vfs --disable-cdparanoia --disable-libvisual --disable-alsa --disable-ogg --disable-oggtest --disable-pango --disable-vorbis --disable-vorbistest

/home/gstreamer/gst-plugins-good-0.10.11/
$ ./configure --host=arm-linux --prefix=/home/gstreamer/gst-plugins-good-0.10.11/../install --disable-nls --disable-static --with-html-dir=/tmp/dump --with-plugins=avi,qtdemux CFLAGS=-I/home/gstreamer/install/lib/glib-2.0/include -I/home/gstreamer/install/include/glib-2.0 -I/home/gstreamer/install/include/liboil-0.3/liboil -I/home/gstreamer/install/include/gstreamer-0.10/gst -I/home/gstreamer/install/include/gio-unix-2.0/gio -I/home/gstreamer/install/include/libxml2/libxml LDFLAGS=-L/home/gstreamer/install/lib/ -L/home/gstreamer/install/lib/gstreamer-0.10 -L/home/gstreamer/install/lib/python2.5/site-packages --disable-x --disable-xshm --disable-xvideo --disable-esd --disable-shout2

/home/gstreamer/gst-plugins-ugly-0.10.10/
$ ./configure --host=arm-linux --prefix=/home/gstreamer/gst-plugins-ugly-0.10.10/../install --disable-nls --disable-static --with-html-dir=/tmp/dump --with-plugins=asfdemux CFLAGS=-I/home/gstreamer/install/lib/glib-2.0/include -I/home/gstreamer/install/include/glib-2.0 -I/home/gstreamer/install/include/liboil-0.3/liboil -I/home/gstreamer/install/include/gstreamer-0.10/gst -I/home/gstreamer/install/include/gio-unix-2.0/gio -I/home/gstreamer/install/include/libxml2/libxml LDFLAGS=-L/home/gstreamer/install/lib/ -L/home/gstreamer/install/lib/gstreamer-0.10 -L/home/gstreamer/install/lib/python2.5/site-packages

/home/gstreamer/gst-plugins-bad-0.10.9/
$ ./configure --host=arm-linux --prefix=/home/gstreamer/gst-plugins-bad-0.10.9/../install CFLAGS=-I/home/gstreamer/install/lib/glib-2.0/include -I/home/gstreamer/install/include/glib-2.0 -I/home/gstreamer/install/include/liboil-0.3/liboil -I/home/gstreamer/install/include/gstreamer-0.10/gst -I/home/gstreamer/install/include/gio-unix-2.0/gio -I/home/gstreamer/install/include/libxml2/libxml LDFLAGS=-L/home/gstreamer/install/lib/ -L/home/gstreamer/install/lib/gstreamer-0.10 -L/home/gstreamer/install/lib/python2.5/site-packages --disable-nls --disable-static --with-html-dir=/tmp/dump --disable-apexsink --disable-sdl

/home/gstreamer/glib-2.18.3
$ ./configure --cache-file=arm.cache --host=arm-linux --prefix=/home/gstreamer/glib-2.18.3/install
arm.cache的内容在前面的文章里写了。家里用X86_64编译的,把posix那2个设置为no,可以编译过了。也没有WARNING提示了。

/home/gstreamer/libxml2-2.6.24/
$ ./configure --host=arm-linux --prefix=/home/gstreamer/libxml2-2.6.24/../install/

/home/gstreamer/liboil-0.3.15/
$ ./configure --host=arm-linux --prefix=/home/gstreamer/liboil-0.3.15/../install/ --disable-static --with-html-dir=/tmp/dump CFLAGS=-I/home/gstreamer/install/lib/glib-2.0/include -I/home/gstreamer/install/include/glib-2.0 LDFLAGS=-L/home/gstreamer/install/lib/
修改的configure文件在前面文章里写了

这里的编译都是不带额外的plugins,比如没有把mad加进去

运行时设置环境变量GST_PLUGINS_PATH为包含plugin的地址
在没有设置该环境变量时,运行/home/gstreamer/gstreamer-0.10.21/tests/examples/helloworld/.libs下的helloworld程序会报错:

# ./helloworld a
**
ERROR:helloworld.c:59:main: assertion failed: (filesrc)
Aborted

本来是件简单的事情,设置环境变量就行了,但是网上没搜到解决办法,加入了gstreamer的QQ群,也没人告诉我。有个人倒是算热心回答我问题,但是他觉得这里不应该出错,他不会在这里出错。那么他们怎么把有哪些plugin告诉gstreamer的?可能办法不一样吧。结果我找到一篇"GStreamer Plugin Writer's Guide(0.10.21.1)",Chapter 9. Building a Test Application才知道要设置GST_PLUGIN_PATH

2008年12月19日星期五

在fedora9 x86_64上编译arm qt2.2.0

系统:Fedora9 x86_64

1>下载cross-3.3.2.tar.bz2,并解压到/usr/local/arm/文件夹下,设置环境变量PATH
tar zjf cross-3.3.2.tar.bz2 -C /usr/local/arm/
export PATH=$PATH:/usr/local/arm/3.3.2/bin

2>建立目录armqt,设置环境变量
mkdir /home/armqt //arm qt根目录
export ARMQT=/home/armqt
mkdir $ARMQT/tools //arm库
mkdir $ARMQT/tools/lib //arm库lib
mkdir $ARMQT/tools/include //arm库include
mkdir $ARMQT/arm220 //编译arm qt
mkdir $ARMQT/qtopia //make install的路径,生成的qt及其库的文件系统文件夹

3>下载qtopia-free-src-2.2.0.tar.gz解压到$ARMQT/arm220,省掉下一级qtopia-free-2.2.0目录

4>下载arm需要的库,并解压到$ARMQT/tools下,并编译
A e2fsprogs-1.39.tar.gz

下载地址
http://nchc.dl.sourceforge.net/sourceforge/e2fsprogs/e2fsprogs-1.39.tar.gz

安装
./configure --host=arm-linux --enable-elf-shlibs --with-cc=arm-linux-gcc --with-linker=arm-linux-ld --prefix=/usr/local/arm/2.95.3/arm-linux
make
cp lib/libuuid.so* ../lib/

B jpegsrc.v6b.tar.gz

下载地址
http://down1.chinaunix.net/distfiles/jpegsrc.v6b.tar.gz

I 缺少libtool,下载
yum install libtool
cp /usr/share/libtool/config.guess /home/armqt/tools/jpeg-6b/ -rf
cp /usr/share/libtool/config.sub /home/armqt/tools/jpeg-6b/ -rf

II ./configure --enable-shared

III 修改Makfile,搜索到CC,AR,AR2宏替换为下面(如果是export CC=arm-linux-gcc,
在Makefile中虽然cc,ld等变了,但是ar,ranlib就没有改变)
CC=arm-linux-gcc
AR=arm-linux-ar rc
AR2=arm-linux-ranlib

IV make

V 拷贝库文件和头文件到统一目录
cp *.h ../include/
cp .libs/libjpeg.so* ../lib/

VI 可以用file看一下编译出来的是否是arm版本的及是否动态链接
[root@localhost jpeg-6b]# file wrjpgcom
wrjpgcom: ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), for GNU/Linux 2.0.0, not stripped

C zlib-1.2.3.tar.bz2

下载地址
http://www.zlib.net/zlib-1.2.3.tar.gz

I ./configure -shared

II 修改Makfile,搜索到CC,LDSHARED,CPP,AR,RANLIB,prefix宏替换为下面
CC=arm-linux-gcc
CPP=arm-linux-gcc -E
LDSHARED=arm-linux-gcc -shared -Wl,-soname,libz.so.1
AR=arm-linux-ar rc
RANLIB=arm-linux-ranlib
prefix=/usr/local/arm/3.3.2/arm-linux

III make

IV 拷贝库文件和头文件到统一目录
cp libz.so* ../lib/
cp *.h ../include/

D libpng-1.2.14.tar.bz2

下载地址
http://superb-east.dl.sourceforge.net/sourceforge/libpng/libpng-1.2.14.tar.bz2

I cp scripts/makefile.linux Makefile

II 修改Makfile,搜索到CC,AR,AR2,prefix,ZLIBLIB,ZLIBINC宏替换为下面
CC=arm-linux-gcc
AR=arm-linux-ar rc
AR2=arm-linux-ranlib
prefix=/usr/local/arm/3.3.2/arm-linux
ZLIBLIB=../lib
ZLIBINC=../include

III make

IV 拷贝库文件和头文件到统一目录
cp libpng12.so* ../lib/
cp libpng12.so ../lib/libpng.so
cp *.h ../include/

E uic-qt2

下载地址
http://vanille.de/tools/uic-qt2

chmod 777 uic-qt2
cp uic-qt2 $ARMQT/arm220/qt2/bin/uic

5>编译qt前的准备
A修改文件$ARMQT/arm220/qtopia/mkspecs/qws/linux-arm-g++/qmake.conf
chmod 777 $ARMQT/arm220/qtopia/mkspecs/qws/linux-arm-g++/qmake.conf

QMAKE_LIBS_QT = -lqte
改为
QMAKE_LIBS_QT = -lqte -lpng -lz -luuid -ljpeg

B修改文件$ARMQT/arm220/qtopia/src/qt/qconfig-qpe.h
chmod 777 $ARMQT/arm220/qtopia/src/qt/qconfig-qpe.h
添加到文件最后
#define QT_QWS_IPAQ
#define QT_QWS_IPAQ_RAW

C修改文件$ARMQT/arm220/qt2/include/qvaluestack.h
chmod 777 $ARMQT/arm220/qt2/include/qvaluestack.h
remove( this->fromLast() );
改为
this->remove( this->fromLast() );

D修改文件$ARMQT/arm220/qtopia/src/libraries/qtopia/qdawg.cpp
chmod 777 $ARMQT/arm220/qtopia/src/libraries/qtopia/qdawg.cpp
QDawgPrivate::~QDawgPrivate()
改为
~QDawgPrivate()

E
cp $ARMQT/arm220/qtopia/src/qt/qconfig-qpe.h $ARMQT/arm220/qt2/src/tools
cd $ARMQT/arm220/qtopia/src/libraries/qtopia
cp custom-linux-ipaq-g++.cpp custom-linux-arm-g++.cpp
cp custom-linux-ipaq-g++.h custom-linux-arm-g++.h

F编译时出现了qvfb错误,没搜到网上别人怎么做的,反正arm也用不上,所以干脆删了
rm $ARMQT/arm220/dqt/tools/qvfb -rf

G下面都是在编译时少什么就加什么库,先用yum whatprovides确定库名字,然后用yum install更新,感觉很不安全一样,我怕影响有些什么功能不能使用了.gcc -m32也就是32位编译了,不知道为什么更新后它自动加上了-m32,是自适应还是手动?

/*****
本来安装了这3个包,但是按照前2天在32位机上使用gcc32的做法(替换gcc,g++,lib)会出错,所以只好放弃,谁能告诉我怎样在x86_64上用i386 gcc32?
compat-gcc-32-3.2.3-47.3.i386.rpm
compat-gcc-32-c%2B%2B-3.2.3-47.3.i386.rpm
compat-libstdc++-33-3.2.3-63.i386.rpm
******/

I gcc少头文件和libc
yum whatprovides */gnu/stubs-32.h
yum install glibc-devel.i386

yum whatprovides */4.3.0/libstdc++.a
yum install libstdc++-devel.i386

II 编译时缺少的其他i386库
yum whatprovides */libXext.so
yum install libXext-devel.i386

yum whatprovides */libX11*
yum install libX11-devel.i386
yum install libX11.i386

yum whatprovides */libSM*
yum install libSM.i386
cd /usr/lib64
rm libSM.so -rf
ln -s ../lib/libSM.so.6 libSM.so

yum whatprovides */libICE*
yum install libICE-devel.i386

H 配置环境变量
export QPEDIR=$ARMQT/arm220/qtopia
export QTDIR=$ARMQT/arm220/qtopia
export QTDIR=$ARMQT/arm220/qt2
export LD_LIBRARY_PATH=$QTDIR/lib:$QPEDIR/lib:$LD_LIBRARY_PATH
export TMAKEDIR=$ARMQT/arm220/tmake
export TMAKEPATH=$TMAKEDIR/lib/qws/linux-arm-g++

6>配置及编译qt, 最好配置是手敲的,网上考下来的容易少空格,配置错了又要重编划不来
echo 'yes'|./configure -qte "-embedded -xplatform linux-arm-g++ -qconfig qpe -no-qvfb -depths 16,24 -system-jpeg -system-libpng -system-zlib -gif -thread -no-xft -release -I$ARMQT/tools/include -L$ARMQT/tools/lib -lpng -lz -luuid -ljpeg" -qpe "-xplatform linux-arm-g++ -edition pda -displaysize 320x240 -I$ARMQT/tools/include -L$ARMQT/tools/lib -prefix=$ARMQT/qtopia"

make
make install

总算编出来了

2008年12月18日星期四

liboil编译选项

下载地址是http://liboil.freedesktop.org/download/

./configure --host=arm-linux --prefix=$PWD/install GLIB_CFLAGS=-I/home/gongh/test/gstreamer/glib-2.18.3/install/include/ GLIB_LIBS=-L/home/gongh/test/gstreamer/glib-2.18.3/install/lib/ CFLAGS="-I/home/gongh/test/gstreamer/glib-2.18.3/install/lib/glib-2.0/include -I/home/gongh/test/gstreamer/glib-2.18.3/install/include/glib-2.0" LDFLAGS=-L/home/gongh/test/gstreamer/glib-2.18.3/install/lib/ --disable-static --with-html-dir=/tmp/dump

开始用的是liboil0.3.15一直不能编译通过,错误是
arm-linux-gcc -DHAVE_CONFIG_H -I. -I. -I../.. -Wall -D_BSD_SOURCE -D_GNU_SOURCE -I../.. -DOIL_ENABLE_UNSTABLE_API -mfpu=vfp -I/home/gongh/test/gstreamer/glib-2.18.3/install/lib/glib-2.0/include -I/home/gongh/test/gstreamer/glib-2.18.3/install/include/glib-2.0 -MT libarm_la-math_vfp.lo -MD -MP -MF .deps/libarm_la-math_vfp.Tpo -c math_vfp.c -fPIC -DPIC -o .libs/libarm_la-math_vfp.o
cc1: error: invalid option `fpu=vfp'
make[3]: *** [libarm_la-math_vfp.lo] Error 1
make[3]: Leaving directory `/home/gongh/test/gstreamer/liboil-0.3.15/liboil/arm'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/home/gongh/test/gstreamer/liboil-0.3.15/liboil'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/gongh/test/gstreamer/liboil-0.3.15'
make: *** [all] Error 2

然后我换成了0.3.12版本居然过了。

但是0.3.12版本不能满足gstreamer 最低0.3.14要求。
再编译0.3.15,注释configure16617行,
#VFP_CFLAGS="$VFP_CFLAGS -mfpu=vfp"
这样是可以编译过,但这样会不会有什么问题?

gstreamer编译选项

另外下载了flex-2.5.35.tar.gz编译后替换了/usr/bin/flex,不然gstreamer-0.10.21配置检查flex版本过不了,即使修改configure中flex版本让老版本的去编译,也通过不了,确实还是需要高版本的flex才行

GLIB_CFLAGS=-I/home/gongh/test/gstreamer/glib-2.18.3/install/include/glib-2.0/ GLIB_LIBS=-L/home/gongh/test/gstreamer/glib-2.18.3/install/lib/ XML_LIBS=-L/home/gongh/test/gstreamer/libxml2-2.6.30/install/lib/ XML_CFLAGS=-I/home/gongh/test/gstreamer/libxml2-2.6.30/install/include/ ./configure --disable-nls --disable-static --enable-binary-registry --disable-loadsave --with-html-dir=/tmp/dump --prefix=$PWD/install --host=arm-linux LDFLAGS="-L/home/gongh/test/gstreamer/libxml2-2.6.30/install/lib/ -L/home/gongh/test/gstreamer/glib-2.18.3/install/lib/ -lglib-2.0 -lgio-2.0 -lgobject-2.0 -lgthread-2.0 -lgmodule-2.0" CFLAGS="-I/home/gongh/test/gstreamer/libxml2-2.6.30/install/include/ -I/home/gongh/test/gstreamer/glib-2.18.3/install/include/glib-2.0/ -I/home/gongh/test/gstreamer/glib-2.18.3/install/lib/glib-2.0/include" GLIB_ONLY_CFLAGS=-I/home/gongh/test/gstreamer/glib-2.18.3/install/include/glib-2.0/ GLIB_ONLY_LIBS=-L/home/gongh/test/gstreamer/glib-2.18.3/install/lib/

2008年12月17日星期三

交叉编译glib 2.18.3

现在版本是glib-2.18.3,编译器arm-linux 3.4.1

我用FC4编译的,有点老,在configure的时候说pkg-config版本太老了,至少要0.16版本的,而FC4是0.15版本,所以我把configure改了.新linux应该不用改吧
7600 if $PKG_CONFIG --atleast-pkgconfig-version 0.16 ; then
改成了
7600 if $PKG_CONFIG --atleast-pkgconfig-version 0.15 ; then

然后参考一篇很有用的howto
http://library.gnome.org/devel/glib/unstable/glib-cross-compiling.html
需要写一个cache文件arm.cache,且我在当前目录下建立了一个install文件夹,存放make install后的库等。配置是
./configure --cache-file=arm.cache --host=arm-linux --prefix=$PWD/install

编译时如果出现错误,就看错误是什么,根据howto添加,我编译时最少添加如下几项后就能配置通过,然后就编译通过了。以下是arm.cache的内容。
glib_cv_long_long_format=ll
glib_cv_stack_grows=no
glib_cv_uscore=no
ac_cv_func_posix_getpwuid_r=yes
ac_cv_func_posix_getgrgid_r=yes

当配置成功后arm.cache内容就变了

2008年12月11日星期四

MPlayer-1.0rc2编译选项

--target=arm-linux --prefix=install --cc=/usr/local/arm/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux-gnu/bin/arm-softfloat-linux-gnu-gcc --enable-fbdev --disable-win32dll --disable-dvdread --disable-network --enable-menu --disable-ftp --disable-alsa --enable-ossaudio --disable-tv --disable-x11 --enable-cross-compile --target=arm-linux --host-cc=gcc --disable-armv5te --disable-armv6 --language=en --enable-debug

可以跑,不过mp3没声音,所以一会加个mad上去
加上了,要make clean后再make,不然链接有错误
./configure --target=arm-linux --prefix=install --cc=/usr/local/arm/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux-gnu/bin/arm-softfloat-linux-gnu-gcc --enable-fbdev --disable-win32dll --disable-dvdread --disable-network --enable-menu --disable-ftp --disable-alsa --enable-ossaudio --disable-tv --disable-x11 --enable-cross-compile --target=arm-linux --host-cc=gcc --disable-armv5te --disable-armv6 --language=en --enable-debug --enable-mad --with-extraincdir=/home/gongh/test/libmad-0.15.1b/install/include --with-extralibdir=/home/gongh/test/libmad-0.15.1b/install/lib --disable-mp3lib

可以播mp3了

但是播放avi时还是会音视频不同步,加autosync后,视频虽然和音频打印同步了,但是其实CPU速度就是不够,声音还是走在视频前面

2008年11月27日星期四

uda1341在2.6.27 2440

直接用的网上的patch,虽然patch的时候稍微有一点差别,造成*.orig, *.prej,但是改一下就好了,把patch地址给出来。连续4页

[PATCH RESEND 0/3] ALSA SOC driver for s3c24xx with uda134x

http://www.spinics.net/lists/arm-kernel/msg58298.html

http://www.spinics.net/lists/arm-kernel/msg58299.html

http://www.spinics.net/lists/arm-kernel/msg58300.html

http://www.spinics.net/lists/arm-kernel/msg58301.html

记录一下今天上午看的mmc代码(2.6.27)

S3C2440板子。先统计一下编译了哪些文件,分别是

card/
block.o queue.o
host/
s3cmci.o
core/
bus.o core.o host.o
及sd,mmc,sdio 3种规范的相关文件:
sd: sd.o sd_ops.o
mmc: mmc.o mmc_ops.o
sdio: sdio.o sdio_ops.o sdio_bus.o sdio_cis.o sdio_io.o sdio_irq.o

看别人写的抄下来的流程:
1. 内核启动initcall ==>> mmc_init() ==>> mmc_blk_init()
2. xx_mmc_probe 检测挂在的设备
3. 起延时任务mmc_rescan()对卡初始化
4. mmc_attach_sd(),mmc_attach_mmc(),mmc_attach_sdio()加载设备
5. mmc_add_card()

6.卡加入系统后,mmc_blk_probe()分配mmc_blk_data结构变量
7.mmc_init_queue()初始化
8.建立线程mmc_queue_thread(),接受块设备读写请求并处理

然后看代码把每个文件做的事写一下,有点乱
s3cmci.c
注册s3c2410,2412,2440平台驱动
mmc_alloc_host
硬件初始化,注册中断
mmc->ops = &s3cmci_ops 结构成员函数有request,set_ios,get_ro,get_cd
中断函数s3cmci_irq()完成读写,中断中起tasklet即pio_tasklet(),再区分为do_pio_read(),do_pio_write()

block.c
注册块设备,主设备号179,向mmc_driver注册驱动
mmc_blk_probe()==>>mmc_blk_alloc()==>>mmc_init_queue()在此函数中起线程.线程函数是queue.c中的mmc_queue_thread()
在 线程中根据blk_queue_plugged()判断队列是否有插入,取得elv_next_request()的返回值struct request*,调用mq->issue_fn函数即block.c的mmc_blk_issue_irq()处理,在 mmc_wait_for_req()函数种把请求传给host->ops->request,即s3cmci_ops中的request结 构成员函数

bus.c
struct mmc_card结构相关
提供函数alloc card(),add_card(), 在add_card()中调用device_add()添加设备
向系统注册总线mmc_bus_type
把block.c注册过来的mmc_driver注册为系统的驱动

core.c
mmc_rescan()分辨检测卡
mmc_init()起工作队列,初始检测及热插拔时detect用
调用注册总线,注册class

host.c
与s3cmci.c相关联的文件,找到设备前先假设有设备,mmc_alloc_host()起工作队列mmc_rescan()检测设备,未检测到释放host,检测到了调用device_add添加设备

只看mmc规范
mmc.c
mmc_rescan中找到卡后调用mmc_attach_mmc初始化卡,提供detect函数每次检测卡是否拔出

mmc_ops.c
mmc的具体命令,比如go_idle(),send_cid()等

分辨sdio,mmc,sd卡,通过发命令,具体命令我不确定
发送cmd5,如果有响应就是sdio,没响应就往下走
发送cmd1,如果有响应就是mmc,如果没响应就是sd

卡插入中断后的处理:
s3cmci,c中的s3cmci_irq_cd()==>>mmc_detect_change()==>>host->detect()==>>mmc_detect()
这里的s3cmci_irq_cd()是sd卡插入检测脚cd的中断处理函数

mmc/sd 在 2.6.27 2440

让板子能识别热插拔的卡。正好手上MMC卡和SD卡都有,能用

1. 先加上sdi的platform_device, s3c_device_sdi
arch/arm/mach-s3c2440/mach-smdk2440.c
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
//zhourr
&s3c_device_adc,
&s3c_device_sdi,
};

2. 添加自己板子特别的地方,比如卡接的中断脚,卡插入检测脚,卡写保护脚,检测和写保护脚的极性,提供的sd卡电压范围
static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
/* This is currently here to avoid a number of if (host->pdata)
* checks. Any zero fields to ensure reaonable defaults are picked. */
//zhourr
.wprotect_invert = 0,
.detect_invert = 0,
.gpio_detect = S3C2410_GPG8,
.gpio_wprotect = S3C2410_GPH8,
.ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34,
.set_power = NULL,
};

此时MMC卡已经可以热插拔,并在dev下找到mmcblk0

# ls -l /dev/mmc*
brw-rw---- 1 0 0 179, 0 Jan 1 00:03 /dev/mmcblk0

但是SD卡系统启动前正常,热插拔插入时会有timeout错误
错误1:
s3c2440-sdi s3c2440-sdi: mci_setup_data() transfer stillin progress.
s3c2440-sdi s3c2440-sdi: CMDSTAT: error CMDTIMEOUT
s3c2440-sdi s3c2440-sdi: CMD[ERR -110] #47 op:6 arg:0x00fffff1 flags:0x08b5 retries:0 Status:nothing to complete
s3c2440-sdi s3c2440-sdi: DAT[OK] #4 bsize:64 blocks:1 bytes:64
s3c2440-sdi s3c2440-sdi: powered down.
mmc0: error -110 whilst initialising SD card

错误2:
s3c2440-sdi s3c2440-sdi: unfinished read - pio_count:[0] pio_words:[16]
s3c2440-sdi s3c2440-sdi: CMD[OK] #68 op:6 arg:0x00fffff1 flags:0x08b5 retries:0 R0:0x00000900
s3c2440-sdi s3c2440-sdi: DAT[ERR -22] #6 bsize:64 blocks:1 bytes:64 DCNT:0x00000000
mmc0: problem reading switch capabilities, performance might suffer.

3.解决SD插入错误-->加延时
driver/mmc/core/sd.c 的mmc_sd_init_card()函数中mmc_read_switch前延时10ms

mdelay(10);

err = mmc_read_switch(card);

查看插入后的设备
# ls -l /dev/mmc*
brw-rw---- 1 0 0 179, 0 Jan 1 00:04 /dev/mmcblk0
brw-rw---- 1 0 0 179, 1 Jan 1 00:04 /dev/mmcblk0p1

mount后使用卡,可读写
# mount -t vfat /dev/mmcblk0p1 /opt/

写完后自己sync一下,确保写进去了,PC上就可以看到了


4.有个问题:
如果拔出太快又插入,现在会当作只拔出了。还不清楚MMC里怎么做的,要看一下了

2008年11月26日星期三

cs8900在2440 linux2.6.27

driver/net/cs89x0.c

1.修改ioaddr和irq,接CS3,addr24选择io或memory方式,irq是EINT9,GPG1,写网卡MAC地址
#include "../../arch/arm/mach-s3c2410/include/mach/map.h"
#include "../../arch/arm/mach-s3c2410/include/mach/regs-mem.h"
#include "../../arch/arm/mach-s3c2410/include/mach/regs-gpio.h"
#include "../../arch/arm/mach-s3c2410/include/mach/regs-irq.h"
static unsigned int netcard_portlist[] __used __initdata = { S3C24XX_VA_CS8900_CS3 + 0x300, 0};
static unsigned int cs8900_irq_map[] = {IRQ_EINT9,0,0,0};

2.添加2440硬件初始化函数
static void cs89x0_hw_setup(struct net_device *dev)
{
unsigned int regval = 0;

//CS3, 16 bit bus width
__raw_writel(0x2211d110,S3C2410_BWSCON);
__raw_writel(0x1f7c,S3C2410_BANKCON3);

//EINT[9]
regval = __raw_readl(S3C2410_GPGCON);
regval &= ~(3<<2);
regval |= 2 <<2;
__raw_writel(regval, S3C2410_GPGCON);

//irq mode
regval = __raw_readl(S3C2410_EXTINT1);
regval &= ~(7<<4);
regval |= 4 <<4;
__raw_writel(regval, S3C2410_EXTINT1);

//irq MASK
regval = __raw_readl(S3C2410_EINTMASK);
regval &= ~(1<<9);
__raw_writel(regval, S3C2410_EINTMASK);

//mac addr
dev->dev_addr[0] = 0x00;
dev->dev_addr[1] = 0x00;
dev->dev_addr[2] = 0xc0;
dev->dev_addr[3] = 0xff;
dev->dev_addr[4] = 0xee;
dev->dev_addr[5] = 0x08;

printk("[cs89x0_probe] S3C2410_BWSCON = %x\r\n", __raw_readl(S3C2410_BWSCON));
printk("[cs89x0_probe] S3C2410_BANKCON3 = %x\r\n", __raw_readl(S3C2410_BANKCON3));
printk("[cs89x0_probe] S3C2410_GPGCON = %x\r\n", __raw_readl(S3C2410_GPGCON));
printk("[cs89x0_probe] S3C2410_EXTINT1 = %x\r\n", __raw_readl(S3C2410_EXTINT1));
printk("[cs89x0_probe] S3C2410_EINTMASK = %x\r\n", __raw_readl(S3C2410_EINTMASK));
printk("[cs89x0_probe] MAC ADDR: %x-%x-%x-%x-%x-%x\r\n",
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);

}

3.在cs89x0_probe里调用cs89x0_hw_setup函数

cs89x0_hw_setup(dev);

if (net_debug)
printk("cs89x0:cs89x0_probe(0x%x)\n", io);

4.修改readword,writeword函数,portno不需要左移(我现在怎么看着不需要了啊,好像else里的也没有左移)

static u16
readword(unsigned long base_addr, int portno)
{
return __raw_readw(base_addr+portno);
}

static void
writeword(unsigned long base_addr, int portno,u16 value)
{
__raw_writew(value,base_addr+portno);
}

5.设置网口RJ45,省去boot启动时带参数
lp->force = g_cs89x0_media__force;
改成
lp->force=FORCE_RJ45;

6.注释掉irq_map的安全检查
#if 0
if (((1 <<>irq) & lp->irq_map) == 0) {
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map);
ret = -EAGAIN;
goto bad_out;
}
#endif

7.2440初始化时增加分配cs8900的io port,修改mach-smdk2440.c

static struct map_desc smdk2440_iodesc[] __initdata = {
/* ISA IO Space map (memory space selected by A24) */

{
.virtual = (u32)S3C24XX_VA_ISA_WORD,
.pfn = __phys_to_pfn(S3C2410_CS2),
.length = 0x10000,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
.pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
.length = SZ_4M,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_BYTE,
.pfn = __phys_to_pfn(S3C2410_CS2),
.length = 0x10000,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
.pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
.length = SZ_4M,
.type = MT_DEVICE,
}, { //zhourr
.virtual = (u32)S3C24XX_VA_CS8900_CS3,
.pfn = __phys_to_pfn(S3C2410_CS3 + (1<<24)),
.length = SZ_1M,
.type = MT_DEVICE,
}
};

8.在arch/arm/mach-s3c2410/include/mach/map.h增加宏定义,跟别的不冲突就行了
#define S3C24XX_VA_CS8900_CS3 S3C2410_ADDR(0x04000000)

2008年11月20日星期四

sh下运行#!/bin/bash开头的脚本会返回not found

inittab脚本:
::sysinit:/etc/rc.sysinit
::respawn:-/bin/sh
::once:/bin/mount -a
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown

我在/etc/inittab里想执行/etc/rc.sysinit脚本失败,提示是:
cannot run '/etc/rc.sysinit': No such file or directory

单独在sh里敲提示not found
# /etc/rc.sysinit
-/bin/sh: /etc/rc.sysinit: not found

但是source就可以执行
# source /etc/rc.sysinit
starting udevd...

我以为是没有执行属性,还是不行
chmod 777 /etc/rc.sysinit

网上说sh /etc/rc.sysinit,我就改inittab第一行为:
::sysinit:/bin/sh /etc/rc.sysinit
这样脚本就可以执行了,

但是脚本里udevd失败,报错:
starting udevd...
udevd[824]: main: error disabling OOM: No such file or directory

后来发现我的rc.sysinit脚本前用的是#!/bin/bash,改为#!/bin/sh,又把inittab第一行恢复原样
这样rc.sysinit就可以找到并执行了

但是udevd还是报错,根据启动打印sysinit第一个执行,我想把它放到mount -a的后面,于是把第一行放到了第三行后面
::respawn:-/bin/sh
::once:/bin/mount -a
::sysinit:/etc/rc.sysinit
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown
但是它还是第一个执行

我猜是::sysinit:使它第一个执行的,改为::once:
udevd就好了

2008年11月17日星期一

2440 2.6.27启动后主频405Mhz却打印出来是571Mhz

2.6.27
网上有人一样是启动时乱码,他说修改时钟频率为12M就可以了,我的板子本来就是12M晶振
我是临时通过屏蔽内核串口设置来去掉乱码的,下面有正确做法
drivers/serial/samsung.c中8个wr_regl 函数屏蔽掉
core 571.536 MHz,确实是主时钟错了,有点离谱,bootloader里的时钟是405M,启动后不修改uart设置,能正常显示打印,说明这时时钟还是405MHZ。虽然是主频导致uart计算波特率的divider出错导致的乱码,但是为什么会到571Mhz呢?

这样我启动后看到的打印是:
enter Main
cp15 register 1 = c000107c
************************************
* *
* 2440 bootloader *
* Nov 17 2008,11:22:08 *
* *
************************************
Read chip id = ec76
Nand flash status = c0
NAND_Read addr : 40000, size : 1c0000
................................................................................................................Uncompressing Linux.................................................................................................................. done, booting the kernel.
Linux version 2.6.27 (root@sherman_samba) (gcc version 3.4.1) #4 Tue Nov 18 11:51:27 CST 2008
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
Machine: SMDK2440
ATAG_INITRD is deprecated; please update your bootloader.
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C244X: core 571.536 MHz, memory 142.884 MHz, peripheral 71.442 MHz
S3C24XX Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (2.116 MHz), fast, MPLL on, UPLL on
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200
irq: clearing subpending status 00000092
PID hash table entries: 256 (order: 8, 1024 bytes)
timer tcon=00000000, tcnt e88e, tcfg 00000200,00000000, usec 00001580
Console: colour dummy device 80x30
console [ttySAC0] enabled
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 61120KB available (3256K code, 322K data, 144K init)
Calibrating delay loop... 285.08 BogoMIPS (lpj=712704)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 440 bytes
NET: Registered protocol family 16
S3C2410 Power Management, (c) 2004 Simtec Electronics
S3C2440: Initialising architecture
S3C2440: IRQ Support
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
S3C244X: Clock Support, DVS off
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
NET: Registered protocol family 1
NetWinder Floating Point Emulator V0.97 (extended precision)
JFFS2 version 2.2. (NAND) (SUMMARY) © 2001-2006 Red Hat, Inc.
msgmni has been set to 119
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Console: switching to colour frame buffer device 30x40
fb0: s3c2410fb frame buffer device
lp: driver loaded but no devices found
ppdev: user-space parallel port driver
Serial: 8250/16550 driver4 ports, IRQ sharing enabled
s3c2440-uart.0: s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2440
s3c2440-uart.1: s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2440
s3c2440-uart.2: s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2440
brd: module loaded
loop: module loaded
dm9000 Ethernet Driver, V1.31
Uniform Multi-Platform E-IDE driver
Driver 'sd' needs updating - please use bus_type methods
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
60 ns is too big for current clock rate 142884
s3c2440-nand s3c2440-nand: cannot get suitable timings
s3c2440-nand: probe of s3c2440-nand failed with error -22
usbmon: debugfs is not available
s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
usbcore: registered new interface driver libusual
usbcore: registered new interface driver usbserial
usbserial: USB Serial support registered for generic
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial Driver core
usbserial: USB Serial support registered for FTDI USB Serial Device
usbcore: registered new interface driver ftdi_sio
ftdi_sio: v1.4.3:USB FTDI Serial Converters Driver
usbserial: USB Serial support registered for pl2303
usbcore: registered new interface driver pl2303
pl2303: Prolific PL2303 USB to serial adaptor driver
mice: PS/2 mouse device common for all mice
S3C24XX RTC, (c) 2004,2006 Simtec Electronics
s3c2440-i2c s3c2440-i2c: slave address 0x10
s3c2440-i2c s3c2440-i2c: bus frequency set to 372 KHz
s3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapter
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
TCP cubic registered
NET: Registered protocol family 17
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
Root-NFS: No NFS server available, giving up.
VFS: Unable to mount root fs via NFS, trying floppy.
VFS: Cannot open root device "mtdblock2" or unknown-block(2,0)
Please append a correct "root=" boot option; here are the available partitions:
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
========================
时钟不对,连nand都不能正常操作
------->>>>
s3c244x.c s3c244x_init_clocks
------->>>>
cpu.c static struct cpu_table cpu_ids[] __initdata
------->>>>
cpu.c s3c24xx_init_clocks
------->>>>
mach-smdk2440.c smdk2440_map_io
该函数中带了时钟输入参数
s3c24xx_init_clocks(16934400);
因为我们用的晶振是12M的,所以需要改成下面这样
s3c24xx_init_clocks(12000000);

这样串口也正常了,时钟也对了,nand也对了

2008年11月13日星期四

动态中断向量

ResetEntry
b ResetHandler
b Undefined_Handler
b SWI_Handler
b Prefetch_Handler
b Abort_Handler
nop
ldr pc, =0x300ffffc
b FIQ_Handler

//0x18 = jump to 0x300ffffc
//0x300ffffc = jump to IsrHandler
//b arm, ea000006 = 6 <<2 +8 + pc
//b code, (dst - src -8) >>2 +0xea000000
void RegInterrupteHandlerTable(void)
{
unsigned long dest_addr = (unsigned long)IsrHandler;
unsigned long offset_addr ;
unsigned long *pIrqHandler = (unsigned long *)0x300ffffc;

offset_addr = (((dest_addr - (unsigned long)pIrqHandler - 8)) >> 2)&0xffffff;

*pIrqHandler = 0xea000000+offset_addr;
}

以前把整个表做重新做动态了,没必要,现在就修改irq这一条,而且思路比以前清晰

0x18地址存放的指令是 pc=0x300ffffc
0x300ffffc地址存放的指令是 b IsrHandler,是做出来的指令

拿一般第一条指令的机器码来说,一般是b resethandler
0地址机器码 :0xea000006
resethandler函数地址 0x20

0 + 6 << 2 +8 = 0x20,这样就会跳转到resethandler函数的地址了

2008年11月4日星期二

-/bin/sh: XXX: not found

# ./qpe
-/bin/sh: ./qpe: not found

shell找不到该文件,及刚启动完打印的找不到/etc/rc.sysinit文件同样的现象

网上有人说是busybox静态编译改成动态编译就可以了,我改了,真的可以了
库文件当然用的是编译器里的*.so文件拷贝到根文件系统/lib下