-NTFS-3G完整移植+中文支持+自动挂载
1.1进入内核源码目录下:
$make menuconfig
Linux/arm 2.6.37 Kernel Configuration
File systems ---> //NTFS-3G需要依赖用户空间文件系统FUSE的支持
<*> FUSE (Filesystem in Userspace) support
<*>Character device in Userspace support
-*- Native language support ---> //默认语言配置为utf8,并包含一些其他常用语言的编码
(utf8) Default NLS Option
<*> Codepage 437 (United States, Canada)
<*> Simplified Chinese charset (CP936, GB2312)
<*> ASCII (United States)
<*> NLS ISO 8859-1 (Latin 1; Western European Languages)
<*> NLS UTF-8
DOS/FAT/NT Filesystems ---> //这里的NTFS是只读的,不支持写,我们使用NTFS-3G软件包,并且支持读写,所以这里不配置。
< > NTFS file system support
1.2编译生成新的uImage,放入提供tftp服务文件夹下;
$make uImage
$cp arch/arm/boot/uImage /tftpboot
NTFS-3G使用的是时间距离较近的版本,优化了内存占用过多的问题:
2.1解压:
$tar xvf ntfs-3g_ntfsprogs-2016.2.22
2.2进入ntfs-3g源码目录下:
$cd ntfs-3g_ntfsprogs-2016.2.22
2.3编译前配置
$ ./configure --build=i386 --host=arm-arago-linux-gnueabi --prefix=/song/usr --exec-prefix=/song
--build=i386 编译的主机;
--host=arm-arago-linux-gnueabi编译出来的二进制程序所执行的主机;
/song/usr和/song 目录为生成的文件存放位置,可自己定义;
2.4然后就是make && make install;稍等片刻,就可以了。
$make && make install
2.5 /song/bin文件夹下的ntfsfix、ntfs-3g拷贝到nfs文件系统的/bin目录下:
$cp ntfsfix ntfs-3g /DVRRDK_04.00.00.03/target/rfs_816x/bin/
ntfsfix //ntfs硬盘修复工具
ntfs-3g //ntfs硬盘挂载工具
2.6 /song/sbin文件夹下的mkntfs拷贝到nfs文件系统的/sbin目录下:
$cp mkntfs /DVRRDK_04.00.00.03/target/rfs_816x/bin/
mkntfs //格式化分区工具
2.7 /song/lib文件夹下的libntfs-3g.so、libntfs-3g.so.87、libntfs-3g.so.87.0.0
拷贝到nfs文件系统的/lib目录下:
$cp libntfs-3g.so libntfs-3g.so.87 libntfs-3g.so.87.0.0 /DVRRDK_04.00.00.03/target/rfs_816x/bin/
libntfs-3g.so libntfs-3g.so.87 libntfs-3g.so.87.0.0 //动态库
暂时只用到挂载时的ntfs-3g和格式化的mkntfs以及ntfsfix三个工具,注意ntfs-3g需要动态库libntfs-3g.so.87,需要把lib夹中的so一同一起移植过去。
2.8好了,到此ok,我测试了一下:
[root@JHI-SXY:/media]#: ntfs-3g
ntfs-3g: No device is specified.
ntfs-3g 2016.2.22 integrated FUSE 27 - Third Generation NTFS Driver
Configuration type 1, XATTRS are on, POSIX ACLS are off
Copyright (C) 2005-2007 Yura Pakhuchiy
Copyright (C) 2006-2009 Szabolcs Szakacsits
Copyright (C) 2007-2016 Jean-Pierre Andre
Copyright (C) 2009 Erik Larsson
Usage: ntfs-3g [-o option[,...]]
Options: ro (read-only mount), windows_names, uid=, gid=,
umask=, fmask=, dmask=, streams_interface=.
Please see the details in the manual (type: man ntfs-3g).
Example: ntfs-3g /dev/sda1 /mnt/windows
News, support and information: http://tuxera.com
2.9 ntfs-3g可以显示版本,再进行挂载测试:
#ntfs-3g /dev/sda1 /mnt //可以正常挂载,但是不支持中文目录,在后面进行了解决;
#mount -t ntfs-3g /dev/sda1 /mnt //不可以使用,ntfs-3g不是ntfs,无法识别,试了好多方法还是不行,原因可能是busybox的mount的缺陷吧,放弃;最后决定自动挂载时使用ntfs-3g,心累!。
3.1进入Busybox源码目录下,busybox版本是1.19.4
$cd libbb/
$vi printable_string.c
printable_string.c源码修改了红色加粗的代码:
中文是“?”的原因:大于0x7F的字符直接被break掉,或者直接被“?”代替了。所以就算是linux内核设置了支持中文,也是无法显示出来的,被“?”代替了。
1. const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
2. {
3. static char *saved[4];
4. static unsigned cur_saved; /* = 0 */
5.
6. char *dst;
7. const char *s;
8.
9. s = str;
10. while (1) {
11. unsigned char c = *s;
12. if (c == '\0') {
13. /* 99+% of inputs do not need conversion */
14. if (stats) {
15. stats->byte_count = (s - str);
16. stats->unicode_count = (s - str);
17. stats->unicode_width = (s - str);
18. }
19. return str;
20. }
21. if (c < ' ')
22. break;
23. /*
24. if (c >= 0x7f)
25. break;
26. */
27. s++;
28. }
29.
30. #if ENABLE_UNICODE_SUPPORT
31. dst = unicode_conv_to_printable(stats, str);
32. #else
33. {
34. char *d = dst = xstrdup(str);
35. while (1) {
36. unsigned char c = *d;
37. if (c == '\0')
38. break;
39. if (c < ' ' /*|| c >= 0x7f */)
40. *d = '?';
41. d++;
42. }
43. if (stats) {
44. stats->byte_count = (d - dst);
45. stats->unicode_count = (d - dst);
46. stats->unicode_width = (d - dst);
47. }
48. }
49. #endif
50.
51. free(saved[cur_saved]);
52. saved[cur_saved] = dst;
53. cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1);
54.
55. return dst;
56. }
3.2修改unicode.c文件,如果不修改这个,ls命令也是无法显示出中文的。
$vi unicode.c
源代码修改红色加粗的代码:
1. static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags)
2. {
3. char *dst;
4. unsigned dst_len;
5. unsigned uni_count;
6. unsigned uni_width;
7.
8. if (unicode_status != UNICODE_ON) {
9. char *d;
10. if (flags & UNI_FLAG_PAD) {
11. d = dst = xmalloc(width + 1);
12. while ((int)--width >= 0) {
13. unsigned char c = *src;
14. if (c == '\0') {
15. do
16. *d++ = ' ';
17. while ((int)--width >= 0);
18. break;
19. }
20. *d++ = (c >= ' '/* && c < 0x7f */) ? c : '?';
21. src++;
22. }
23. *d = '\0';
24. } else {
25. d = dst = xstrndup(src, width);
26. while (*d) {
27. unsigned char c = *d;
28. if (c < ' '/* || c >= 0x7f */)
29. *d = '?';
30. d++;
31. }
32. }
33. if (stats) {
34. stats->byte_count = (d - dst);
35. stats->unicode_count = (d - dst);
36. stats->unicode_width = (d - dst);
37. }
38. return dst;
39. }
40.
41. dst = NULL;
42. uni_count = uni_width = 0;
43. dst_len = 0;
44. while (1) {
45. int w;
46. wchar_t wc;
47.
48. #if ENABLE_UNICODE_USING_LOCALE
49. {
50. mbstate_t mbst = { 0 };
51. ssize_t rc = mbsrtowcs(&wc, &src, 1, &mbst);
52. /* If invalid sequence is seen: -1 is returned,
53. * src points to the invalid sequence, errno = EILSEQ.
54. * Else number of wchars (excluding terminating L'\0')
55. * written to dest is returned.
56. * If len (here: 1) non-L'\0' wchars stored at dest,
57. * src points to the next char to be converted.
58. * If string is completely converted: src = NULL.
59. */
60. if (rc == 0) /* end-of-string */
61. break;
62. if (rc < 0) { /* error */
63. src++;
64. goto subst;
65. }
66. if (!iswprint(wc))
67. goto subst;
68. }
69. #else
70. src = mbstowc_internal(&wc, src);
71. /* src is advanced to next mb char
72. * wc == ERROR_WCHAR: invalid sequence is seen
73. * else: wc is set
74. */
75. if (wc == ERROR_WCHAR) /* error */
76. goto subst;
77. if (wc == 0) /* end-of-string */
78. break;
79. #endif
80. if (CONFIG_LAST_SUPPORTED_WCHAR && wc > CONFIG_LAST_SUPPORTED_WCHAR)
81. goto subst;
82. w = wcwidth(wc);
83. if ((ENABLE_UNICODE_COMBINING_WCHARS && w < 0) /* non-printable wchar */
84. || (!ENABLE_UNICODE_COMBINING_WCHARS && w <= 0)
85. || (!ENABLE_UNICODE_WIDE_WCHARS && w > 1)
86. ) {
87. subst:
88. wc = CONFIG_SUBST_WCHAR;
89. w = 1;
90. }
91. width -= w;
92. /* Note: if width == 0, we still may add more chars,
93. * they may be zero-width or combining ones */
94. if ((int)width < 0) {
95. /* can't add this wc, string would become longer than width */
96. width += w;
97. break;
98. }
99.
100. uni_count++;
101. uni_width += w;
102. dst = xrealloc(dst, dst_len + MB_CUR_MAX);
103. #if ENABLE_UNICODE_USING_LOCALE
104. {
105. mbstate_t mbst = { 0 };
106. dst_len += wcrtomb(&dst[dst_len], wc, &mbst);
107. }
108. #else
109. dst_len += wcrtomb_internal(&dst[dst_len], wc);
110. #endif
111. }
112.
113. /* Pad to remaining width */
114. if (flags & UNI_FLAG_PAD) {
115. dst = xrealloc(dst, dst_len + width + 1);
116. uni_count += width;
117. uni_width += width;
118. while ((int)--width >= 0) {
119. dst[dst_len++] = ' ';
120. }
121. }
122. dst[dst_len] = '\0';
123. if (stats) {
124. stats->byte_count = dst_len;
125. stats->unicode_count = uni_count;
126. stats->unicode_width = uni_width;
127. }
128.
129. return dst;
130. }
经过以上修改之后,就算配置支持Unicode,ls命令也是可以支持中文的。同时也可以进入中文目录可以文件夹。
3.3进入busybox源码目录下,配置支持Unicode:
$make menuconfig
Busybox Configuration
Busybox Settings --->
General Configuration --->
[*] Support Unicode
[*] Check $LANG environment variable
(63) Character code to substitute unprintable characters with
(767) Range of supported Unicode characters
[ ] Allow zero-width Unicode characters on output
[*] Allow wide Unicode characters on output
3.4编译生成新的busybox,拷贝到nfs文件系统/bin文件夹下;
$make && make install
$cp _install/bin/busybox /DVRRDK_04.00.00.03/target/rfs_816x/bin/
测试
[root@JHI-SXY:/media/sda1]#:ls ls
2.txt 新建 Microsoft Word 文档.docx
System Volume Information 新建文本文档123.txt
我主要是针对mount -t ntfs-3g /dev/sda1 /mnt 不可以使用,在网上找了找论坛,发现都是讲mdev;但我的内核Linux/arm 2.6.37 Kernel,支持udev。
udev的规则文件以行为单位,以”#”开头的行代表注释行。其余的每一行代表一个规则。每个规则分成一个或多个“匹配”和“赋值”部分。“匹配”部分用“匹配“专用的关键字来表示,相应的“赋值”部分用“赋值”专用的关键字来表示。“匹配”关键字包括:ACTION,KERNEL,BUS,SYSFS等等,“赋值”关键字包括:NAME,SYMLINK,OWNER等等。具体详细的描述可以阅读udev的man文档。
下面举个例子来说明一下,有这样一条规则:SUBSYSTEM==”net”, ACTION==”add”, SYSFS{address}==”00:0d:87:f6:59:f3″, IMPORT=”/sbin/rename_netiface %k eth0″
这个规则中的“匹配”部分有三项,分别是SUBSYSTEM,ACTION和SYSFS。而”赋值”部分有一项,是IMPORT。这个规则就是说,当系统中出现的新硬件属于net子系统范畴,系统对该硬件采取的动作是加入这个硬件,且这个硬件在SYSFS文件系统中的“address”信息等于“00:0d…”时,对这个硬件在udev层次施行的动作是调用外部程序/sbin/rename_netiface,传递的参数有两个,一个是“%k”,代表内核对该新设备定义的名称。另一个是”eth0“。 从上面这个例子中可以看出,udev的规则的写法比较灵活的,尤其在“匹配”部分中,可以通过诸如”*“, ”?“,[a-c],[1-9]等shell通配符来灵活匹配多个匹配项。具体的语法可以参考udev的man文档。
4.1找到规则文件
$vi /DVRRDK_04.00.00.03/target/rfs_816x/etc/udev/rules.d/local.rules
找到块设备的挂载规则如下:
# media automounting
SUBSYSTEM=="block", ACTION=="add" RUN+="/etc/udev/scripts/mount.sh"
SUBSYSTEM=="block", ACTION=="remove" RUN+="/etc/udev/scripts/mount.sh"
4.2打开mount.sh文件修改。
红色部分为修改的,目的是:
if mount -t auto -o utf8 /设备文件 /挂载目录
else ntfs-3g -o utf8 /设备文件 /挂载目录
$vi mount.sh
#!/bin/sh
#
# Called from udev
#
# Attempt to mount any added block devices and umount any removed devices
MOUNT="/bin/mount"
PMOUNT="/usr/bin/pmount"
UMOUNT="/bin/umount"
NTFS="/bin/ntfs-3g"
for line in `cat /etc/udev/mount.blacklist`
do
if [ ` expr match "$DEVNAME" "$line" ` -gt 0 ];
then
logger "udev/mount.sh" "[$DEVNAME] is blacklisted, ignoring"
exit 0
fi
done
automount() {
name="`basename "$DEVNAME"`"
! test -d "/media/$name" && mkdir -p "/media/$name"
if $MOUNT -t auto -o utf8 $DEVNAME "/media/$name"
then
logger "mount.sh/automount" "Auto-mount of [/media/$name] successful"
touch "/tmp/.automount-$name"
elif $NTFS -o utf8 $DEVNAME "/media/$name"
then
logger "mount.sh/ntfs-3g" "Auto-mount of [/media/$name] successful"
touch "/tmp/.automount-$name"
else
#logger "mount.sh/automount" "$MOUNT -t auto $DEVNAME \"/media/$name\" failed!"
rm_dir "/media/$name"
fi
}
rm_dir() {
# We do not want to rm -r populated directories
if test "`find "$1" | wc -l | tr -d " "`" -lt 2 -a -d "$1"
then
! test -z "$1" && rm -r "$1"
else
logger "mount.sh/automount" "Not removing non-empty directory [$1]"
fi
}
if [ "$ACTION" = "add" ] && [ -n "$DEVNAME" ]; then
if [ -x "$PMOUNT" ]; then
$PMOUNT $DEVNAME 2> /dev/null
elif [ -x $MOUNT ]; then
$MOUNT $DEVNAME 2> /dev/null
fi
# If the device isn't mounted at this point, it isn't configured in fstab
grep -q "^$DEVNAME " /proc/mounts || automount
fi
if [ "$ACTION" = "remove" ] && [ -x "$UMOUNT" ] && [ -n "$DEVNAME" ]; then
for mnt in `cat /proc/mounts | grep "$DEVNAME" | cut -f 2 -d " " `
do
$UMOUNT $mnt
done
# Remove empty directories from auto-mounter
name="`basename "$DEVNAME"`"
test -e "/tmp/.automount-$name" && rm_dir "/media/$name"
Fi
保存退出测试一下,ok,能自动挂载了,并且FAT32U盘的文件也可以支持中文了。