|
楼主 |
发表于 2010-7-23 21:38:04
|
显示全部楼层
居然还有人在挖这个帖子啊,:-)。我当然很高兴告诉你了:
http://blog.csdn.net/xiaoshao_0_0/archive/2008/03/25/2217712.aspx
不是为了广告啊
原创 对saa7134电视卡驱动内核模块的探索和红外遥控实现 收藏
前回书讲到,我很不爽没有实现电视卡的红外遥控功能,于是,痛下决心,打算涉足从来没有弄过得内核编译这一块。有感于官方wiki还没有一个很好的关于内核编译的介绍,这里的内容适用于但是也不限于fedora 8,同时也涉及内核编译的一小点,不敢乱说,第一次弄,大家见笑了。
1.下载内核源代码包,最新的说法是有kernel-devel这个包就好了,实际上只是有了头文件和Makefile,Kconfig这样的配置文件了。我要编译的正好是内核的一个模块,所以内核源代码是免不了要下载的了。
首先,下载安装yum-utils(yum-utils-1.1.11-1.fc8 我的是这个)
yum install yum-utils
然后下载kernel source
yumdownloader --source kernel
然后我的到了一个rpm包:kernel-2.6.24.3-34.fc8.src.rpm,当然你的可能不一样阿。
然后安装这个包(用root登录,或者sudo):
rpm -ivh kernel-2.6.24.3-34.fc8.src.rpm
不要理会那些什么用户阿,组阿不存在的警告,因为本来就不存在阿。
然后还有很重要的一步,就是选择你的机器的架构:
root 用户:
rpmbuild -bp --target=$(uname -m) /usr/src/redhat/SPECS/kernel.spec
或者
sudo rpmbuild -bp --target=$(uname -m) /usr/src/redhat/SPECS/kernel.spec
就是指定你的内核类型,针对CPU,现在一般都i686级别了,uname -m 输出都是 i686。
安装之后,你的源文件在哪儿呢?
cd /usr/src/redhat/BUILD/
这里这个kernel目录即是我们的内核源代码了。
看一下,这里面有两个子目录:
linux-2.6.24.i686 vanilla
第一个,就是我们要用的打好了redhat特定的补丁之后的内核,vanilla则是最纯洁的kernel.org上面下载来的那种内核。
然后,我进入到linux-2.6.24.i686这个目录下面。
发现这里有很多config.XXX的文件,保险起见,我们还是采用自己的内核原来的config作为蓝本。
所以拷贝 cp /boot/config-2.6.24.3-34.fc8 ./.config
注意,这个/boot下的这个config文件是针对当前内核的最新的,用它覆盖当前目录下的.config这个隐藏文件。
然后运行make menuconfig,没有什么要改的,就把菜单拉到最下面,选择load config这个,选择我们的.config,呵呵,保险而已。
内核编译耗时耗力,当然是电脑CPU发烧了,哈哈。
改好之后,先编译了一下试试看,
make all
顾名思义,呵呵,用了1个小时吧,大概。
然后所有的东西(all)都编译好了,进入到drivers/media/video/saa7134/这个目录下,找到我们的主角,saa7134XXX.ko这样的文件:
saa6752hs.ko saa7134-alsa.ko saa7134-dvb.ko saa7134-empress.ko saa7134.ko
我们用insmod这个命令来尝试一下:
首先把我们就得模块卸载:
rmmod saa7134
insmod saa7134.ko
如果报错说没有这个命令,用/sbin/rmmod 或者/sbin/insmod
实际上,这里会报内核模块 format not match也就是说格式不对。
这里我想了很久,才想起来,是不是我们的内核版本问题呢?
于是回到 /usr/src/redhat/BUILD/kernel-2.6.24/linux-2.6.24.i686
打开Makefile,最上面就是版本号了,只有一个小区别,就是fedora的内核都带了一个
2.6.24.3-34.fc8 这个-34.fc8就是比标准的多出来的东西。
一不做,二不休,我就把这个
/usr/src/kernels/2.6.24.3-34.fc8-i686/Makefile
拷贝过来,覆盖了了事。
然后在make all ??
这里考虑了一下,用make modules就足够了,呵呵,这样比较快10分钟左右搞定。
在insmod一次成功了。
先别高兴的太早,这个只是一个默认的编译阿,换句话说跟我们原来的一样阿。
一律拷到(等等,请先备份saa7134 这个目录阿)
/lib/modules/2.6.24.3-34.fc8 /kernel/drivers//media/video/saa7134/
红色部分,请参考当前的内核版本号,
uname -a
Linux bogon 2.6.24.3-34.fc8 #1 SMP Wed Mar 12 18:17:20 EDT 2008 i686 athlon i386 GNU/Linux
这样看到了吧。
然后呢,试试看,我们的新模块吧。
如果你只制作了一个ko的模块,当然用insmod就可以尝试了,但是要是你同时更新两个文件,你就要考虑把它们复制到系统目录里了。
下面是我列出了针对天敏电视精灵二代的修改,完美地识别,包括了红外遥控的部分。
[robin@localhost common]$ for b in $a; do echo $b ;diff ./$b /home/robin/linux-2.6.25.x86_64/drivers/media/common/$b; done
ir-functions.c
ir-keymaps.c
2035a2036,2116
> /*
> * Remote control for the 10MOONTVBABY2
> * Robin Shao <swjbook@gmail.com>
> */
>
> IR_KEYTAB_TYPE ir_codes_10moon_baby_2[IR_KEYTAB_SIZE] = {
> // Keys 0 to 9
> [0x05] = KEY_0,
> [0x24] = KEY_1,
> [0x2e] = KEY_2,
> [0x3e] = KEY_3,
> [0x26] = KEY_4,
> [0x36] = KEY_5,
> [0x22] = KEY_6,
> [0x3a] = KEY_7,
> [0x12] = KEY_8,
> [0x1a] = KEY_9,
>
> [0x0b] = KEY_ESC,//KEY_RECORD,// recording
> [0x18] = KEY_MUTE, // mute
> [0x02] = KEY_POWER,
> [0x01] = KEY_LAST, // recall
> [0x0d] = KEY_UP,//KEY_CHANNELUP,// channel / program +
> [0x00] = KEY_DOWN,//KEY_CHANNELDOWN,// channel / program -
> [0x2c] = KEY_VOLUMEUP,
> [0x2a] = KEY_VOLUMEDOWN,
> [0x2d] = KEY_ENTER,//KEY_OK,// also labeled as Pause
> [0x0e] = KEY_F,//KEY_ZOOM,// full screen and Stop
> [0x10] = KEY_MODE,// AV Source or Rewind
> [0x08] = KEY_LIST, // -/--
> // small arrows above numbers
> [0x16] = KEY_RIGHT, // also Fast Forward
> [0x1c] = KEY_LEFT, // also Rewind
> // these are in a rather non standard layout and have
> //an alternate name written
> [0x1e] = KEY_F5, // Video Setting
> [0x50] = KEY_SPACE, // Video Default
> // [0x28] = KEY_S, // Snapshot
> [0x0c] = KEY_V, // Hide Panel
> // Four buttons without label
> // [0x92] = KEY_RED,
> // [0xd0] = KEY_GREEN,
> // [0xc8] = KEY_YELLOW,
> [0x0a] = KEY_BLUE,
> };
> EXPORT_SYMBOL_GPL(ir_codes_10moon_baby_2);
>
> /*
> off key=0x2
> mute key=0x18
> videosetting key=0x1e
> snapshot key=0x28
> pause key=0x2d
> video default key=0x14
> hide panel key=0xc
> s1 key=0x25
> s2 key=0x34
> s3 key=0x32
> s4 key=0x3
> v- key=0xd
> c+ key=0x2a
> rec key=0xb
> v+ key=0x2c
> c- key=0x0
> full key=0xe
> av key=0x10
> sleft key=0x1c
> sright key=0x16
> n1 key=0x24
> n2 key=0x2e
> n3 key=0x3e
> n4 key=0x26
> n5 key=0x36
> n6 key=0x22
> n7 key=0x3a
> n8 key=0x12
> n9 key=0x1a
> list key=0x8
> n0 key=0x5
> last key=0x1
> */
Kconfig
Makefile
saa7146_core.c
saa7146_fops.c
saa7146_hlp.c
saa7146_i2c.c
saa7146_vbi.c
saa7146_video.c
[robin@localhost saa7134]$ for b in $a; do echo $b ;diff ./$b /home/robin/linux-2.6.25.x86_64/drivers/media/video/saa7134/$b; done
Kconfig
Makefile
saa6752hs.c
saa7134-alsa.c
saa7134-cards.c
805a806,848
> [SAA7134_BOARD_10MOONSTVBABY2] = {
> /* "robin shao" <swjbook@gmail.com> */
> .name = "10MOONS PCI TV CAPTURE CARD",
> .audio_clock = 0x00200000,
> .tuner_type = TUNER_LG_PAL_NEW_TAPC,
> .radio_type = UNSET,
> .tuner_addr = ADDR_UNSET,
> .radio_addr = ADDR_UNSET,
> .gpiomask = 0xe000,
> .inputs = {{
> .name = name_tv,
> .vmux = 1,
> .amux = LINE2,
> .gpio = 0x0000,
> .tv = 1,
> },{
> .name = name_comp1,
> .vmux = 0,
> .amux = LINE2,
> .gpio = 0x4000,
> },{
> .name = name_comp2,
> .vmux = 3,
> .amux = LINE2,
> .gpio = 0x4000,
> },{
> .name = name_svideo,
> .vmux = 8,
> .amux = LINE2,
> .gpio = 0x4000,
> }},
> .radio = {
> .name = name_radio,
> .amux = LINE2,
> .gpio = 0x2000,
> },
> .mute = {
> .name = name_mute,
> .amux = LINE2,
> .gpio = 0x8000,
> },
> },
>
4202a4246,4252
> .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
> .subvendor = PCI_VENDOR_ID_PHILIPS,
> .subdevice = 0x2104,
> .driver_data = SAA7134_BOARD_10MOONSTVBABY2,
>
> },{
> .vendor = PCI_VENDOR_ID_PHILIPS,
5085a5136,5137
> case SAA7134_BOARD_10MOONSTVMASTER:
> case SAA7134_BOARD_10MOONSTVBABY2:
saa7134-core.c
saa7134-dvb.c
saa7134-empress.c
saa7134.h
256a257
> #define SAA7134_BOARD_10MOONSTVBABY2 133
saa7134-i2c.c
saa7134-input.c
67a68
> static int getkeycode_10MOON(int keyraw);
99a101,102
> // if(data!=0x3f)
> // data=getkeycode_10MOON(data);
100a104
> //printk("try to put a key down key=%d\n",data);
102a107
> //printk("no key now\n");
408a414,419
> case SAA7134_BOARD_10MOONSTVMASTER:
> ir_codes = ir_codes_encore_enltv;
> mask_keycode = 0x00000fa;
> mask_keyup = 0x0000100;
> polling = 50; //ms
> break;
414a426,432
> case SAA7134_BOARD_10MOONSTVBABY2:
> ir_codes = ir_codes_10moon_baby_2;
> // ir_codes = ir_codes_encore_enltv;
> mask_keycode = 0x00000fa;
> mask_keyup = 0x0000100;
> polling =50; //ms
> break;
575a594,630
> static int getkeycode_10MOON(int keyraw)
> {
> int key=-1;
> printk("before key=0x%x\n",keyraw);
> return keyraw;
> switch(keyraw)
> {
> case 0x08:
> key=0x0e;//ESC for OFF
> break;
> case 0x60:
> key=0x0d;//M for mute
> break;
> case 0x38:
> key=0x1b;//f for full screen
> break;
> case 0xa8:
> key=0x17;//v-
> break;
> case 0xb0:
> key=0x0c;//v+
> break;
> case 0x32:
> key=0x16;//c+
> break;
> case 0x00:
> key=0x12;//c-
> break;
> default:
> key=keyraw;
> }
> printk("after key=0x%x\n",key);
> return key;
>
>
> }
>
saa7134-reg.h
saa7134-ts.c
saa7134-tvaudio.c
saa7134-vbi.c
saa7134-video.c |
|