php mipsl,MIPS系列笔记-交叉编译MIPS架构ASLA

本文详细讲述了在MIPS架构下交叉编译Alsa库时遇到的`undefined reference to atomic_sub'和`atomic_add'错误,涉及配置步骤、编译器选择、函数修改和移植策略。作者分享了配置和编译的技巧,以及如何在嵌入式平台上正确安装和测试AlsaLib和AlsaUtil。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

交叉编译MIPS架构ASLA ../src/.libs/libasound.so: undefined reference to `atomic_sub'

我使用下面的命令进行config:

./configure --host=mipsel-linux --prefix=/home/cy/alsa/lib/ --enable-shared --disable-python

然后make出现以下错误:

../src/.libs/libasound.so: undefined reference to `atomic_sub'

../src/.libs/libasound.so: undefined reference to `atomic_add'

atomic_sub在include/iatomic.h中定义,找了下有__arm__对应的版本,但是没有__mipsel__,只有__mips__,那就死马当活马了:

./configure --host=mips-linux --prefix=/home/cy/alsa/lib/ --enable-shared --disable-python

然后make,又是:

../src/.libs/libasound.so: undefined reference to `atomic_sub'

../src/.libs/libasound.so: undefined reference to `atomic_add

//extern __inline__ void atomic_add(int i, atomic_t * v)

//extern __inline__ void atomic_sub(int i, atomic_t * v)

将其中的函数实现的函数类型“extern ”改为“static”即可!

//static __inline__ void atomic_add(int i, atomic_t * v)

//static __inline__ void atomic_sub(int i, atomic_t * v)

alsa-lib-1.0.24.1配置编译

CC=/opt/buildroot-gcc342/bin/mipsel-linux-gcc ./configure --host=mipsel-linux --prefix=/opt/mips/alsa_lib/ --enable-shared --disable-python

alsa-utils-1.0.24.2配置编译

CC=/opt/buildroot-gcc342/bin/mipsel-linux-gcc ./configure --prefix=/opt/mips/alsa_utils/ --host=mips --with-alsa-prefix=/opt/mips/alsa_lib/lib_1.0.24.1/lib/ --with-alsa-inc-prefix=/opt/mips/alsa_lib/lib_1.0.24.1/include/

./configure --prefix=/home/armmlinux/zdfwork/project/audio/alsa/output/mips-linux AR=/opt/buildroot-gcc342/bin/mipsel-linux-uclibc-ar CC=/opt/buildroot-gcc342/bin/mipsel-linux-uclibc-gcc CXX=/opt/buildroot-gcc342/bin/mipsel-linux-uclibc-g++ CXX=/opt/buildroot-gcc342/bin/mipsel-linux-uclibc-g++ --host=mipsel-linux-uclibc --enable-shared=yes --enable-static=no --target=mipsel-linux-uclibc --with-debug=no --with-alsa-devdir=/dev --with-softfloat --with-configdir=/usr/ LDFLAGS="-lm"

ALSA是目前Linux系统上大量采用的音频设备库,通过Alsa架构能分离驱动和应用的开发。Alsa为上层提供API的同时,也为下层提供了接口,在内核配置的时候指定“支持Alsa”就能得到内核支持,具体位置为:

Menuconfig -> Device Drivers -> Soundcard support -> Advanced Linux Sound Architecture

有了Alsa内核驱动,我们还需要Alsa Lib和Alsa Util的支持,这3者的关系如下图所示:

Alsa Util

-------------

Alsa lib

-------------

Alsa Driver

Alsa Util是纯应用层的软件,相当于Alsa设备的测试程序,AlsaLib则是支持应用API的中间层程序。移植Alsa程序的顺序就是先后移植Driver,Lib,Util。

一.Alsa Lib移植

1.编译alsa-lib:

cd /home/pingle/BackUp/alsa-tools/alsa-lib-1.0.15/

$ ./configure --prefix=/home/pingle/alsa/ AR=mipsel-openwrt-linux-uclibc-ar CC=mipsel-openwrt-linux-uclibc-gcc CXX=mipsel-openwrt-linux-uclibc-g++ CXX=mipsel-openwrt-linux-uclibc-g++ --host=mipsel-openwrt-linux-uclibc --enable-shared=yes --enable-static=no --target=mipsel-openwrt-linux-uclibc --with-debug=no --with-alsa-devdir=/dev --with-softfloat --with-configdir=/usr/local/share LDFLAGS="-lm"

make

make install

2.编译alsa-utils:

cd /home/pingle/BackUp/alsa-tools/alsa-utils-1.0.15/

./configure --prefix=/home/pingle/alsa/ AR=mipsel-openwrt-linux-uclibc-ar CC=mipsel-openwrt-linux-uclibc-gcc CXX=mipsel-openwrt-linux-uclibc-g++ CXX=mipsel-openwrt-linux-uclibc-g++ --host=mipsel-openwrt-linux-uclibc CPPFLAGS="-I/home/pingle/alsa/include" LDFLAGS="-L/home/pingle/alsa/lib" --disable-alsamixer

make

make install

1)--host指定编译器,这里指定为在目标板所运行的交叉编译器。注意运行本配置命令前务必保证编译器已经可以在Shell下直接执行了。

2)--prefix指定编译后文件的安装路径,后续的安装命令会在该目录中创建lib和include两个目录

3)若编译make install时报错:"mipsel-linux-ranlib command not found",解决方案为:执行make install之前,先用下su命令取得root权限。然后再执行make install

二.lib和util安装到嵌入式平台

在目标板上,以下文件必须被拷贝至对应位置

1) lib库文件,放在 /lib/中

2) conf文件,应放在/usr/local/share中,与编译时指定的目录相同

3) 应用文件,util能产生aplay,amixer,arecord可执行程序,这些文件可放在/usr/sbin中

4) 必须保证有/dev/snd/目录中,此目录下应包含以下几个设备文件(驱动),controlC0, pcmC0D0c, pcmC0D0p, timer如果这些文件已经在/dev/下,可拷贝到snd目录中。或者建立相应符号链接,

ln -s /dev/pcmC0D0c /dev/snd/pcmC0D0c

ln -s /dev/controlC0 /dev/snd/controlC0

ln -s /dev/timer /dev/snd/timer

三.运行测试程序

export ALSA_CONFIG_PATH=/usr/share/alsa/alsa.conf

未添加环境变量前出现的错误:

~ # ./aplay

ALSA lib conf.c:2827:(snd_config_hook_load) cannot access file /usr/share/arm-alsa/share/alsa/cards/aliases.conf

ALSA lib pcm.c:1959:(snd_pcm_open_conf) Invalid type for PCM default definition (id: default, value: cards.pcm.default)

aplay: main:533: audio open error: Invalid argument

~ # ./aplay

ALSA lib pcm.c:2090:(snd_pcm_open_noupdate) Unknown PCM default

aplay: main:533: audio open error: No such file or directory

编译报错:can't load library 'libpthread.so.0'。

解决方案:在openwrt中的make menuconfig中加入libpthread支持。

编译报错:fatal error: alsa/asoundlib.h: No such file or directory compilation terminated.

解决方案:mipsel-openwrt-linux-uclibc-gcc -lasound -L/home/pingle/alsa/lib -I/home/pingle/alsa/include -o test_audio2 test_audio02.c

四.回顾驱动程序

还是oss驱动接口调用比较好理解,不过终于找到了这个图,一看就啥都明白了

period(周期):硬件中中断间的间隔时间。它表示输入延时。

声卡接口中有一个指针来指示声卡硬件缓存区中当前的读写位置。只要接口在运行,这个指针将循环地指向缓存区中的某个位置。

frame size = sizeof(one sample) * nChannels

alsa中配置的缓存(buffer)和周期(size)大小在runtime中是以帧(frames)形式存储的。

period_bytes = frames_to_bytes(runtime, runtime->period_size);

bytes_to_frames()

The period and buffer sizes are not dependent on the sample format because they are measured in frames; you do not need to change them.

五.小技巧:

1.经过yaff文件系统烧入用户文件到板子上:

在/home/pingle/kernal/ws04/build_dir/target-mipsel_uClibc-0.9.32/root-xburst目录下加入自己的文件;

然后:

$cd /home/pingle/Yaff/linux-2.6.24.3/fs/yaffs2/utils

(可能要make一下哦!)

$./mkyaffs2image 1 /home/pingle/kernal/ws04/build_dir/target-mipsel_uClibc-0.9.32/root-xburst /home/pingle/desktop/xburst-tools-ws10/image/rootfs.yaffs2

(参数) (rootfs的目录) (生成的文件yaffs系统存到的目录)

2.uboot下检测内存命令:mtest.

驱动器 D 中的卷是 LINUX 卷的序列号是 4471-561B D:\桌面\mips交叉编译环境 的目录 2009-10-22 20:27 <DIR> . 2009-10-22 20:27 <DIR> .. 2009-10-22 20:09 27,425,338 gcc-3.4.3.tar.bz2 2009-10-22 20:08 7,421,782 binutils-2.10.91.0.2.tar.bz2 2009-10-22 20:08 242,445 glibc-linuxthreads-2.5.tar.bz2 2009-10-22 20:10 20,544,628 glibc-2.5.tar.gz 2009-10-22 20:20 1,720 elf-machine-rela-mips.dpatch 2009-10-22 20:26 4,727 建立基于linux的MIPS交叉编译环境 .txt 6 个文件 55,640,640 字节 2 个目录 6,793,084,928 可用字节 三、构建过程 1、准备环境 目标平台: mipsel-linux(即little endian,x86也是little endian的,不懂的话自己到网上查资料吧) 安装目录: /usr/local/crossdev 源代码安装目录: /usr/local/src 注:没有的目录请自行建立。 2、准备MIPS环境的头文件 我们是在i386下编译的,但要使用MIPS的头文件定义才能正确编译MIPS交叉编译工具。这些头文件都在kernel源程序中。 cd /usr/local/src/ tar xzvf linux-2.4.2.tar.gz cd linux/ make ARCH=mips menuconfig 在"CPU selection"中, 选中"(R3000) CPU type",也可以选你实际的MIPS平台的CPU类型 在"General setup"中, 选中"Generate little endian code" make dep mkdir -p /usr/local/crossdev/mipsel-linux/include cp -r /usr/local/src/linux/include/asm-mips /usr/local/crossdev/mipsel-linux/include/asm cp -r /usr/local/src/linux/include/linux /usr/local/crossdev/mipsel-linux/include/ 3、编译binutils cd /usr/local/src/ tar xzvf binutils-2.11.90.0.31.tar.gz cd binutils-2.11.90.0.31/ ./configure --target=mipsel-linux --prefix=/usr/local/crossdev make make install export PATH=/usr/local/crossdev/bin:$PATH 4、编译自举的(bootstrap)gcc 因为这时还没有MIPS的glibc库可以使用,只能编译一个最简单的gcc,用这个gcc编译出glibc后就可以再编译一个完成的gcc了。 cd /usr/local/src/ tar xzvf gcc-3.0.2.tar.gz cd gcc-3.0.2/ ./configure --target=mipsel-linux --prefix=/usr/local/crossdev --enable-languages=c --with-newlib --disable-shared make make install 注:以上编译安装的工具已经可以直接编译MIPS的kernel(make zImage)了。 5、编译glibc 现在可以使用刚才建立的binutils和gcc来编译MIPS的glibc了。 cd /usr/local/src/ tar xzvf glibc-2.2.3.tar.gz cd glibc-2.2.3/ tar xzvf ../glibc-linuxthreads-2.2.3.tar.gz patch -p1 < ../glibc-2.2.3-mips-base-addr-got.diff CC=mipsel-linux-gcc AR=mipsel-linux-ar RANLIB=mipsel-linux-ranlib ./configure --host=mipsel-linux --prefix=/usr/local/crossdev/mipsel-linux --enable-add-ons=linuxthreads make make install 6、重新编译完整的gcc cd /usr/local/src/ rm -rf gcc-3.0.2/ tar xzvf gcc-3.0.2.tar.gz cd gcc-3.0.2/ ./configure --target=mipsel-linux --prefix=/usr/local/crossdev --enable-languages=c,c++ make make install 以上就构建好了一套自己的MIPS交叉编译环境,目录在/usr/local/crossdev下,你可以把它打包拷贝到其它i386的Linux系统下也能使用。 要使用其来交叉编译时请先加上PATH环境变量:export PATH=/usr/local/crossdev/bin:$PATH
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值