2009年3月14日星期六
使用qemu调试arm linux内核
安装qemu
下载内核文件 这里用2.6.27
建立交叉编译环境。
2.获取编译内核用的config文件
从qemu网站下载测试qemu用的文件http://www.nongnu.org/qemu/linux-user-test-0.3.tar.gz
tar zxvf linux-user-test-0.3.tar.gz
解压后,可以看到3个文件:arm_root.img zImage.integrator README
假设解压后的文件放在 /qemu-test目录下
在内核源代码的根目录下执行
./scripts/extract-ikconfig /qemu-test/zImage.integrator > qemu-linux_defconfig
结束后,将生成一个qemu-linux_defconfig配置文件
3.编译内核
cp qemu-linux_defconfig .config
make zImage
4.用qemu启动内核
qemu-system-arm -kernel zImage -initrd /qemu-test/arm_root.img / -redir tcp:9999::9999 -s -S
5.用gdb调试内核
假设运行qemu的机器的ip地址是192.168.1.5
arm-eabi-gdb vmlinux
在gdb的提示符下运行下面的命令:
target remote 192.168.1.5:1234
这时候就可以调试内核了。
比如设置断点
break start_kernel
查看寄存器
info registers
等等。。。
2009年3月1日星期日
用android build system 编译自己的init
建立一个myinit文件夹
编辑一个init.c文件
代码如下
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int i = 0;
while (1)
{
printf("hello world (%d)",i++);
sleep(2);
}
return 0;
}
另外建立一个Android.mk 文件,内容如下
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
init.c
LOCAL_MODULE:= init
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
LOCAL_STATIC_LIBRARIES := libcutils libc
#LOCAL_STATIC_LIBRARIES := libcutils libc libminui libpixelflinger_static
#LOCAL_STATIC_LIBRARIES += libminzip libunz libamend libmtdutils libmincrypt
#LOCAL_STATIC_LIBRARIES += libstdc++_static
include $(BUILD_EXECUTABLE)
在myinit文件夹下输入mm,
编译系统就会自动输出一个编译好的init程序
输出的路径也会提示出来。
用android build system 编译一个最小的android平台
http://source.android.com/download
这个网站的方法配置系统
然后下载android平台文件
repo init -u git://android.git.kernel.org/platform/manifest.git
repo sync
在平台所在文件夹下运行
. build/envsetup.sh
然后运行
在build/core/main.mk文件中的
ifeq ($SDK_ONLY),true)行前面
添加SDK_ONLY := false
BUILD_TINY_ANDROID := true
保存。
在平台所在文件夹下,运行mm,系统将自动编译整个平台。
所生成的文件的存放路径也会提示出来。
如果提示和libpixelflinger 与hardware_legacy依赖相关的错误,
则修改
Android.mk中的LOCAL_SHARED_LIBRARIES
将hardware_legacy行去掉。
2009年2月26日星期四
让vim显示行尾的空格
match WhitespaceEOL /\s\+$/
2009年2月25日星期三
2009年2月24日星期二
make xxx Is a directory. Stop. 的原因
2009年2月19日星期四
为linux建立最小的根文件系统
在编译内核时候,可以指定一个文件夹作为内核启动时候的根文件系统,linux中管这个文件系统叫做initramfs。
具体做法如下(以i386为例)
1.下载内核文件
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.26.tar.bz2
2.解压内核
bzip2 -d linux-2.6.26.tar.bz2 生成一个linux-2.6.26.tar文件,然后
tar xvf linux-2.6.26.tar
解压后,将有个linux-2.6.26文件夹存在
3.准备一个iniramfs文件系统的文件夹
在linux-2.6.26文件夹下建立一个文件夹 myinitramfs
写一个测试用的hello world,起名为hello.c,如下:
#include
#include
int main(int argc,char *argv[])
{
int i = 0;
while (1) {
printf("hello world (%d)\n",i);
}
return 0;
}
编译 gcc -static -o init hello.c
把init拷贝到myinitramfs文件夹下。
cp init myinitramfs/
由于需要显示文字,还需要在文件夹下准备console设备文件。
mkdir myinitramfs/dev
cp -a /dev/console myinitramfs/
4.编译内核
在linux-2.6.26文件下下,执行make help。
将看到很多帮助信息,其中有一项是 i386_defconfig
执行 make i386_defconfig,将生成一个.config文件。
为了把之前准备好的文件夹添加到内核配置文件中,还需要重新配置下config文件
make config
在 General Setup --->
Initial RAM filesystem and RAM disk (initramfs/initrd) support (BLK_DEV_INITRD) [Y/n/?]
Initramfs source file(s) (INITRAMFS_SOURCE) [myinitramfs]
处,输入准备好的文件夹.
配置好后,在.config文件中会有如下一条定义
CONFIG_INITRAMFS_SOURCE="myinitramfs"
保存.config
make 编译内核
5.用qemu测试内核和initramfs
qemu -kernel linux-2.6.26/arch/i386/boot/bzImage -initrd linux-2.6.26/usr/initramfs_data.cpio.gz /dev/zero
initramfs_data.cpio.gz 这个文件是内核自动生成的,具体名字可能不同的系统或者内核有差异,但是后缀应该是.cpio.gz
2008年7月13日星期日
linux usb设备驱动程序初探
- USB2.0协议规格,这个可以到www.usb.org网站下载,如果要做HID(人机接口设备)的话,还要看下hid的协议,也在该网站上。
- USB设备的工作方式,就是设备都会向主机提供那些信息
- linux如何发现USB设备,如何根据设备提供的信息搜索合适的驱动程序。
- linux驱动程序的开发方法,以及如何将驱动程序注册到linux系统中
3呢,linux是通过Vendor ID和ProductID找到一个设备的驱动程序的。当一个usb设备插到系统上后,系统会自动向设备索取设备描述信息,这个信息里面有设备的类型,最大数据包,还有上面提到的venderID和ProductID。收到设备描述信息后,linux系统会根据ID信息在已经注册的驱动程序中搜索,如果发现匹配的驱动程序,就调用驱动程序的Probe函数。没有的话,就变成无法识别的设备。
为了有个感性的认识,举了USB驱动开发的例子。
系统情况: 内核版本是2.6.22
ubuntu系统。
USB设备是一个VendorID和ProductID分别为0x4500,0xdf10的USB键盘。
操作步骤:
到系统的/usr/src/linux-xxx的源代码目录下,打开driver/usb目录,里面有个usb-skeleton.c文件,这个是linux系统提供的usb设备驱动模板。
把这个文件拷贝到一个目录下,假设为/test_user。
打开这个模板文件,
找到
#define USB_SKEL_VENDOR_ID
#define USB_SKEL_PRODUCT_ID
两行,修改为
#define USB_SKEL_VENDOR_ID 0x4500
#define USB_SKEL_PRODUCT_ID 0xdf10
修改后,这个模板驱动程序实际上就可以被注册到linux中,并被调用。
首先编译这个驱动,
在模板文件所在目录,建立一个Makefile
内容为
obj-m := usb-skeleton.o
注意的是.o文件的名字和驱动源程序文件名字一定要一样。
然后用Make -C /usr/src/linux-headers-xxx/ M=`pwd` modules命令编译
结束后,会输出一个usb-skeleton.ko文件。
使用insmod usb-skeleton.ko将驱动加载到linux系统中。
加载后,将usb设备插到usb接口,这时候
dmesg |tail命令,就可以看到usb驱动输出的一些信息了。
下图是一个USB设备描述信息