arm開發板的NTFS-3G完整移植+中文目錄支援+自動掛載(udev)
-NTFS-3G完整移植+中文支援+自動掛載
1核心裁剪
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
2 NTFS-3G完整移植
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,我測試了一下:
[[email protected]:/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[,...]] <device|image_file> <mount_point>
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中文支援
這裡採用了這位博主的方法:http://blog.csdn.net/wavemcu/article/details/72029083.1進入Busybox原始碼目錄下,busybox版本是1.19.4
$cd libbb/
$vi printable_string.c
printable_string.c原始碼修改了紅色加粗的程式碼:
中文是“?”的原因:大於0x7F的字元直接被break掉,或者直接被“?”代替了。所以就算是linux核心設定了支援中文,也是無法顯示出來的,被“?”代替了。
1. constchar* FAST_FUNC printable_string(uni_stat_t *stats, constchar *str)
2. {
3. staticchar *saved[4];
4. static unsigned cur_saved; /* = 0 */
5.
6. char *dst;
7. constchar *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. staticchar* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, constchar *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/
測試
[[email protected]:/media/sda1]#:ls ls
2.txt 新建 Microsoft Word 文件.docx
System Volume Information 新建文字文件123.txt
4自動掛載
我主要是針對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盤的檔案也可以支援中文了。