2026年4月13日 星期一

Compile vim

Prerequisite:

Install libx11-dev and libxtst-dev xorg-dev

./configure --with-features=huge --enable-python3interp=yes --enable-rubyinterp=yes --enable-multibyte --enable-cscope --enable-gui=auto --with-x --enable-fail-if-missing

make

sudo checkinstall


Note, 

rm src/auto/config.cache

2025年11月14日 星期五

加rust到vimrc

新增rust.vim與coc.nvim 並且把tagfunc設成CocTagFunc

這樣就能使用tag對rust定義的跳轉

3 " set the runtime path to include Vundle and initialize↵
4 set rtp+=~/.vim/bundle/Vundle.vim↵
5 call vundle#begin()↵
6 "set rtp+=~/.vim/bundle/vundle/↵
7 "call vundle#rc()↵
8 ↵
9 "let Vundle manage Vundle↵
10 "required!↵
11 Plugin 'VundleVim/vundle.vim'↵
12 "Bundle 'Shougo/neocomplete.vim'↵
13 Plugin 'Shougo/vimproc.vim'↵
14 Plugin 'Shougo/vimshell.vim'↵
15 Plugin 'mbbill/echofunc'↵
16 Plugin 'derekwyatt/vim-scala'↵
17 Plugin 'rust-lang/rust.vim'↵
18 Plugin 'neoclide/coc.nvim', {'branch': 'release'}↵
19 ↵
20 " All of your Plugins must be added before the following line↵
21 call vundle#end() " required↵
22 filetype plugin indent on " required↵
121 set tagfunc=CocTagFunc↵

2025年10月30日 星期四

安裝Coc.nvim與coc plugin

 安裝完Coc.nvim之後

透過:CocInstall coc-rust-analyzer發生錯誤

透過檢查:CocOpenLog發現

Vim(redir):E930: Cannot use :redir inside execute() on function coc#api#Command

redir有問題

於是採用手動安裝的方式

cd ~/.config/coc/extensions

npm install coc-rust-analyzer --global-style --ignore-scripts --no-bin-links

然後在Vim裡透過

:CocList extensions

[No Name][+] [unix] [] [utf-8] [ASCII=000] [POS=0001,0001][100%] [LEN=1]                                                             []
 * coc-snippets 3.4.7 ~/.config/coc/extensions/node_modules/coc-snippets                                                               
 + coc-rust-analyzer 0.85.0 ~/.config/coc/extensions/node_modules/coc-rust-analyzer        

可以看到安裝成功

升級方法:

npm update coc-rust-analyzer --global-style

:CocRestart

2021年8月2日 星期一

extract cpio uboot

移掉u-boot tool生成的64byte header

dd if=rootfs.cpio.uboot_32 of=rootfs.cpio.gz bs=64 skip=1

解開gz

gunzip rootfs.cpio.gz

讀出rootfs

mkdir rootfs; cd rootfs

使用fakeroot來避免 sudo

fakeroot

cpio -i < ../rootfs.cpio

更改....

重新打包 # rm dev/*

 find . | cpio -H newc -o | gzip -9 > ../new_initramfs.cpio.gz 

離開fakeroot

exit

加回header

 mkimage -A arm -T ramdisk -C gzip -d new_initramfs.cpio.gz uramdisk.image.gz

reference:

https://community.nxp.com/t5/i-MX-Processors/modify-initramfs/m-p/194825

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842473/Build+and+Modify+a+Rootfs?view=blog

2019年1月11日 星期五

如何在python上使用gtags

gtags本身並不支援Python
但是有個透過plugin可以加上python syntax highlighting來生成正確的tag
用法:
$ sudo pip install Pygments
$ git clone https://github.com/yoshizow/global-pygments-plugin.git
$ cd global-pygments-plugin
$ ./reconf.sh
$ ./configure
$ make
$ sudo make install
$ cp sample.globalrc ~/.globalrc

參考資料:
[1] https://stackoverflow.com/questions/5661485/how-to-add-python-plug-in-to-gnu-global
[2] https://github.com/yoshizow/global-pygments-plugin

2018年11月27日 星期二

vim +cscope字串搜尋

在vim +cscope裡尋找一個字串
:cs f s mystring
會跳出一連串待選列1....
需要一個個選擇有點麻煩
解決的方法就是打開cscopequickfix
這樣就可以利用cn, cp (cnext, cprevious)在前後之間跳躍

參考資料:

https://stackoverflow.com/questions/28185067/vim-go-to-next-search-result-across-multiple-files

2014年9月15日 星期一

androidized kernel跑在linux上的眉角之二(locale)

當locale沒被設定的時候
會自動fall back到"C"
這時可能會對許多package執行造成困擾
這時候就可以用如下的命令解決
export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
locale-gen en_US.UTF-8
dpkg-reconfigure locales

 
參考資料:
http://www.thomas-krenn.com/en/wiki/Perl_warning_Setting_locale_failed_in_Debian

2014年9月12日 星期五

androidized kernel跑在linux上的眉角之一(ethernet)

把一個android kernel配上linux root file system
什麼怪事都會發生
例如說
root@ubuntu:/# ping 8.8.8.8
socket: Permission denied
什麼?有沒有搞錯?permission denied?
我可是天下無敵無所不能的root耶
居然連ping都不能用
.
.
.
.
.
經過了一番google的努力後
才發現原來android的權限設置遠比原生linux還要複雜
必須要在/etc/group裡加入下列兩行
inet:x:3003:root
net_raw:x:3004:root 

root才能使用inet的功能
如果別的用戶要使用inet都必需要加到這兩個group裡面
真是太麻煩了
但!
有個一勞永逸的方法
就是把
CONFIG_ANDROID_PARANOID_NETWORK
關掉就好了
簡單吧

2014年8月29日 星期五

patch的幾種方法

有幾種常見做diff和patch的方法

1. 使用大家最愛的git

matthew@E6430:~/temp$ git log
commit 406400903bc059bedfee59b11d60f7375818a21b
Author: Matthew.Shyu
Date:   Fri Aug 29 19:59:47 2014 +0800

    add hello world

commit 619ff93b9c08a2c63d433bd67de2f4051046332f
Author: Matthew.Shyu
Date:   Fri Aug 29 19:59:09 2014 +0800

    initial commit


例如要為"add hello world"這個commit做一個patch file的時候
可以使用如下的命令
$ git format-patch 406400903bc059bedfee59b11d60f7375818a21b -1
-1 代表往前一個commit的意思

要apply patch的時候就可以
$ git apply 0001-add-hello-world.patch

或者
$ git am 0001-add-hello-world.patch

這兩個的差別在於
第一個命令只是將patch的內容加上去並不會進行commit
所以在workspace上只是以unstaging change的形式存在
第二個命令就直接將patch進行commit到log裡

2. 使用quilt
quilt是一個patch管理程式
在Debian/Ubuntu上可以使用
$ apt-get install quilt
來安裝

我們首先在source code的根目錄產生一個patches目錄
$ mkdir patches
然後新增一個patch
$ quilt new hello-world.patch
再來是將需要修改的file加到quilt中
有兩個作法
$ quilt add test.c
或直接
$ quilt edit test.c
第二個作法是將test.c加到quilt中
並使用預設的編輯器對test.c進行編輯
當改好後
$ quilt refresh
就可以檢查patches/裡的patch是否正確
如果不再修改了
則使用
$ quilt pop
這時候被修改的文件會恢復成原狀
如果要再度修改
$ quilt push hello-world.patch

3. 古老的diff/patch法
使用
$ diff -purN <orig> <new> > hello-world.patch
$ patch -p0 < hello-world.patch
p0代表不rip directory
p1代表去除一層directory
依此類推


2014年8月13日 星期三

Android與Linux常用的debug技巧

很久沒有分享心得了
今天來分享一下常用的debug技巧

當系統當機時,最常見的就是stack dump
那要怎麼利用stack dump來track down bug呢
有幾個常見的方法

1.  使用addr2line
這個方法非常好用,但只適用於自己編出來的系統
例如我們在logcat裡看到
07-30 09:52:15.289: INFO/DEBUG(28):          #00  pc 0000aea4  /system/lib/libc.so
07-30 09:52:15.289: INFO/DEBUG(28):          #01  pc 00026810  /data/data/oms.cj.yap/lib/libsdl.so
由logcat我們可以知道
這個當機發生在libc 的0xaea4行
但對應source code在哪裡呢?
這時候就可以
$ addr2line -f -e libc.so 0000aea4
<格式>
$ addr2line -f -e <path to library> <offset>

2. 直接看assembly code
那要怎麼知道哪個symbol是位於哪個library
第一個方法當然就是直接去看makefile
看library究竟包了哪些source file
但這個方法稍嫌麻煩了一點
我們可以利用nm來把symbol從library dump出來
<格式>
$ nm <library>
然後可以用objdump把source code + assembly code 用mixed format輸出
<格式>
$ objdump -dRS <path to library> > tmp

3. 除了addr2line之外,Android ndk tool也有一些很棒的工具可以使用
例如
$ adb logcat |  ndk-stack -sym <path to libraries>
$ ndk-stack -sym <path to libraries> -dump <file with crash log>

再來介紹一下gdb/gdbserver常見的技巧
在embedded system上
我們常常利用gdbserver和gdb配對進行debug
這是因為在embedded system上,通常記憶體,儲存空間,和cpu效率都是有限的
如果我們直接把gdb放到embedded system上會有幾個問題
1. 要使用gdb的話library必須要unstripped, 也就是說我們將會佔用大量的儲存空間
2. 執行gdb會耗費大量的cpu resource, 如果發生的bug與timing有關, 就會比較難以復現, 甚至於會出現其他的問題
另外gdbserver由於體積小所以更有著容易porting的好處

要開始debug時
我們先在embedded system上把gdbserver打開
# gdbserver :5039 <app>

然後在host上執行gdb
arm-linux-gdb
(gdb) target remote 192.168.0.100:5039 # 這個命令指定target的ip
(gdb) info shared # 這個命令用來確定gdb是否正確找到library的路徑, 因為使用cross compilation的關係, 所以通常default search path是不能使用的
(gdb) set solib-search-path staging/usr/lib # 用這個命令來指定library search path
(gdb) set sysroot staging # 也可以用這個命令直接指定cross compilation的root,就不用單獨指定search path了
(gdb) set logging overwrite on # 下面這幾個命令是用來把core dump儲存起來
(gdb) set logging on
(gdb) continue
(gdb) bt full
(gdb) set logging off


2013年10月2日 星期三

如何使用gdb debug apk

這篇文章中我談到如何使用gdb配合上adb來進行native process除錯.
但是如果除錯的對象是一個apk的話要怎麼辦?
因為apk是以依附在android framework上執行的
所以在/system/bin下面並無法找到一個相對應的process來獲取symbol

解決方法如下:
1. 將apk啟動(這是以attach的方式進行debug, 如果需要從一開始就進入debug mode的話, 請研究一下am的使用方法)
2. 在平台上找到apk的process id 以bluetooth為例
# ps | grep bluetooth
bluetooth 4040  2412  665656 24064 ffffffff 400f6004 S com.android.bluetooth
3. 將gdbserver attach上去

# gdbserver :5039 --attach 4040
4. 在pc端進行adb forward
$ adb forward tcp:5039 tcp:5039
5. 將gdbclient attach到app_process上
這裡就是重點了
所有的apk其實都是從app_process spawn出來的
所以可以藉由app_process找到正確的symbol
$ gdbclient app_process

這樣就大功告成
Enjoy!

參考資料:
1. http://blog.csdn.net/androidsecurity/article/details/8859313


2013年9月6日 星期五

更新.vimrc

~/.vimrc.html
 1 set nocompatible
 2 filetype off
 3 set rtp+=~/.vim/bundle/vundle/
 4 call vundle#rc()
 5 
 6 "let Vundle manage Vundle
 7 "required! 
 8 Bundle 'gmarik/vundle'
 9 Bundle 'Shougo/neocomplete.vim'
10 Bundle 'Shougo/vimproc.vim'
11 Bundle 'Shougo/vimshell.vim'
12 Bundle 'mbbill/echofunc'
13 
14 " Disable AutoComplPop. 
15 let g:acp_enableAtStartup = 0
16 " Use neocomplete.
17 let g:neocomplete#enable_at_startup = 1
18 " Use smartcase.
19 let g:neocomplete#enable_smart_case = 1
20 " Set minimum syntax keyword length.
21 let g:neocomplete#sources#syntax#min_keyword_length = 3
22 let g:neocomplete#lock_buffer_name_pattern = '\*ku\*'
23 
24 " Define dictionary.
25 let g:neocomplete#sources#dictionary#dictionaries = {
26      \ 'default' : '',
27      \ 'vimshell' : $HOME.'/.vimshell_hist',
28      \ 'scheme' : $HOME.'/.gosh_completions'
29 \ }
30 " Define keyword.
31 if !exists('g:neocomplete#keyword_patterns')
32     let g:neocomplete#keyword_patterns = {}
33 endif
34 let g:neocomplete#keyword_patterns['default'] = '\h\w*'
35 
36 set number
37 set showcmd
38 set showmatch
39 set hlsearch
40 set incsearch
41 set sw=4
42 set ts=4
43 syntax on
44 filetype indent on
45 filetype plugin on "~/.vim/syntax "omni-complete ~/.vim/autoload ^x^n
46 set smarttab
47 set sidescroll=1
48 set guifont=Inconsolata\ Medium\ 14
49 set guifontwide=YaHei\ Mono\ 14
50 set laststatus=2
51 set statusline=%F%m%r%h%w\ [%{&ff}]\ [%Y]\ [%{(&fenc==\"\")?&enc:&fenc}%{(&bomb?\",BOM\":\"\")}]\ [ASCII=\%03.3b]\ [POS=%04l,%04v][%p%%]\ [LEN=%L]\ %=[%{GitBranch()}]
52 set backspace=2
53 set clipboard=unnamedplus
54 set autoindent
55 set smartindent
56 set cindent
57 "set spell
58 set encoding=utf-8
59 set makeprg=
60 set smartcase
61 set ruler
62 set cursorline
63 colors koehler
64 if has("gui_running")
65 else
66     set t_Co=16
67     "hi CursorLine cterm=NONE ctermbg=DarkGray ctermfg=NONE guibg=NONE guifg=NONE
68     hi CursorLine cterm=bold ctermbg=black ctermfg=NONE guibg=NONE guifg=NONE
69 endif
70 set fileencodings=ucs-bom,utf-8,euc-jp,cp936,big5,gb18030,euc-kr,latin1
71 set guioptions=aegimrLt
72 autocmd BufNewFile,BufRead *.mip :set syntax=mips
73 autocmd BufNewFile,BufRead *.S :set syntax=mips
74 if has("gui_running")
75 set langmenu=zh_TW.UTF-8
76 source $VIMRUNTIME/delmenu.vim
77 source $VIMRUNTIME/menu.vim
78 language messages zh_TW.utf-8
79 endif
80 
81 "let Tlist_Use_Right_Window=1                 " 在右側窗口中顯示
82 let Tlist_File_Fold_Auto_Close=1             " 自動摺疊 
83 let Tlist_Sort_Type = "name"
84 let Tlist_Show_One_File = 1
85 
86 let g:LargeFile=10
87 "let g:EclimTaglistEnabled=0
88 set csprg=gtags-cscope " use fake cscope
89 set cst "use cscope to get tags
90 cs a GTAGS . -C
91 "au BufWinLeave ?* mkview
92 "au BufWinEnter ?* silent loadview

2013年6月14日 星期五

coding的好朋友 -- tag

  當需要trace一個比較大的project時, 要如何正確找到function和variable的definition呢?

還在使用grep嗎?那就嚴重落伍了.

下面介紹三個產生tag的tool

1. EXUBERANT Ctags
http://ctags.sourceforge.net/
這個是最常用, 如果有使用Vim的人一定會知道的command (Ctrl + ] )
這個command可以幫你快速跳到definition這個後面就是使用ctags產生出來的tag list.
另外, 雖然一開始是為了C發展出來的tag, 但現在已經發展到支援許多語言格式, 如常見的java, python等等都有支援, 而且正確度極高.

2. Cscope
http://cscope.sourceforge.net/
上面說到ctags可以快速幫你找到function definition, 但如果是要找function caller的時候就不是這麼方便了.
這個時候就可以使用Cscope, Cscope能夠與Vim完美整合, 在Quick Fix Window裡顯示出所有可能的function caller的位置.
但Cscope有一個致命的缺點就是只有在C語言下表現完美, 在C++與Java裡都只是堪用而已, 準確度較低.

3. Gtags
http://www.gnu.org/software/global/
最後一個介紹的是Gtags, Gtags的曝光率比較低,
以至於在Ubunut/Debian的package太舊了也沒人去跟新
所以使用Gtags的方法必須要下載原始碼後自行編譯,
所幸編譯上非常簡單

Gtags綜合了ctags和cscope的優點
也就是說Gtags可以幫你很正確的找到function definition, function caller, function callee.
但Gtags也是有缺點的, 最大的缺點應該是界面很難用, 我認為這
應該是使用率較低的原因

不過近來Joe Steffen替Gtags寫了一個新的界面
讓Gtags可以透過cscope的界面與外部溝通稱之為gtags-cscope
http://www.gnu.org/software/global/globaldoc.html#SEC34
只要在Vim裡設置

set csprg=gtags-cscope
cs add GTAGS

Gtags就可以如同Cscope般使用

此外,
Gtags還有一個很重要的優點
那就是gtags可以incrementally update
每當文件修改後就會發生tag無法對上的問題
對ctags來說解決方法就是重新產生一個新的tag
對cscope來說問題就更大了
因為在Vim裡Cscope是藉由呼叫外部程式
而這個程式會將Cscope的tag lock住
所以每當要update tag必須先將Vim關閉
但Gtags就沒有這個問題,
要update Gtags僅僅需要在command line裡執行
$ global -u
就行了

2013年6月11日 星期二

Vim plugin from the ONE



Vim裡提供的Omni-complete, 我長久以來一直覺的是一個雞肋, 不只複合鍵難用, 正確率也不高, 也就是說僅處於堪用的階段. 最近看到許多人在討論clang-complete, 還有YouCompleteMe, 但據我的使用經驗要成功把clang的tag編出來還挺費工夫的.




另一個神級neocomplete(https://github.com/Shougo/neocomplete.vim)的插件

解決了這個困擾

不廢話看圖就知道了



不過在Ubuntu12.04上的Vim太舊了而無法支援neocomplete

還好有好心人打包了新的Vim$ sudo add-apt-repository ppa:fcwu-tw/ppa $ sudo apt-get update $ sudo apt-get install vim


總而言之
真是太神了!!

參考資料:
1. https://github.com/Shougo/neocomplete.vim
2.http://rickey-nctu.blogspot.tw/2013/05/vim-youcompleteme.html

2013年5月24日 星期五

在nexus 4上使用adb

將nexus 4連上usb後, 卻發現adb找不到devices.
心念很快一轉,這一定是usb debug選項沒有開啟
進到settings後卻怎麼也找不到developer options.
原來Google在4.2以後將developer options給隱藏了起來
開啟的密技是進到About Phone後
向下轉到最後一項Build Number連點7下
你就可以成功拿回developer options,
有趣的是當你點三下後, Nexus 4會告訴你你還差4下就可以成為developer. Funny Ha?


參考資料:
http://www.androidcentral.com/how-enable-developer-settings-android-42

2013年4月26日 星期五

找不到libpython2.6.so.1.0

prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-gdb: error while loading shared libraries: libpython2.6.so.1.0

解決方法:
$ sudo add-apt-repository ppa:fkrull/deadsnakes
$ sudo apt-get update
$ sudo apt-get install libpython2.6

參考資料:
http://e2e.ti.com/support/arm/sitara_arm/f/791/t/205822.aspx

2013年1月22日 星期二

我所不知道的Vim

這裡紀錄一下新學會的Vim Command
1. Vim diff裡尋找上一個與下一個差異
]c 與 [c

2013年1月9日 星期三

讓一般user使用/dev/ttyUSB0

一開始我認為只要把user加入dialout的group就好了, 結果還是遇到permission denied的問題

還好找到了以下的solution

$ sudoedit /etc/udev/rules.d/50-ttyusb.rules

貼上


KERNEL=="ttyUSB[0-9]*",NAME="tts/USB%n",SYMLINK+="%k",GROUP="uucp",MODE="0666"K+="%k",GROUP="uucp",MODE="0666"

參考資料:
How do I allow a non-default user to use serial device ttyUSB0?

2013年1月8日 星期二

用tcpip來進行android debug

1. 先確認工作站與device在同一個網域內
假設工作站ip為192.168.0.1
device的ip為192.168.0.2

2. 連接device
$ adb connect 192.168.0.2
確認是否正確連接
$ adb devices
List of devices attached
192.168.0.2:5555    device


3. 打開device上的gdbserver
# gdbserver :5039 /system/bin/myProgram

或者是用attach的方法
# gdbserver :5039 --attach myProgramPid

4. 將adb port forwarding 打開,這是要將工作站端的port forward到device 的port
$ adb forward tcp:5039 tcp:5039

5. 打開gdb
$ gdbclient myProgram

註:
gdbclient是envsetup.sh裡的function
所以要先作
$ . build/envsetup.sh
$ lunch
後才能使用


參考資料:
http://www.kandroid.org/online-pdk/guide/debugging_gdb.html

2013年1月7日 星期一

加一個remote到android repo

我想要在工作站和本端電腦都建立一個repo,這樣一來就可以在任何地方都可以進行編輯
以圖示來說就是
A(官方repo) <- B(工作站)<=>C(本端)
依照http://www.androidenea.com/2010/06/using-localmanifestxml-file-in-repo-to.html裡的說法我應該可以利用local_manifest.xml達到這個目的,然而我卻沒辦法成功的config出來
於是我就想到了一個方法
我何不再每個git下面建立個別的remote然後利用repo的forall來幫我把所有的git都建好正確的remote對應
因此我寫了下面的小script
/bin/add_remote.sh.html
1 #!/bin/bash
2 REMOTE_NAME=$1
3 URL=$2
4 LOCAL_REPO_BASE=$3
5 REMOTE_REPO_BASE=$4
6 CWD=`pwd`
7 CWD=${CWD/$LOCAL_REPO_BASE/$REMOTE_REPO_BASE}
8 git remote add $REMOTE_NAME $URL$CWD
9 echo "git remote add $REMOTE_NAME $URL$CWD"
-->
把script取名為/bin/add_remote.sh
然後我再用以下的command就可以將remote設好了YA
$ repo forall -c add_remote.sh workstation_repo ssh://user@worksation localrepo remoterepo