工具:
雲端HDD (密碼放在說明裡), 可到M$去下載
前言:
因為要把 Windows XP裡的Outlook Express 郵件 copy到新電腦的 Office Outlook 中....
直接用XP的Outlook Express匯出, 會一直出現啥 MAPI 錯誤..
而新電腦又不能裝 Outlook Express (因為Win7沒有, 這時要OOXX一下M$)
偏偏Office Outlook的檔案匯入又沒法匯入dbx檔...
作法:
從Outlook Express中把要匯出的郵件檔 copy 到一個資料夾,
然後安裝這個程式 (沒法直接轉)
得再安裝 dbx2pst 或 dbxtopst converter 程式才能轉.. (都是搶錢軟體, 沒錢只能轉幾封信)
不過...
我是直接安裝 Office 2007(這是坑錢軟體) 用匯入的方式將Outlook Express檔
先匯進Office Outlook 2007 裡
再將Office Outlook 2007的pst 檔 copy到新電腦匯入....
2015年5月18日 星期一
2015年4月22日 星期三
為什麼 vdso.so.1 是空的?
以下摘錄自 http://codex.wiki/post/135102-931/ :
VDSO就是Virtual Dynamic Shared Object,就是 Kernel 提供的虛擬的.so,這個.so文件不在磁碟上,而是在 Kernel 裡頭。Kernel 把包含某.so的內存頁在程序啟動的時候映射入其內存空間, 對應的程序就可以當普通的.so來使用裡頭的函數。比如syscall()這個函數就是在linux-vdso.so.1裡頭的,但是磁碟上並沒有對應的 文件.可以通過ldd/bin/bash看看。
這樣,隨 kenel 發行的 libc就唯一的和一個特定版本的 kernel 綁定到一起了。注意,VDSO只是隨 kernel 發行,沒有在 kernel 空間運行,這個不會導致 kernel 膨脹。這樣 kernel 和 libc 都不需為能相容多個不同版本而寫太多的代碼,甚至引入太多的bug了。
當然,libc不單單有到 kernel 的介面,還有很多常用的函數,這些函數不需要特別的為不同版本的 kernel 小心編寫,所以,我估計Linux上會出現兩個 libc, 一個 libc在 kernel,只是系統調用的package,另一個 libc還是普通的 libc,只是這個 libc再也不需要花精力去配合如此繁多的kernel了。
姑且一個叫 kernellibc,一個叫 glibc:printf() 這些的還在 glibc。open(),read(),write(),socket()這些卻不再是glibc的了,他們在kernellibc。
Linux 下傳統的系統調用是通過軟中斷(0x80)實現的,在一個Kernel.org的郵件列表中,有一封郵件討論了「"Intel P6 vs P7 system call performance」,最後得出的結論是採用傳統的int 0x80的系統調用浪費了很多時間,而sysenter/sysexit可以彌補這個缺點,所以才最終決定在linux kernel 中用後都替換前者(最終在 2.6版本的 kernel 中才加入了此功能,即採用sysenter/sysexit)。
如何用替換sysenter/sysexit替換以前的 int 0x80呢?linux kenerl 需要考慮到這點:有的機器並不支持sysenter/sysexit,於是它跟glibc說好了,「你以後調用系統調用的時候就從我給你的這個地址調用, 這個地址指向的內容要麼是int 0x80調用方式,要麼是sysenter/sysexit調用方式,我會根據機器來選擇其中一個」(kernel與glibc的配合是如此的默契),這 個地址便是vsyscall的首地址。
可以將vdso看成一個shared objdect file(這個文件實際上不存在),kernel 將其映射到某個地址空間,被所有程序所共享。(我覺得這裡用到了一個技術:多個虛擬頁面映射到同一個物理頁面。即 kernle 把 vdso 映射到某個物理頁面上,然後所有程序都會有一個頁表項指向它,以此來共享,這樣每個程序的vdso地址就可以不相同了)
這個後來常用在 32bit 程式跑在 64 bit kernel, 或是 64bit 程式跑在32 bit kernel 中...
可使用下列方式查看~
例如: lmgrd (程式名)
:pts/0)$ ls -l lmgrd
-rwxrwxr-x 1 root root 1509320 Apr 22 10:31 lmgrd
pts/0)$ readelf -h lmgrd
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x4050a0
Start of program headers: 64 (bytes into file)
Start of section headers: 1507336 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 8
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 30
pts/0)$ ldd lmgrd
linux-vdso.so.1 => (0x00007fff945d3000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc7888f8000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc7885fc000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc7883e5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc788026000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc787e22000)
/lib64/ld-lsb-x86-64.so.3 => /lib64/ld-linux-x86-64.so.2 (0x00007fc788b35000)
有沒有發現, 其中 linux-vdso.so.1 是指到一個未知的函式庫..
這個 linux-vdso.so.1 可是找不到套件可安裝的.. 因為它打一開始就不存在 (為虛擬的)
如果, 在執行程式時發生:
"-bash: lmgr no such file or directory" 的情況.. (已確認存在且可執行, 而且用絕對路徑也一樣)
應該就是 linux-vdso.so.1 的對映出問題了,
您可是試著安裝 lsb 或 lsb-core 來解決
apt-get install lsb 或 apt-get install lsb-core
不過要有時會出現相依性問題, 那就得自行去下載相關套件安裝了
http://packages.ubuntu.com/search?suite=default§ion=all&arch=any&keywords=lsb-core&searchon=names
以我的小桌機 Ubuntu 12.04 (Linux 3.11.0-24) 來說, 要安裝( dpkg -i *.deb) 以下:
alien_8.86_all.deb
intltool-debian_0.35.0+20060710.1_all.deb
lsb-release_4.0-0ubuntu20_all.deb
debhelper_9.20120115ubuntu3_all.deb
libgettextpo0_0.18.1.1-5ubuntu3_amd64.deb
ncurses-term_5.9-4_all.deb
dh-apparmor_2.7.102-0ubuntu3.10_all.deb
libunistring0_0.9.3-5_amd64.deb
pax_20120216-1_amd64.deb
gettext_0.18.1.1-5ubuntu3_amd64.deb
lsb-base_4.0-0ubuntu20_all.deb
po-debconf_1.0.16+nmu2ubuntu1_all.deb
html2text_1.3.2a-15_amd64.deb
lsb-core_4.0-0ubuntu20_amd64.deb
VDSO就是Virtual Dynamic Shared Object,就是 Kernel 提供的虛擬的.so,這個.so文件不在磁碟上,而是在 Kernel 裡頭。Kernel 把包含某.so的內存頁在程序啟動的時候映射入其內存空間, 對應的程序就可以當普通的.so來使用裡頭的函數。比如syscall()這個函數就是在linux-vdso.so.1裡頭的,但是磁碟上並沒有對應的 文件.可以通過ldd/bin/bash看看。
這樣,隨 kenel 發行的 libc就唯一的和一個特定版本的 kernel 綁定到一起了。注意,VDSO只是隨 kernel 發行,沒有在 kernel 空間運行,這個不會導致 kernel 膨脹。這樣 kernel 和 libc 都不需為能相容多個不同版本而寫太多的代碼,甚至引入太多的bug了。
當然,libc不單單有到 kernel 的介面,還有很多常用的函數,這些函數不需要特別的為不同版本的 kernel 小心編寫,所以,我估計Linux上會出現兩個 libc, 一個 libc在 kernel,只是系統調用的package,另一個 libc還是普通的 libc,只是這個 libc再也不需要花精力去配合如此繁多的kernel了。
姑且一個叫 kernellibc,一個叫 glibc:printf() 這些的還在 glibc。open(),read(),write(),socket()這些卻不再是glibc的了,他們在kernellibc。
Linux 下傳統的系統調用是通過軟中斷(0x80)實現的,在一個Kernel.org的郵件列表中,有一封郵件討論了「"Intel P6 vs P7 system call performance」,最後得出的結論是採用傳統的int 0x80的系統調用浪費了很多時間,而sysenter/sysexit可以彌補這個缺點,所以才最終決定在linux kernel 中用後都替換前者(最終在 2.6版本的 kernel 中才加入了此功能,即採用sysenter/sysexit)。
如何用替換sysenter/sysexit替換以前的 int 0x80呢?linux kenerl 需要考慮到這點:有的機器並不支持sysenter/sysexit,於是它跟glibc說好了,「你以後調用系統調用的時候就從我給你的這個地址調用, 這個地址指向的內容要麼是int 0x80調用方式,要麼是sysenter/sysexit調用方式,我會根據機器來選擇其中一個」(kernel與glibc的配合是如此的默契),這 個地址便是vsyscall的首地址。
可以將vdso看成一個shared objdect file(這個文件實際上不存在),kernel 將其映射到某個地址空間,被所有程序所共享。(我覺得這裡用到了一個技術:多個虛擬頁面映射到同一個物理頁面。即 kernle 把 vdso 映射到某個物理頁面上,然後所有程序都會有一個頁表項指向它,以此來共享,這樣每個程序的vdso地址就可以不相同了)
這個後來常用在 32bit 程式跑在 64 bit kernel, 或是 64bit 程式跑在32 bit kernel 中...
可使用下列方式查看~
例如: lmgrd (程式名)
:pts/0)$ ls -l lmgrd
-rwxrwxr-x 1 root root 1509320 Apr 22 10:31 lmgrd
pts/0)$ readelf -h lmgrd
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x4050a0
Start of program headers: 64 (bytes into file)
Start of section headers: 1507336 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 8
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 30
pts/0)$ ldd lmgrd
linux-vdso.so.1 => (0x00007fff945d3000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc7888f8000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc7885fc000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc7883e5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc788026000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc787e22000)
/lib64/ld-lsb-x86-64.so.3 => /lib64/ld-linux-x86-64.so.2 (0x00007fc788b35000)
有沒有發現, 其中 linux-vdso.so.1 是指到一個未知的函式庫..
這個 linux-vdso.so.1 可是找不到套件可安裝的.. 因為它打一開始就不存在 (為虛擬的)
如果, 在執行程式時發生:
"-bash: lmgr no such file or directory" 的情況.. (已確認存在且可執行, 而且用絕對路徑也一樣)
應該就是 linux-vdso.so.1 的對映出問題了,
您可是試著安裝 lsb 或 lsb-core 來解決
apt-get install lsb 或 apt-get install lsb-core
不過要有時會出現相依性問題, 那就得自行去下載相關套件安裝了
http://packages.ubuntu.com/search?suite=default§ion=all&arch=any&keywords=lsb-core&searchon=names
以我的小桌機 Ubuntu 12.04 (Linux 3.11.0-24) 來說, 要安裝( dpkg -i *.deb) 以下:
alien_8.86_all.deb
intltool-debian_0.35.0+20060710.1_all.deb
lsb-release_4.0-0ubuntu20_all.deb
debhelper_9.20120115ubuntu3_all.deb
libgettextpo0_0.18.1.1-5ubuntu3_amd64.deb
ncurses-term_5.9-4_all.deb
dh-apparmor_2.7.102-0ubuntu3.10_all.deb
libunistring0_0.9.3-5_amd64.deb
pax_20120216-1_amd64.deb
gettext_0.18.1.1-5ubuntu3_amd64.deb
lsb-base_4.0-0ubuntu20_all.deb
po-debconf_1.0.16+nmu2ubuntu1_all.deb
html2text_1.3.2a-15_amd64.deb
lsb-core_4.0-0ubuntu20_amd64.deb
2015年4月9日 星期四
Linux: xargs 指令範例與教學
原文在此
在 UNIX/Linux 系統中,xargs 這個指令跟其他的指令結合之後,將會變得非常有用,這裡整理了一些常見的 xargs 使用範例與教學,透過這些簡單的範例可以很快的了解 xargs 的各種使用方式。
雖然這裡的範例都很簡單,但是當你了解 xargs 的用法之後,你會發現 xargs 其實可以拿來處理各式各樣的問題,而且非常好用,尤其是對於伺服器的系統管理者而言,在管理大量的檔案與目錄結構時,有這樣的工具會方便很多。
$ xargs
接著在終端機中輸入
arg1 arg2
arg3
結束時按下 Ctrl + d,這時候 xargs 就會把輸入的兩行資料切割成 3 個字串(分別為 arg1、arg2 與 arg3),接著把這三個字串當作指定指令的參數,而這裡我們沒有指定任何指令,所以預設會使用 /bin/echo,直接把三個字串輸出至終端機中。
arg1 arg2 arg3
這裡雖然輸入的資料中有包含一個換行字元(\n),不過因為 xargs 預設不會保留換行字元,所以整個輸出就變成一整行。這個效果相當於
如果要指定 xargs 所要執行的指令,可以直接將指令的名稱放在所有 xargs 的參數之後,例如
在 UNIX/Linux 系統中,xargs 這個指令跟其他的指令結合之後,將會變得非常有用,這裡整理了一些常見的 xargs 使用範例與教學,透過這些簡單的範例可以很快的了解 xargs 的各種使用方式。
雖然這裡的範例都很簡單,但是當你了解 xargs 的用法之後,你會發現 xargs 其實可以拿來處理各式各樣的問題,而且非常好用,尤其是對於伺服器的系統管理者而言,在管理大量的檔案與目錄結構時,有這樣的工具會方便很多。
xargs 基本用法
xargs 這個指令會標準輸入(standard input)讀取資料,並以空白字元或換行作為分隔,將輸入的資料切割成多個字串,並將這些字串當成指定指令(預設為 /bin/echo)執行時的參數。如果直接執行$ xargs
接著在終端機中輸入
arg1 arg2
arg3
結束時按下 Ctrl + d,這時候 xargs 就會把輸入的兩行資料切割成 3 個字串(分別為 arg1、arg2 與 arg3),接著把這三個字串當作指定指令的參數,而這裡我們沒有指定任何指令,所以預設會使用 /bin/echo,直接把三個字串輸出至終端機中。
arg1 arg2 arg3
這裡雖然輸入的資料中有包含一個換行字元(\n),不過因為 xargs 預設不會保留換行字元,所以整個輸出就變成一整行。這個效果相當於
/bin/echo arg1 arg2 arg3
xargs 在讀取標準輸入的資料時,會自動忽略空白行,多餘的空白或是 tab 字元也會自動被忽略。如果要指定 xargs 所要執行的指令,可以直接將指令的名稱放在所有 xargs 的參數之後,例如
xargs cat
arg1 arg2
arg3
就相當於cat arg1 arg2 arg3
指定分隔字元
如果要指定 xargs 在讀取標準輸入時所使用的分隔字元,可以使用 -d 這個參數。例如:xargs -d\n arg1 arg2 arg3
輸出為arg1 arg2
arg3
這裡當我們使用 -d 這個參數指定分隔字元時,xargs 就會將換行字元保留下來,所以輸出會分為兩行。
參數個數上限
預設的狀況下,xargs 會把從標準輸入的資料所分割出來的字串,一次全部都放進指定指令參數中,例如:echo a b c d e f | xargs
就相當於echo a b c d e f
所以輸出為
a b c d e f
如果我們不想讓所有的參數都放進一個指令中指令中執行,可以使用 -n 參數來指定每一次執行指令所使用的參數個數上限值,例如echo a b c d e f | xargs -n 3
就相當於echo a b c echo d e f
所以輸出就變為
a b c
d e f
如果指定上限為 2:echo a b c d e f | xargs -n 2
輸出就會變成
a b
c d
e f
執行前的確認
如果你對於 xargs 的使用方式不是很熟悉,或是需要以 root 權限執行一些不容出錯的指令,可以加上 -p 參數,讓指令在實際執行指令之前可以先進行確認的動作。例如:echo a b c d e f | xargs -p -n 3
則在每一行指令執行前,都會先確認,如果要執行就輸入 y,若不執行則輸入 n,假設每一個指令我們都輸入 y讓它執行,則整個輸出就會變成這樣:
/bin/echo a b c ?...y
/bin/echo d e f ?...a b c
y
d e f
這裡因為 xargs 的確認訊息與 echo 指令的輸出混在一起,所以看起來有點奇怪。 如果所有的指令進行確認時,我們都輸入 n,這樣就不會執行任何的 echo 指令,輸出就會像這樣: /bin/echo a b c ?...n
/bin/echo d e f ?...n
/bin/echo ?...n
忽略空字串參數
大家應該有注意到上面的例子當我們使用 -p 參數時,如果所有的指令都輸入 n 跳過不執行時,最後還會出現一個沒有任何參數的 echo 指令,如果想要避免以這種空字串作為參數來執行指令,可以加上 -r 參數:echo a b c d e f | xargs -p -n 3 -r
/bin/echo a b c ?...n
/bin/echo d e f ?...n
如果標準輸入為空字串時,xargs 預設還是會執行一次 echo 指令:xargs -p
/bin/echo ?...n
這種狀況同樣可以加上 -r 參數:xargs -p -r
顯示執行的指令
使用 -t 參數可以讓 xargs 在執行指令之前先顯示要執行的指令,這樣可以讓使用者知道 xargs 執行了哪些指令。xargs -t abcd
按下 Ctrl + d 之後,xargs 就會先輸出要執行的指令內容,接著才是實際指令執行的輸出,最後得到輸出為/bin/echo abcd
abcd
結合 xargs 與 find 指令
xargs 本身的功能並不多,但是他跟其他的 Linux 指令一起搭配使用時,功能就會顯得很強大。 與 find 指令合在一起使用是 xargs 的一項非常重要的功能,它可以讓你找尋特定的檔案,並且進行特定的處理動作。 假設我們有一些資料夾,其中包含各式各樣的檔案,以 tree 指令查看目錄結構會呈現假設我們想要找出目前路徑之下的所有 .c 檔案,並且將其刪除,就可以使用. ├── folder1 │ ├── file1.c │ ├── file1.h │ ├── file2.c │ └── file2.h └── folder2 ├── file3.c └── file3.h 2 directories, 6 filesfind . -name "*.c" | xargs rm -f
這裡我們將 xargs 要執行的指令指定為 rm -f,讓 find 所找到的 .c 檔案都當成 rm -f 的參數,所以其指令的效果就相當於rm -f ./folder2/file3.c ./folder1/file2.c ./folder1/file1.c
如果你對於指令的操作還不是很熟悉,也可以配合上面介紹的 -p 參數,在執行前確認一下find . -name "*.c" | xargs -p rm -f
刪除 .c 檔案之後,以 tree 指令查看整個目錄樹就會變成這裡因為是示範用的例子,所以並沒有建立太多的檔案與目錄結構,在實際的應用上,當整個目錄結構很複雜、檔案又很多的時候,使用這樣的方式就會非常有效率。. ├── folder1 │ ├── file1.h │ └── file2.h └── folder2 └── file3.h 2 directories, 3 files包含空白的檔案名稱
假設我們的目錄中有一些檔名包含空白字元:touch "G T Wang.c"
在這種狀況下如果用上面 find 與 xargs 的方式會無法將其刪除,原因在於當我們執行find . -name "*.c" | xargs rm -f
的時候,xargs 所產生的指令為rm -f ./G T Wang.c
因為檔名包含空白,所以這會會造成 rm 指令無法正確刪除該檔案。 這個時候我們可以將 find 指令加上 -print0 參數,另外將 xargs 指令加上 -0 參數,改成這樣find . -name "*.c" -print0 | xargs -0 rm -rf
如此一來,即可正確處理包含空白字元的檔案名稱。命令列長度的限制
使用 --show-limits 參數可以查看系統對於命令列長度的限制,這些限制會跟 xargs 的運作情況有關,如果要處理很大量的資料時,這些限制要注意一下。xargs --show-limits
輸出為
Your environment variables take up 2022 bytes
POSIX upper limit on argument length (this system): 2093082
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2091060
Size of command buffer we are actually using: 131072
Execution of xargs will continue now, and it will try to read its input
and run commands; if this is not what you wanted to happen, please type
the end-of-file keystroke.
Warning: /bin/echo will be run at least once. If you do not want that to happen, then press the interrupt keystroke.結合 xargs 與 grep 指令
xargs 與 grep 兩個指令的合併也是一個很常見的使用方式,它可以讓你找尋特定檔案之後,進而搜尋檔案的內容。 假設我們要在所有的 .c 檔案中搜尋 stdlib.h 這個字串,就可以使用find . -name '*.c' | xargs grep 'stdlib.h'
我直接拿 VTK 的原始碼來測試,輸出會像這樣
./CMake/TestOggTheoraSubsampling.c:#include <stdlib.h>
./Wrapping/Tools/lex.yy.c:#include <stdlib.h>
./Wrapping/Tools/vtkWrapPythonInit.c:#include <stdlib.h>
./Wrapping/Tools/vtkWrapTcl.c:#include <stdlib.h>
./Wrapping/Tools/vtkWrapTclInit.c:#include <stdlib.h>
./Wrapping/Tools/vtkParsePreprocess.c:#include <stdlib.h>
./Wrapping/Tools/vtkWrapText.c:#include <stdlib.h>
./Wrapping/Tools/vtkParseData.c:#include <stdlib.h>
./Wrapping/Tools/vtkParseHierarchy.c:#include <stdlib.h>
./Wrapping/Tools/vtkParseMain.c:#include <stdlib.h>
[略] 這個對於程式設計師在看一堆專案原始碼的時候特別有用。
Linux 搜尋並取代 (某些文件裡面的某個字串)
原文: 原文在此
== 結論的好方法 ==
情境 ex1:將資料夾內 case01.conf ~ case99.conf 裡的
senor 錯字改成 sensor
find *.conf | xargs -i sed -i 's/senor/sensor/g' {}
find *.conf 會找資料夾內的 .conf 檔,
即情境中的 case01.conf ~ case99.conf,輸出為 99 行;
| 是 pipe 指令,能將前者的 standard output,
作為後者的 standard input 繼續處理;
(這裡有兩個 point,一是前一個指令的 standard error 會被忽略,
二是後一個指令必需是處理 standard input 的指令)
xargs 的目的,是用來將所得的結果參數化,
即我們會將前者的 standard output,當作接下來指令的某個參數。
其中,透過 xargs -i {},
我們可以將前者 n行輸出的每一行,視為一次輸出,
將其擺至 {} 的位置,而得到 n 次輸入執行 n 遍。
(若不使用 xargs -i {},則會把前面 n行的 output 一次全丟給後者)
也就是說
find *.conf | xargs -i sed -i 's/senor/sensor/g' {}
至此會等同於
sed 's/senor/sensor/g' case01.conf
sed 's/senor/sensor/g' case02.conf
…
sed 's/senor/sensor/g' case99.conf
而 sed 的格式是
sed 'command' filename,
command 跟 regular expression 有關,
總之,這個例子的意思是,
尋找 filename 檔案中的所有 senor 字串,並取代為 sensor 字串。
情境 ex2:1test1、1test2 … 24test5、24test6 內,
有些字串是 2.6.16,有些是 2a6b16,
欲將 2.6.16 改為 2.6.28
find *test* | xargs -i sed -i 's/2\.6\.16/2\.6\.28/g' {}
ex2 的寫法在底下對 vim 的討論有詳細的解釋,
== 對單一檔案的解法 ==
假設要將 filename 檔案裡的 2009 改成 2010
vim 解法 (後面有詳細的討論,與不知如何解的問題)
vim -c '1,$s/2009/2010/g' -c ':wq' filename
或是 vim 檔案後,直接按 :
輸入 1,$s/2009/2010/g 的指令。
sed 解法 (速度快,效果好)
sed -i 's/2009/2010/g' file
有新版的 GNU sed 即可用上面的解法,
舊版的可能要
sed 's/2009/2010/g' oldfile > tmpfile; mv tmpfile oldfile
perl 解法 (我不懂 perl,還不會讓其搜尋檔案並操作)
1. 建 xxx.pl 檔,寫一行指令,
2. perl -pi -e "s/2009/2010/g" filename
3. chmod 755 xxx.pl 使其可執行後,
4. 下 ./xxx.pl 執行
== 舊的 vim 的討論 ==
目的:
把 fullset-k26.mak 裡的 2.6.16 全部取代成 2.6.28
指令:
vim -c ':1,$s/2\.6\.16/2\.6\.28/g' fullset-k26.mak
== vim 的 解釋 ==
vim -c command file
這裡有兩個部份要注意,
一個是 "vim -c command file" 整段是 command line 的命令,
有些特殊字元在 command line 有別的意義,
另一個是 "command" 本身是要傳給 vim 的命令,
要符合 regular expression 的用法。
因為 command line 中, $ 會被視為呼叫變數,
所以需用 \$ 或是 '$' 來表示 $ 是傳給 vim 的 regular expression
(在 reqular expression 中, $ 代表 檔尾 or 行尾,
例如 1,$s/x$/l,第一個$是檔尾,第二個$是行尾)
在此是整串 command 都用 ' ' 括住比較方便 (因為後面還有 . 要注意)
在regular expression的 . 代表非斷行的任意字元
所以為了確保不會有 2a6b28 被取代掉,
所以在 vim 的 command 中要用 \. 來表示是 2.6 而非 2a6 之類的任意字元
而在 command line 中,應該用 \\. 或是 '\.' 代表要傳 \. 給 vim
(如果是 \.,會把 \ 忽略認為要傳 . 給 vim,vim 會認為 . 代表任意字元
所以是 \\. ,認為要傳 \. 給 vim,讓 vim 找 . 這個字元)
也就是上述的命令等同於
vim -c :1,\$s/2\\.6\\.16/2\\.6\\.28/g fullset-k26.mak
不過,還是用括號括比較方便
也就是一開頭的
vim -c ':1,$/2\.6\.16/2\.6\.28/g' fullset-k26.mak
然後,不再接一個 -c ':wq' 的指令,
他會把檔案開啟來,並把 2.6.16 取代成 2.6.28 後,仍未存檔,
好處是可以檢查無誤後再存檔。
== vim 的 問題 ==
與 find *.conf | xargs -i {} 合在一起用時,如:
find *.conf | xargs -i vim -c '1,$s/senor/sensor/g' -c ':wq' {}
最後會當掉。
== 結論的好方法 ==
情境 ex1:將資料夾內 case01.conf ~ case99.conf 裡的
senor 錯字改成 sensor
find *.conf | xargs -i sed -i 's/senor/sensor/g' {}
find *.conf 會找資料夾內的 .conf 檔,
即情境中的 case01.conf ~ case99.conf,輸出為 99 行;
| 是 pipe 指令,能將前者的 standard output,
作為後者的 standard input 繼續處理;
(這裡有兩個 point,一是前一個指令的 standard error 會被忽略,
二是後一個指令必需是處理 standard input 的指令)
xargs 的目的,是用來將所得的結果參數化,
即我們會將前者的 standard output,當作接下來指令的某個參數。
其中,透過 xargs -i {},
我們可以將前者 n行輸出的每一行,視為一次輸出,
將其擺至 {} 的位置,而得到 n 次輸入執行 n 遍。
(若不使用 xargs -i {},則會把前面 n行的 output 一次全丟給後者)
也就是說
find *.conf | xargs -i sed -i 's/senor/sensor/g' {}
至此會等同於
sed 's/senor/sensor/g' case01.conf
sed 's/senor/sensor/g' case02.conf
…
sed 's/senor/sensor/g' case99.conf
而 sed 的格式是
sed 'command' filename,
command 跟 regular expression 有關,
總之,這個例子的意思是,
尋找 filename 檔案中的所有 senor 字串,並取代為 sensor 字串。
情境 ex2:1test1、1test2 … 24test5、24test6 內,
有些字串是 2.6.16,有些是 2a6b16,
欲將 2.6.16 改為 2.6.28
find *test* | xargs -i sed -i 's/2\.6\.16/2\.6\.28/g' {}
ex2 的寫法在底下對 vim 的討論有詳細的解釋,
== 對單一檔案的解法 ==
假設要將 filename 檔案裡的 2009 改成 2010
vim 解法 (後面有詳細的討論,與不知如何解的問題)
vim -c '1,$s/2009/2010/g' -c ':wq' filename
或是 vim 檔案後,直接按 :
輸入 1,$s/2009/2010/g 的指令。
sed 解法 (速度快,效果好)
sed -i 's/2009/2010/g' file
有新版的 GNU sed 即可用上面的解法,
舊版的可能要
sed 's/2009/2010/g' oldfile > tmpfile; mv tmpfile oldfile
perl 解法 (我不懂 perl,還不會讓其搜尋檔案並操作)
1. 建 xxx.pl 檔,寫一行指令,
2. perl -pi -e "s/2009/2010/g" filename
3. chmod 755 xxx.pl 使其可執行後,
4. 下 ./xxx.pl 執行
== 舊的 vim 的討論 ==
目的:
把 fullset-k26.mak 裡的 2.6.16 全部取代成 2.6.28
指令:
vim -c ':1,$s/2\.6\.16/2\.6\.28/g' fullset-k26.mak
== vim 的 解釋 ==
vim -c command file
這裡有兩個部份要注意,
一個是 "vim -c command file" 整段是 command line 的命令,
有些特殊字元在 command line 有別的意義,
另一個是 "command" 本身是要傳給 vim 的命令,
要符合 regular expression 的用法。
因為 command line 中, $ 會被視為呼叫變數,
所以需用 \$ 或是 '$' 來表示 $ 是傳給 vim 的 regular expression
(在 reqular expression 中, $ 代表 檔尾 or 行尾,
例如 1,$s/x$/l,第一個$是檔尾,第二個$是行尾)
在此是整串 command 都用 ' ' 括住比較方便 (因為後面還有 . 要注意)
在regular expression的 . 代表非斷行的任意字元
所以為了確保不會有 2a6b28 被取代掉,
所以在 vim 的 command 中要用 \. 來表示是 2.6 而非 2a6 之類的任意字元
而在 command line 中,應該用 \\. 或是 '\.' 代表要傳 \. 給 vim
(如果是 \.,會把 \ 忽略認為要傳 . 給 vim,vim 會認為 . 代表任意字元
所以是 \\. ,認為要傳 \. 給 vim,讓 vim 找 . 這個字元)
也就是上述的命令等同於
vim -c :1,\$s/2\\.6\\.16/2\\.6\\.28/g fullset-k26.mak
不過,還是用括號括比較方便
也就是一開頭的
vim -c ':1,$/2\.6\.16/2\.6\.28/g' fullset-k26.mak
然後,不再接一個 -c ':wq' 的指令,
他會把檔案開啟來,並把 2.6.16 取代成 2.6.28 後,仍未存檔,
好處是可以檢查無誤後再存檔。
== vim 的 問題 ==
與 find *.conf | xargs -i {} 合在一起用時,如:
find *.conf | xargs -i vim -c '1,$s/senor/sensor/g' -c ':wq' {}
最後會當掉。
2015年2月16日 星期一
MSM8909 2pin-UART 沒LOG輸出
剛下載的 MSM8909 , compile 後, 卻發現...
開機的UART Console LOG 只有幾秒(一但 boot console, early console被turn off 後就沒LOG了)
我們公司的UART 只接了2隻pin 腳, 即 :
GPIO4--> UART TX
GPIO5--> UART RX
就醬~~
結果就是... 沒LOG 了....
當然依QC給的文件 80-NU767-1 去改...
不過... 應該沒啥用... 呵~~
先給解法, 喜歡找為什麼的人, 就再往後看怎麼debug吧~~
解法:
kernel/arch/arm/configs/msm8909-xxx_defconfig:
查看看起下的是否都有開?
CONFIG_SERIAL_MSM
CONFIG_SERIAL_MSM_CONSOLE
CONFIG_SERIAL_MSM_HS
CONFIG_SERIAL_MSM_HSL
CONFIG_SERIAL_MSM_HSL_CONSOLE
CONFIG_GPIOLIB
CONFIG_GPIO_GENERIC
CONFIG_GPIO_MSM_V3
主要是這部份(應該有多開了幾項, 各位大大可以查一下那幾項可省)
CONFIG_PINCTRL
CONFIG_PINMUX
CONFIG_PINCONF
CONFIG_GENERIC_PINCONF
CONFIG_PINCTRL_SINGLE
CONFIG_USE_PINCTRL_IRQ
CONFIG_PINCTRL_MSM_TLMM
如此就OK了~~
簡言之就是... dts中明明就是用pinctrl 去調控pin的設定,
可是卻沒有driver去handle, 因此當然就不會動囉~~
DEBUG技巧:
1. QC的Kernel是採用3.1x, 因此, 所有的devices 的註冊是源自device tree
也就是板子上有那些週邊全靠device tree來決定,
所以...... 第一步當然是先確認 UART的node是否有被正常讀到...
我在查的時後, 利用修改:
kernel/driver/base/core.c中的 device_register, 填加一行
pr_err("========== %s: %s \n", __func__, dev->of_node->name);
再利用開機時 boot UART console還可印訊息掃出kernel找到的 device nodes
2. 修改 kernel/driver/base/bus.c 印出找到那些bus裝置
在 bus_register 印出 bus->name
3. 修改 platform_driver_probe 印出那些driver正常被 probe(有device tree node且driver有配到)
印 drv->driver.name
4. 接下去當然是改
driver/tty/serial/msm_serialxxxx.c了
查的時後可以看到 有node, 但無法probe...
所以應該是driver的對映配對有問題...
這下問題就簡單很多啦~~
a. 找找config設定
b. 是否ID 配對有問題
c. 是否 driver 在 probe時有錯誤
開機的UART Console LOG 只有幾秒(一但 boot console, early console被turn off 後就沒LOG了)
我們公司的UART 只接了2隻pin 腳, 即 :
GPIO4--> UART TX
GPIO5--> UART RX
就醬~~
結果就是... 沒LOG 了....
當然依QC給的文件 80-NU767-1 去改...
不過... 應該沒啥用... 呵~~
先給解法, 喜歡找為什麼的人, 就再往後看怎麼debug吧~~
解法:
kernel/arch/arm/configs/msm8909-xxx_defconfig:
查看看起下的是否都有開?
CONFIG_SERIAL_MSM
CONFIG_SERIAL_MSM_CONSOLE
CONFIG_SERIAL_MSM_HS
CONFIG_SERIAL_MSM_HSL
CONFIG_SERIAL_MSM_HSL_CONSOLE
CONFIG_GPIOLIB
CONFIG_GPIO_GENERIC
CONFIG_GPIO_MSM_V3
主要是這部份(應該有多開了幾項, 各位大大可以查一下那幾項可省)
CONFIG_PINCTRL
CONFIG_PINMUX
CONFIG_PINCONF
CONFIG_GENERIC_PINCONF
CONFIG_PINCTRL_SINGLE
CONFIG_USE_PINCTRL_IRQ
CONFIG_PINCTRL_MSM_TLMM
如此就OK了~~
簡言之就是... dts中明明就是用pinctrl 去調控pin的設定,
可是卻沒有driver去handle, 因此當然就不會動囉~~
DEBUG技巧:
1. QC的Kernel是採用3.1x, 因此, 所有的devices 的註冊是源自device tree
也就是板子上有那些週邊全靠device tree來決定,
所以...... 第一步當然是先確認 UART的node是否有被正常讀到...
我在查的時後, 利用修改:
kernel/driver/base/core.c中的 device_register, 填加一行
pr_err("========== %s: %s \n", __func__, dev->of_node->name);
再利用開機時 boot UART console還可印訊息掃出kernel找到的 device nodes
2. 修改 kernel/driver/base/bus.c 印出找到那些bus裝置
在 bus_register 印出 bus->name
3. 修改 platform_driver_probe 印出那些driver正常被 probe(有device tree node且driver有配到)
印 drv->driver.name
4. 接下去當然是改
driver/tty/serial/msm_serialxxxx.c了
查的時後可以看到 有node, 但無法probe...
所以應該是driver的對映配對有問題...
這下問題就簡單很多啦~~
a. 找找config設定
b. 是否ID 配對有問題
c. 是否 driver 在 probe時有錯誤
2015年2月4日 星期三
Compile Qualcomm MSM8909
OS: Ubuntu 12.04 Desktop 64bit
安裝compile環境:
前往https://www.codeaurora.org/xwiki/bin/QAEP/release找一份Qualcomm 8x09的code下載,
指令為 (假設要download LA.BR.1.2.3-02010):
repo init -u git://codeaurora.org/platform/manifest.git -b release -m LA.BR.1.2.3-02010-8x09.0.xml --repo-url=git://codeaurora.org/tools/repo.git
詳情請參考: https://www.codeaurora.org/xwiki/bin/QAEP/WebHome
compile:
cd 該目錄
source build/envsetup.sh
lunch msm8909-userdebug
make -j8 (假定PC有8核CPU, 可cat /proc/cpuinfo取得核心數)
$(HOME)/ARM_Compiler_5
$(HOME)/Qualcomm/HEXAGON_Tools/5.0.x
注意: ARM Compile需要另安裝一個 license server (此假定在安裝在 主機: 192.168.0.1)
setup.sh設定檔1(modem 專用)內容:
export COMPILE_TOOLS_ROOT=$HOME
export HEXAGON_ROOT=$COMPILE_TOOLS_ROOT/Qualcomm/HEXAGON_Tools
export HEXAGON_RTOS_RELEASE=6.4.04
export HEXAGON_Q6VERSION=v5
export HEXAGON_IMAGE_ENTRY=0x08000000
export ARMTOOLS=ARMCT5.01
export ARMROOT=$COMPILE_TOOLS_ROOT/ARM_Compiler_5
export ARM_COMPILER_PATH=$ARMROOT/bin64
export ARMHOME=$ARMROOT
export ARMLIB=$ARMROOT/lib
export ARMINCLUDE=$ARMROOT/include
export ARMBIN=$ARMROOT/bin64
export ARMINC=$ARMINCLUDE
export ARMLMD_LICENSE_FILE=8224@192.168.0.1
export SCONS_MAX_NUM_JOBS=1
export PYTHON_PATH=/usr/bin/python
export PYTHONPATH=/usr/bin/python
export MAKE_PATH=/usr/bin/make
export PATH=$MAKE_PATH:$ARM_COMPILER_PATH:$HEXAGON_ROOT/$HEXAGON_RTOS_RELEASE/qc/bin:$HEXAGON_ROOT/$HEXAGON_RTOS_RELEASE/gnu/bin:$PATH:PYTHONPATH
setup.sh設定檔2 內容:
export COMPILE_TOOLS_ROOT=$HOME
export ARMTOOLS=ARMCT5.01
export ARMROOT=$COMPILE_TOOLS_ROOT/ARM_Compiler_5
export ARM_COMPILER_PATH=$ARMROOT/bin64
export ARMHOME=$ARMROOT
export ARMLIB=$ARMROOT/lib
export ARMINCLUDE=$ARMROOT/include
export ARMBIN=$ARMROOT/bin64
export ARMINC=$ARMINCLUDE
export ARMLMD_LICENSE_FILE=8224@192.168.0.1
export SCONS_MAX_NUM_JOBS=1
export MAKE_PATH=/usr/bin/make
export PATH=$MAKE_PATH:$ARM_COMPILER_PATH
安裝compile環境:
1.
sudo
apt-get install git gnupg flex bison gperf build-essential zip curl libc6-dev
libncurses5-dev:i386 x11proto-core-dev libx11-dev:i386 libreadline6-dev:i386
libgl1-mesa-glx:i386 libgl1-mesa-dev g++-multilib mingw32 tofrodos
python-markdown libxml2-utils xsltproc zlib1g-de:i386
2.
sudo
ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
3.
curl https://storage.googleapis.com/git-repo-downloads/repo
> ~/bin/repo
4.
chmod
a+x ~/bin/repo
HLOS 部份 (Android+Linux)
HLOS BuildType
|
Use / Description
|
user
|
limited access; suited for production
|
userdebug
|
like “user” but with root access and debuggability; preferred for
debugging
|
eng
|
development configuration with additional debugging tools
|
前往https://www.codeaurora.org/xwiki/bin/QAEP/release找一份Qualcomm 8x09的code下載,
指令為 (假設要download LA.BR.1.2.3-02010):
repo init -u git://codeaurora.org/platform/manifest.git -b release -m LA.BR.1.2.3-02010-8x09.0.xml --repo-url=git://codeaurora.org/tools/repo.git
詳情請參考: https://www.codeaurora.org/xwiki/bin/QAEP/WebHome
compile:
cd 該目錄
source build/envsetup.sh
lunch msm8909-userdebug
make -j8 (假定PC有8核CPU, 可cat /proc/cpuinfo取得核心數)
Non-HLOS (chipcode)
假定ARM_Compiler與HEXAGON_TOOLS都安裝在 HOME目錄中, 即:$(HOME)/ARM_Compiler_5
$(HOME)/Qualcomm/HEXAGON_Tools/5.0.x
注意: ARM Compile需要另安裝一個 license server (此假定在安裝在 主機: 192.168.0.1)
setup.sh設定檔1(modem 專用)內容:
export COMPILE_TOOLS_ROOT=$HOME
export HEXAGON_ROOT=$COMPILE_TOOLS_ROOT/Qualcomm/HEXAGON_Tools
export HEXAGON_RTOS_RELEASE=6.4.04
export HEXAGON_Q6VERSION=v5
export HEXAGON_IMAGE_ENTRY=0x08000000
export ARMTOOLS=ARMCT5.01
export ARMROOT=$COMPILE_TOOLS_ROOT/ARM_Compiler_5
export ARM_COMPILER_PATH=$ARMROOT/bin64
export ARMHOME=$ARMROOT
export ARMLIB=$ARMROOT/lib
export ARMINCLUDE=$ARMROOT/include
export ARMBIN=$ARMROOT/bin64
export ARMINC=$ARMINCLUDE
export ARMLMD_LICENSE_FILE=8224@192.168.0.1
export SCONS_MAX_NUM_JOBS=1
export PYTHON_PATH=/usr/bin/python
export PYTHONPATH=/usr/bin/python
export MAKE_PATH=/usr/bin/make
export PATH=$MAKE_PATH:$ARM_COMPILER_PATH:$HEXAGON_ROOT/$HEXAGON_RTOS_RELEASE/qc/bin:$HEXAGON_ROOT/$HEXAGON_RTOS_RELEASE/gnu/bin:$PATH:PYTHONPATH
setup.sh設定檔2 內容:
export COMPILE_TOOLS_ROOT=$HOME
export ARMTOOLS=ARMCT5.01
export ARMROOT=$COMPILE_TOOLS_ROOT/ARM_Compiler_5
export ARM_COMPILER_PATH=$ARMROOT/bin64
export ARMHOME=$ARMROOT
export ARMLIB=$ARMROOT/lib
export ARMINCLUDE=$ARMROOT/include
export ARMBIN=$ARMROOT/bin64
export ARMINC=$ARMINCLUDE
export ARMLMD_LICENSE_FILE=8224@192.168.0.1
export SCONS_MAX_NUM_JOBS=1
export MAKE_PATH=/usr/bin/make
export PATH=$MAKE_PATH:$ARM_COMPILER_PATH
APSS HLOS
(boot.img,
cace.img, dt.img, persist.img, ramdisk.img, recovery.img, system.img, userdata.img,
emmc_appsboot.mbn)
result:
out/target/product/msm8909/
|
ubuntu 12.04+
OpenJDK7
|
souce
build/envsetup.sh
lunch msm8909-userdebug
Compile:
make -j8 Clean: make clobber |
MPSS
result:
modem_proc/build/ms/bin/
|
Hexagon tool set
6.4.05
Python 2.7.6+
Perl 5.14.2
SCons v2.0.0+
用設定檔1 |
[NON-HLOS]/modem_proc/build/ms/
Compile:
./build.sh
8909.gen.prod -k
./build.sh
8909.gps.prod -k
Clean:
./build.sh
8909.gen.prod -c
./build.sh
8909.gps.prod -c
|
BOOT loaders
result:
boot_images/build/ms/bin/8909/emmc/
|
ARM compiler
tools
5.01 update
3(build 94)
Python 2.6.6+
Perl 5.8.x+
SCons v2.0.0+
用設定檔2 |
[NON-HLOS]/boot_images/build/ms
Compile:
./build.sh
TARGET_FAMILY=8909 --prod
Clean:
./build.sh -c
TARGET_FAMILY=8909 --prod
|
RPM
result:
rpm_proc/build/ms/bin/8909/
|
ARM compiler
tools
5.01 update
3(build 94)
Python 2.6.6+
Perl 5.6.1+
SCons v2.0.0+
|
[NON-HLOS]/rpm_proc/build/
Compile:
./build_8909.sh
Clean:
./build_8909.sh
-c
|
CNSS
result:
wcnss_proc/build/ms/bin/SCAQMAZ/
|
binary only
|
|
TZ
result:
trustzone_images/build/ms/bin/MAZAANAA
|
ARM compiler
tools
5.01 update
3(build 94)
Python 2.6.6+
Perl 5.10.1+
SCons v2.0.0+
用設定檔2 |
[NON-HLOS]/trustzone_images/build/ms/
Compile:
./build.sh
CHIPSET=msm8909 tz sampleapp tzbsp_no_xpu playready widevine securitytest keymaster commonlib
Clean:
./build.sh
CHIPSET=msm8909 tz sampleapp tzbsp_no_xpu playready widwvine securitytest keymaster commonlib -c
|
訂閱:
文章 (Atom)