本博客倡导开放源代码,在此公布之程序源代码如无特别声明均采用GNU通用公共 许可证(GPL)

乐在其中

分享学习Linux的乐趣

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  23 随笔 :: 0 文章 :: 401 评论 :: 0 Trackbacks
Linux内核负责管理/调度所有的系统资源和设备,并为应用程序提供服务。要想让播放机支持更多的设备,比如USB无线网卡,必需从内核入手。Linux支持动态加载模块,这些模块其实也是内核的一部分,只不过是被模块化罢了。模块化的好处之一是可以在需要时才加载模块,不需要时可以卸载,释放其占用的内存。这对内存紧张的嵌入式系统无疑是有帮助的。

我重新编译内核有以下几个目的:
1) 打开官方内核中某些没有打开的功能,如NFS服务器。
2) 尝试支持更多外部设备,如编译第三方驱动程序。
3) 内核瘦身,比如关闭某些不需要的功能,或者将其编译成模块。

内核源码仍使用华硕公布的源码,其中名为linux-2.6.12.274877.tgz的文件即是内核源码。用tar zxf linux-2.6.12.274877.tgz解开此文件,得到linux-2.6.12目录。看一下版本号
1 $ grep UTS_RELEASE linux-2.6.12/include/linux/version.h
2 #define UTS_RELEASE "2.6.12.6-VENUS"
与在播放机上用'uname -r'看到的一样,因此我们能确信这就是播放机所用内核的源码,虽然来源不是海信,但是我认为海信不会在内核上做什么改动,最多不过调整一些配置参数。

粗略研究了一下内核源码,发现Realtek在原始的2.6.12.6内核基础上做了不少修改,下面列出其中一部分:
  1. 文件系统方面增加了
    • fuse - Filesystem in Userspace
    • ptp - Picture Transfer Protocol,用于数码相机
    • vcd - CDROM文件系统
    • squashfs - 压缩的只读文件系统
    • yaffs - 针对NAND闪存优化的文件系统
  2. 大量的MIPS平台更新,其中包括对Realtek Venus系统(就是播放机所用系统)的支持
  3. 增加了Realtek无线网卡支持,包括RTL8185,RTL8187,RTL8190,RTL8192,RTL8191SU等芯片组的支持。
  4. 增加了一些专门针对Realtek Venus的优化
linux-2.6.12目录下有两个配置文件样本:config.develop.avhdd.mars.old 和 config.rescue.usb.flash.mars.old。根据字面意思推测第一个文件是常规模式的内核配置,第二个是急救模式的内核配置。急救模式只保留了急救固件升级所需功能,因此编译出的内核比常规模式的小很多。在MP800H上,急救内核与Bootloader放在同一个flash分区内,正常的固件升级不会更新这一部分。关于通过串口激活急救模式进行固件升级的方法,请看蓝媒论坛dragon版主的大作《MP800H串口刷机指南》
我以config.develop.avhdd.mars.old为基准对内核进行配置(执行make menuconfig),打开了NFS Server Support(编译成模块,并且只打开NFSv3支持),其余部分保持不变,最后得到的.config文件增加了如下几项:
1 CONFIG_NFSD=m
2 CONFIG_NFSD_V3=y
3 CONFIG_NFSD_TCP=y
4 CONFIG_EXPORTFS=m
然后执行make进行编译(注意:编译内核要用/usr/bin下的工具链,即mipsel-sdelinux-v6.03.01-1,在PATH中/usr/bin应该在/usr/local/bin的前面)。编译完成后会生成名为vmlinux.bin的文件,用lzma把它压缩后改名为vmlinux.develop.avhdd.mars.bin.lzma,这个文件即可用于制作固件。另外还需要把编译好的模块安装到某个目录以便于打包,比如要安装到/home/user/dist/modules则执行如下命令:
1 make INSTALL_MOD_PATH=/home/user/dist/modules modules_install
至此,我们已经准备好了新的内核和模块。在用自己编译的模块替换官方固件模块时要注意两点:
1. 如果配置内核是打开了DEBUG,编译出的模块会很大,在制作固件前最好把调试信息去掉。下面的命令可以很容易的完成这个任务:
1 $ cd /home/user/dist/modules
2 $ find . -name '*.ko' -exec mipsel-linux-strip --strip-unneeded '{}' \;
2. 有一个模块ufsd.ko是没有源码的,这个模块提供NTFS读写的支持。如果你想使用NTFS,则要从官方固件中拷贝这个文件。

posted on 2010-03-21 21:49 gouzhuang 阅读(9358) 评论(132)  编辑 收藏 引用 所属分类: 嵌入式Linux
评论共2页: 1 2 

评论

# re: 编译内核(Compile the Kernel) 2010-04-15 15:22 老顽童
我碰到USB硬盘上EXT2分区mount不上的问题, 麻烦你看看是不是内核缺少IDE支持?? 但是ntfs fat32都可以挂上去, 搞不懂哪里问题了.

http://1073.konamicn.com/thread-580-1-1.html  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-15 16:00 gouzhuang
@老顽童
ext2的支持根本没有编入内核。我认为系统是有意不支持ext2的,因为ext2文件系统不是日志文件系统(Journaling file system: http://en.wikipedia.org/wiki/Journaling_file_system)。如果ext2文件系统非正常卸载,比如直接拔出usb设备或者直接关闭播放机电源等等,则再次mount时必需要经过fsck才行,而且数据也有可能损坏。日志文件系统就不存在这个问题,ext3文件系统就是这样的文件系统,因此是支持的。建议你使用ext3。
如何创建ext3文件系统?下面两个命令都可以:
1. mke2fs -j /dev/sda1
2. mkfs.ext3 /dev/sda1
用你的设备名替换上面的/dev/sda1  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-16 08:36 老顽童
好,回去试试再来报告
ext2不支持,那么内接硬盘上的ext2怎么能挂上呢?
还有, 这个USB的ext2是在M890上创建的啊,如果内核不支持,应该建不了吧?  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-16 13:53 gouzhuang
@老顽童
USB设备都是通过hotplug程序来mount的,根据hotplug程序的源码来看,它是按下面的顺序尝试挂载的:
1. ufsd 非公开源码的ntfs支持
2. ntfs
3. vfat
4. ext3

而且在尝试ext3时还专门跳过SATA硬盘,不太明白是什么原因。不过我看到的源码也许与你的系统上的不同。

我猜测你的播放机不是通过hotplug来挂载内置盘的,很可能是通过系统初始化脚本来完成的。海信的播放机没有内置盘,因此我无法验证这一点。  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-16 16:30 老顽童
看了下解开的固件, 果然有
-rwxr-xr-x 1 root root 64192 2010-03-10 18:25 hotplug
不是busybox链接.

专门跳过SATA硬盘?? 还好我是IDE的USB盘.


挂载内置盘怎么查呢? rcS 有条是这样的:

#/sbin/modprobe ide-cd
dd if=/Test.fat of=/dev/rd/0
mount -t vfat /dev/rd/0 /mnt/rd
swapon /mnt/rd/swap.img

/sbin/modprobe sata_mars&

这也许是挂内置盘吧? 固件里有:
# ls drivers/scsi/
libata.ko sata_mars.ko

难道要加一个
/sbin/modprobe libata.ko &
来加载内置IDE盘?? 我弄了个IDE的盘在里面, 用转换卡连上STAT接口, 就是挂不上去. 莫非libata.ko没加载??
  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-16 17:11 gouzhuang
@老顽童
看一下你的/etc/fstab里面有没有内置盘的配置  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-16 22:17 老顽童
果然高手!!!指点对路, mount上ext3文件系统了!!!
确实改换成ext3, USB自动加载了, 看来USB系统只会识别FAT,NTFS(?),EXT3. 没有SATA盘,所以无法确定是不是能识别SATA盘.

usb盘如果插拔多次,好象设备号 a b c 会改变,比较讨厌, 呵呵.要想固定mount成/opt, 看来要占住一个USB口了   回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-16 22:31 老顽童
内置盘还是不行, 设备没有识别出来,
/sbin/modprobe sata_mars& 原来已经调进 libata.ko了, 我想的不对,


/etc # cat fstab
# /etc/fstab: static file system information.
#
# <file system> <mount pt> <type> <options> <dump> <pass>
#/dev/root / ext3 rw,noauto 0 1
none /proc proc defaults 0 0
devpts /dev/pts devpts defaults,gid=5,mode=620 0 0
none /sys sysfs defaults 0 0
/dev/mtdblock/2 /usr/local/etc yaffs2 rw,noauto 0 0
none /tmp ramfs defaults 0 0


没有配置内接盘. 内接盘不是随机来的,不是每个人都装的, 所以不会出现在/etc/fstab里. 应该是动态加载的,   回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-18 23:37 gouzhuang
@老顽童
>>内置盘还是不行, 设备没有识别出来
前面你提到内置盘ext2可以挂载,现在又说不行,是我理解错了吗?

另外,关于设备号变化的问题其实很好解决,让内核使用下面这个简单的hotplug脚本(echo 脚本路径 > /proc/sys/kernel/hotplug)。如果usb硬盘的根目录下有名为.optware的文件,则将其bind到/opt

#!/bin/sh

# call /sbin/hotplug first
/sbin/hotplug $1

if [ "$SUBSYSTEM.$ACTION" = "block.add" ] ; then
dev=`basename $DEVPATH`
case "$dev" in
sd[a-z][0-9]*)
if [ -e /tmp/usbmounts/$dev/.optware ] ; then
mount --bind /tmp/usbmounts/$dev /opt
fi
;;
esac
fi   回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-19 11:55 老顽童
关于内接盘是我没说清楚,SORRY
SATA内接盘,EXT2"好象"是可以挂上去的,当时是拿单位的盘来试了下,用了随机的FORMAT,弄的,应该是EXT2, OR EXT3 EXT4吧,现在想不起来了, 不管它, SATA是没问题的.

我折腾的是IDE的内接盘, 机器不识别它, 因为机器只有SATA接口,所以我买了转换器, 把IDE转成STAT接上机器, 根本不识别.  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-19 13:04 gouzhuang
@老顽童
看了一下华硕的内核源码配置,IDE支持是关闭的,相信你的播放机也是一样的。要支持IDE和IDE-SATA转接,至少需要打开下面三个内核配置参数:
CONFIG_IDE
CONFIG_BLK_DEV_IDE
CONFIG_BLK_DEV_IDE_SATA_BRIDGE

你需要重新编译你的内核,或者把上述IDE支持编译成模块。  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-19 13:21 gouzhuang
@老顽童
我编译好了内核IDE驱动模块,你可以试试。有可能我的内核编译配置与你的不兼容,模块无法加载,不过试试也没关系。

下载连接:http://www.cnitblog.com/Files/gouzhuang/ide.tar.zip  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-20 11:14 老顽童
好,晚上试下,谢谢!
还有一事相求, 关于无线网卡的,
M890带来的是WG111v3 Realtek RTL8187B的驱动模块,
我手上的是WG111v2 Realtek RTL8187L, 就这一点区别, 没法工作,一直想重编译下驱动,却不得手, cross compile还是玩不转.
能否麻烦你帮我下?

RTL8187L 驱动软件在这里: http://www.realtek.com/downloads/downloadsView.aspx?Langid=3&PNid=1&PFid=1&Level=6&Conn=5&DownTypeID=3&GetDown=false&Downloads=true#RTL8187L  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-20 14:47 老顽童
好,晚上试下,谢谢!
还有一事相求, 关于无线网卡的,
M890支持的是WG111v3 Realtek RTL8187B的驱动模块,
我手上的是WG111v2 Realtek RTL8187L, 就这一点区别, 没法工作,一直想重编译下驱动,却不得手, cross compile还是玩不转.
能否麻烦你帮我下?

RTL8187L 驱动软件在这里: http://www.realtek.com/downloads/downloadsView.aspx?Langid=3&PNid=1&PFid=1&Level=6&Conn=5&DownTypeID=3&GetDown=false&Downloads=true#RTL8187L  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-20 23:03 老顽童
没成功, 说是找不到文件,
我是放在/lib/modules下面了啊, 怎么/sbin/modprobe 找不到文件呢? 是不是modules.dep之类文件需要更新下??
试了 insmod 也不行.
四个文件应该用那个呢? 我试了四个都不行
  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 08:32 gouzhuang
@老顽童
modprobe依赖于modules.dep, insmod则需要输入模块的完整路径。如果insmod报"Invalid Format"之类的错误,说明模块与现有内核不兼容,需要用与内核兼容的配置来编译模块。

如果你遇到的不是兼容性问题,可以在modules.dep中加入下面几行:
kernel/drivers/ide/ide-cd.ko: kernel/drivers/ide/ide-core.ko
kernel/drivers/ide/ide-generic.ko: kernel/drivers/ide/ide-core.ko
kernel/drivers/ide/ide-disk.ko: kernel/drivers/ide/ide-core.ko
kernel/drivers/ide/ide-core.ko:

支持IDE硬盘以及SATA-IDE转接需要加载ide-disk和ide-generic  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 08:59 everpunk
@gouzhuang
我依葫芦画瓢把你粘的命令都输入上去了,出现的是这个
~ # echo

~ # /proc/sys/kernel/hotplug
-sh: /proc/sys/kernel/hotplug: Permission denied
~ # #!/bin/sh
~ # # call /sbin/hotplug first
~ # /sbin/hotplug $1
~ # if [ "$SUBSYSTEM.$ACTION" = "block.add" ] ; then
> dev=`basename $DEVPATH`
> case "$dev" in
> sd[a-z][0-9]*)
> if [ -e /tmp/usbmounts/$dev/.optware ] ; then
> mount --bind /tmp/usbmounts/$dev /opt
> fi
> ;;
> esac

然后就关闭窗口了,不关电源只是reboot后盘符是没变,不过断了电源之后,盘符又在sda和sdb来回变化了,这是代表没成功吧?错在哪里了呢?  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 09:17 gouzhuang
@everpunk
我给的这段是shell脚本,不是在命令行上直接输入的。把脚本存到一个文件里,比如/sbin/myhotplug。

然后修改属性使其可执行:
chmod +x /sbin/myhotplug

修改系统默认的hotplug程序:
echo /sbin/myhotplug > /proc/sys/kernel/hotplug
注意这只在本次启动有效,系统重启后默认hotplug程序又会恢复原来的。要想在系统启动时自动修改,需要将上面的命令加到系统初始化脚本里(如果不熟悉linux系统最好不要轻易修改,否则可能造成系统无法启动)。

另外,这个脚本的目的不是让盘符不变,它使我们在盘符变化的情况下仍然可以正确的挂载/opt
  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 09:22 gouzhuang
@老顽童
关于帮你编译RTL8187L驱动,最好能确定我的编译环境与你的内核兼容,否则编出来也不能用。所以要先确认IDE模块不能加载的原因。  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 10:28 老顽童
没有报"Invalid Format"之类的错误. 就是cannot found XXX module之类的错误,
奇怪, 用了insmod ./ide-core.ko也不行,看来是要写full path. busybox的modprobe里面没有规定路经选项, 所以我猜modprobe应该是在默认的地方找嘛. 怎么会找不到模块呢? 搞不懂, 难道是因为kernel/drivers/ide是新的path? kernel 没有记录这个路径?

回去修改下modules.dep. 那么, 我是要在rcS里面添加
/sbin/modprobe ide-disk &
/sbin/modprobe ide-generic &
两行吧?
ide-core会有上面两行自动调入, ide-cd我就不需要了.

我觉得普通LINUX,不需要这些设定, 有新硬件, kernel会自动加载模块的,这1283怎么不行呢?  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 10:46 老顽童
@everpunk
我建议你用遥控器按键启动脚本方式,手工mount --bind XXX /opt

就是说, 插进USB后,(应该是EXT3文件系统), 手工按下遥控器例如红键,执行 mount --bind XXX /opt, 然后去执行什么BT下载之类事. 这样烦点, 可是安全.


我前天就是安装mediatomb,修改下/etc/inetd.conf, save, 没注意 整个/etc/inetd.conf被清空了,因为/用了100%, telnet都上不去了, 呵呵, 只好重刷firmware, 正好也要加ide的module上去:-)  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 11:52 gouzhuang
@老顽童
>奇怪, 用了insmod ./ide-core.ko也不行
这个我也觉得奇怪。你能把错误信息帖出来吗?

>我觉得普通LINUX,不需要这些设定, 有新硬件, kernel会自动加载模块的,这1283怎么不行呢?
嵌入式系统做了大量裁剪,易用性方面比不上台式系统。  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 11:59 老顽童
记得先 touch .optware 在USB盘上, 在 http://1073.konamicn.com/thread-534-1-1.html
修改下他的脚本:

if [ "$key" = "a9569f00" ] ; then ##按红键
# echo red
DEV=`find /tmp/usbmounts -maxdepth 2 -name .optware -type f -size 0 -printf %h`
mount --bind $DEV /opt
fi

没在机器上, 可能busybox上的find不接受-printf %h,
用dirname吧
DEV=`dirname \`find /tmp/usbmounts -maxdepth 2 -name .optware -type f -size 0 \` `
mount --bind $DEV /opt

正如gouzhang说的, mount --bind 不是改变挂接点, 而是设备重挂了一次, 一个设备, 两个挂点.

df -k 下, 能看到 /dev/sdb1(很长一串不记得了) 挂在/tmp/usbmounts/sdb1 和 /opt 上了  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 12:01 老顽童
@gouzhuang
没有其他错误, 就是not found. 晚上回去再试试  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 12:56 everpunk
@gouzhuang
见笑啊,高手;我是linux菜鸟一窍不通,怎么把这些命令加成脚本又存到目标位置呢?

现在只会telnet到播放器的IP去输入些命令,请原谅我的啰嗦发问啊,嘿嘿  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 12:59 everpunk
@老顽童
现在就是想实现的终极目标是,按键选择加载swap分区和tr的继续下载或者停止下载。

现在只实现了个tr安装,还不能自己启动,盘符还会变化,好晕啊~

期待两位高手指点啊!谢谢  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 13:53 gouzhuang
@everpunk
>怎么把这些命令加成脚本又存到目标位置呢?
在PC上编辑并保存文件,然后ftp传送到播放机或通过U盘转过去。
如果你的播放机的根目录是可写的,直接复制到目标目录就可以了。如果根是只读的,你可以把它放在/usr/local/etc下面。  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 14:33 everpunk
@gouzhuang
郁闷了,移动硬盘是EXT3格式的,这可怎么办啊?

该不会还要在PC上装ubuto才能解决吧  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 14:43 gouzhuang
@everpunk
>郁闷了,移动硬盘是EXT3格式的,这可怎么办啊?
你总该有个U盘吧,把它格式化成fat32。如果实在想要在windows上访问ext3,可以用ext2fsd http://www.ext2fsd.com/  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 15:24 everpunk
@gouzhuang
明白这个意思了,那是在PC上建个TXT文件?编码另存成unicode还是什么?再登录到播放器的telnet复制到目标位置就行了吧?

还有个问题请教:
在/opt/etc/init.d目录下建立启动脚本 vi /opt/etc/init.d/S50transmission
内容为
#!/bin/sh
/opt/bin/transmission-daemon --paused -t -u root -v toor -g /opt/etc/transmission
(-u root -v toor 这两个参数分别是设定账号和密码)
给S50transmission加上执行权限,以后就能开机自动运行transmission了。
chmod +x S50transmission”

可是输入后显示~ # /opt/etc/init.d
-sh: /opt/etc/init.d: Permission denied

现在开机也不能自动启动TR,不知道是哪里的问题
  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 16:04 gouzhuang
@everpunk
>明白这个意思了,那是在PC上建个TXT文件?编码另存成unicode还是什么?再登录到播放器的telnet复制到目标位置就行了吧?
没错。如果文件内容全是英文,无须另存为unicode。

>可是输入后显示~ # /opt/etc/init.d
>-sh: /opt/etc/init.d: Permission denied
?? /opt/etc/init.d是个目录,不能执行!应该输入/opt/etc/init.d/S50transmission
系统是不会自动执行/opt/etc/init.d下的脚本的。你的/opt是在某个脚本里mount的吧?应该在那个脚本中调用/opt/etc/init.d下的脚本。 可以加入下面的代码来实现:
# Start all init scripts in /opt/etc/init.d
for i in /opt/etc/init.d/S??* ;do
if [ -x $i ] ; then
$i start&
fi
done
  回复  更多评论
  

# re: 编译内核(Compile the Kernel) 2010-04-21 17:35 everpunk
谢谢高手指教!

晚上回去再试试看  回复  更多评论
  

评论共2页: 1 2 
只有注册用户登录后才能发表评论。