2011年10月18日 星期二

vim + ctags 看程式碼好用的工具

http://ctags.sourceforge.net/

ctags是用vim寫程式的程式設計師一定要知道的套件
ctags會幫使用者建立一個tag (or index) 檔,方便游標可以在各個符號中快速移動
比如說你在trace一段source code時候發現一個function call
就可以利用快速鍵切換游標到function定義的地方
使用方法非常簡單

首先先在source code的最外層目錄輸入指令:
$ ctags -R *
這時候系統就會建立對應的tag檔
接著進去vim就會自動載入對應tag檔
你也可以在vim中輸入以下指令來載入對應的tag:
:set tags=/home/sway/src/tags
/home/sway/src/tags就是我tag存放的路徑
如果常用的話也可以把這行vim設定存放到~/.vimrc裡頭

之後當你游標移到function call上時,輸入:
【Ctrl】+【]】
就可以跳到function的定義
接著再輸入:
【Ctrl】+【t】
就可回到function call的地方

如果你沒有SourceInsight這類tool的話,vim + ctags也是可以幫你做一些簡單的trace
其他包括macro, class, namespace都可以用這種方法來trace

2011年10月17日 星期一

在vim, vi使用數字鍵盤(pietty, putty)

putty或pietty連到遠端主機使用vi或vim時常常會有這個問題:鍵盤右方的數字鍵無法使用
其實只要更改一下putty, pietty裡頭的設定就可以支援這個功能了
修改方法如下圖

進入設定選單,把Terminal -> Features 中的 Disable application keypad mode打勾即可


2011年10月14日 星期五

Startup code

startup code是程式在正式執行main function前所執行的一段code。在一般的軟體開發中,這段code是由compiler所自動產生並安插在main執行之前。因此平常我們可能不會注意到這段code。一般軟體的startup code最主要的工作就是初始化stack。

在embedded system,startup code是開機上電後第一段會執行的程式,通常是由組合語言所寫成。大部分都叫做startup.asm或是crt0.s。他比一般PC上的軟體會多作一些事情,以下是一個embedded software startup code的流程:

1. 關掉所有的interrupt
2. 配置一塊空間給stack
3. 初始化stack pointer, frame pointer
4. 把資料從ROM搬到RAM上,通常是用DMA來搬
5. 把.bss section清空為0,因為未初始化的變數一開始皆為0
6. 打開interrupt
7. 初始化系統的一些設定
8. jump到main function,開始執行main function中的程式

2011年10月13日 星期四

The C Programming Language


今天很不幸的聽到K & R當中的Dennis Retchie不幸逝世的消息。這本書可能大部分程式設計師都讀過了。講到C的聖經第一本大家會想到的就是這本The C Programming Language。The C Programming Language雖然只有200多頁,但是內容涵蓋了所有C的細節。真的可以說是技術著作的經典之作

The C Programming Language出版於1978年,是第一本C的教學書。並於1988年出第二版。書中的內容一直到現在都還影響這個世界,一個最有名的例子就是"Hello World",這本經典之作的第一個程式就是印出Hello World。一直到現在許多程式語言教學書的第一個程式都還是用印出Hello World來當作範例

2011年10月6日 星期四

設定Register常用的Code

將某bit設為1
C
flag |= (1 << n);
Verilog
flag[n] = 1'b1;
將某bit設為0
C
flag &= ~(1 << n);
Verilog
flag[n] = 1'b0;
將某bit做toggle (0變1,1變0)
C
flag ^= (1 << n);
Verilog
flag[n] = ~flag[n];
判斷某bit是否為1
C
if ((flag & mask) == mask)
Verilog
if (flag[n])
判斷某bit是否為0
C
if ((flag & mask) != mask))
Verilog
if (~flag[n])

System Call

System Call簡介
System call 是 process 與OS之間的介面,由Linux kernel實做出來給user使用,system call提供user
programm和os溝通的界面,當user program需要os的服務時,user program便使用system call


System Call 流程圖




流程:
system call會伴隨一個trap(在Linux下會跳到int 0x80),此時系統將mode bit由user mode改成
monitor mode(1->0)並查尋trap vector找尋相對應trap service routine
(此時可做context switch 0->1)
執行完此routine發出interrupt告訴os已經完成




User program 與 wrapper routine 是 user space 的 code
system call handler 與 service routine 則是屬於 kernel space
從 User space 切換到 kernel space 是透過中斷
底下的用link這個system call當例子,解釋程式碼

syscall_table.S
PATH : /usr/src/linux/arch/i386/kernel/syscall_table.S
在 Linux 中, 每個 system call 都有自己獨有的號碼。
當 user-space 執行一個 system call 時,process是去參考 syscall 的號碼而不是名字。



unistd.h
PATH : /usr/src/linux/include/asm/unistd.h
unistd.h 是一個重要的標頭檔,裡頭是 system call 編號的定義,當 system call 發生時,system call 的號碼將透過 register (EAX) 傳給 kernel。





#define _syscall2(type,name,type1,arg1,type2,arg2) 
type name(type1 arg1,type2 arg2) 
{ 
long __res; 
__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" 
         : "=a" (__res) 
         : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) 
         : "memory"); 
__syscall_return(type,__res); 
}

unistd.h 也定義了不同參數的 system call handler,上面的程式碼是處理 2 個參數的 handler
這是一個 macro,當遇到系統呼叫的時候,就會被展開。

參數傳遞與傳回值
system call 的編號透過 %eax 暫存器來指定;若要傳遞參數,則是透過其它暫存器來傳遞(最上面的流程圖上有標示)
Linux system call 最多可傳遞6個參數,參數的傳遞是透過以下的暫存器來完成:
%ebx:第1個參數。
%ecx:第2個參數。
%edx:第3個參數。
%esi:第4個參數。
%edi:第5個參數。
%ebp:第6個參數(做臨時用途)。

x86 的 Interrupt
x86 的interrupt(中斷)可分為系統定義與使用者自訂:
中斷向量0~8、10~14、16~18:predefined interrupts and exceptions。
中斷向量19-31:保留。
中斷向量32-255:user-defined interrupts(maskable interrupts)。

當從 shell 執行 link 時,0x80 號中斷向量會指到 system_call 進入點的位址,由於 link 有兩個參數,const char* oldfile 和 const char* newfile,因此 shell 會執行 syscall2(int link, const char* oldname, const char* newname),執行 sys_link(),sys_link()會呼叫linkat()。在 linux 中,目錄和檔案在系統中被視為同樣。

int link(const char* oldname, const char* newname)
{
    long _res;
    _asm_  volatile(“int $0x80”
         :”=a”(_res)
         :”0”(_NR_link),”b”((long)(oldname)),
         “c”((long)(newname)));
    do{
        if((unsigned long)(_res)>=(unsigned long)(-(128+1))){
            errno=-(_res);
            _res=-1;
    }
    return (int)(_res);
    }while(0);
}

下面這段組語是 system call 的進入點,也就是 system call table
PATH : /usr/src/linux/arch/i386/kernel/entry.S
ENTRY(system_call)
        pushl %eax                      # save orig_eax
        SAVE_ALL
        GET_CURRENT(%ebx)
        testb $0x02,tsk_ptrace(%ebx)    # PT_TRACESYS
        jne tracesys
        cmpl $(NR_syscalls),%eax
        jae badsys
        call *SYMBOL_NAME(sys_call_table)(,%eax,4)
        movl %eax,EAX(%esp)             # save the return value
 ENTRY(ret_from_sys_call)
        cli                             # need_resched and signals atomic test
        cmpl $0,need_resched(%ebx)
        jne reschedule
        cmpl $0,sigpending(%ebx)
        jne signal_return

syscalls.h
PATH : /usr/src/linux/include/linux/syscalls.h
這個檔案包含了 system call 的宣告。





asmlinkage 是在i386 system call實做中,gcc 很重要的一個標籤。他是一個macro,會被展開成
#define asmlinkage __attribute__((regparm(0)))
這是/usr/include/asm/linkage.h 裡頭的定義,regparm(0)表示不使用register傳遞參數
如此一來所有的參數就會被強迫放在stack當中

這麼做的原因是因為system call handler是assembly code,但是system call routine是C code
為了要保證當system call handler呼叫相對應的system call routine時,符合C語言參數傳遞的規則
是以 stack 方式傳參數,在C function的 prototype前面就要加上 "asmlinkage"。

System call 結束
當 system call 執行完的時候,最後會執行 ret_from_sys_call() 離開。
最後回到 syscallX() 中去。在 syscallX() 中,檢測是否有錯誤碼,然後返回。

2011年10月5日 星期三

GNU Screen教學

最近發現一個Linux底下好用的軟體叫Screen,他可以在一個實體的終端機中模擬多個虛擬視窗
當你要看一堆code的時候,就會覺得他很方便

安裝好後輸入screen就可以開始執行
Screen使用上都是由一個前置鍵【Ctrl-A】所組成,以下是一些我覺得常用的指令

【Ctrl-A】【c】 : 建立一個新的視窗
【Ctrl-A】【w】: 查看目前已經存在的視窗清單
【Ctrl-A】【0~9】 : 切換不同編號的視窗
【Ctrl-A】【Ctrl-A】: 切換回上一個視窗,就是遙控器來回切換的功能
【Ctrl-A】【K】: 刪除這個視窗
【Ctrl-A】【\】: 刪除所有視窗,並且關閉Screen
【Ctrl-A】【g】: 取消畫面閃動提示
【Ctrl-A】【n】: 切換到下一個視窗
【Ctrl-A】【p】: 切換到上一個視窗
底下是Screen指令大全:

Key Action Notes
Ctrl+a c new window
Ctrl+a n next window
Ctrl+a p previous window
Ctrl+a “ select window from list
Ctrl+a Ctrl+a previous window viewed
Ctrl+a S split terminal horizontally into regions Ctrl+a c to create new window there
Ctrl+a | split terminal vertically into regions Requires debian/ubuntu patched screen 4.0
Ctrl+a :resize resize region
Ctrl+a :fit fit screen size to new terminal size Ctrl+a F is the same. Do after resizing xterm
Ctrl+a :remove remove region Ctrl+a X is the same
Ctrl+a tab Move to next region
Ctrl+a d detach screen from terminal Start screen with -r option to reattach
Ctrl+a A set window title
Ctrl+a x lock session Enter user password to unlock
Ctrl+a [ enter scrollback/copy mode Enter to start and end copy region.
Ctrl+a ] to leave this mod
Ctrl+a ] paste buffer Supports pasting between windows
Ctrl+a > write paste buffer to file useful for copying between screens
Ctrl+a < read paste buffer from file useful for pasting between screens
Ctrl+a ? show key bindings/command names Note unbound commands only in man page
Ctrl+a : goto screen command prompt up shows last command entered



2010年8月4日 星期三

Apache 執行CGI設定

如果要在Apache的某個網頁資料夾中設定可執行CGI
只要在httpd.conf中加入下列設定即可

Options ExecCGI : 設定此資料夾可執行CGI
AddHandler cgi-script cgi pl : 設定可執行的副檔名
<Directory "/usr/local/httpd-2.2.9/htdocs/web_cgi">
    Options Indexes ExecCGI FollowSymLinks
    AddHandler cgi-script cgi pl
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

2010年7月20日 星期二

程式揭秘:從C/C++程式碼探索電腦系統的運作原理


這本書就如同標題所列,是在探討電腦實際運作的原理。當初在書局翻了一下,發現這本書討論了包括電腦底層、記憶體與指標、x86指令集、OS Memory機制甚至連程式碼最佳化都包含在裡面了。這本書看起來幾乎囊括了CS裡頭有關程式執行的幾個重要的議題。

後來沒過多久,我從學校圖書館中發現這本書並借回來看。實際翻過之後說真的有點失望,這本書並不如我預期的那樣。我想原因可能有下列幾個:

1.這本書畢竟只有400多頁,但是作者卻想完整的探討電腦底層運作的原理。這就造成整本書大多只有點到為止,缺乏更深入的探討。不過這也不能怪作者,畢竟上面那些探討的議題每一個都是可以出一本厚厚的書。

2.在書中使用的工具竟然是Visual C++ 6.0。現在已經2010年了,如果要示範的話應該要用點新的工具,目前還會使用Visual C++ 6.0畢竟是少數吧。

總而言之,如果你是想要完整的瞭解電腦運作原理。建議針對每個議題去讀專門的書會比較好,例如:作業系統、計算機組織、編譯器、組合語言等這些基礎科目,要是你真的能完全瞭解上面的這些科目,相信你對程式怎麼執行應該很清楚才對。這本書有很大一部份內容都是從這幾個科目來的。如果你是C/C++新手的話,那這本書就完全不適合你了。你可能會被一堆內容搞得眼花撩亂,偏偏這本書又沒有詳細解釋每個議題,看完這本書只會使你更混亂。



2010年6月19日 星期六

現代嵌入式系統開發專案實務


最近從圖書館借到這本書來看,花了兩天時間看完
書中講解一個菜鳥實際開發專案的過程
利用和主管問答的方式,很輕鬆的講解了嵌入式系統開發會遇到的問題
有些地方真的是感同身受
想想過去這一年我也是像這位菜鳥一樣不太懂嵌入式系統
書中菜鳥的問題,同時也是我這一年中時常碰到的問題
這些東西都不是上課可以學到的
一定要自己實際開發過嵌入式系統才能體會
看完後對嵌入式系統有整個融會貫通的感覺

總而言之,很推薦有心想走嵌入式領域的新手看看這本書
作者用很輕鬆的方式講解整個嵌入式系統的開發流程和複雜的觀念
看完之後一定會對整個嵌入式系統的來龍去脈有初步的認識

書中另外有提到一個重點,CS基礎科目的重要性
要解決嵌入式系統各種奇怪的問題
不二法門就是把計算機組織、作業系統這些基本科目學好!