2010年8月11日 星期三

kernel development tutorials

http://www.jamesmolloy.co.uk/tutorial_html/1.-Environment%20setup.html

do{} while(0) 用法

轉自酷!學園

首先 inline 只有 c++ 才有,linux kernel source 基本上不大可能使用 inline 方式語法,只能夠使用 define 這類 c 與 c++ 都可以支援方式。

define 的許多問題我想大家應該知道,常見像是:

程式碼:
#define sq(a) (a*a)

這表示自己次方,一般使用上沒問題,像是:

程式碼:
int answer = sq(5); // 答案是 25

但是這樣用就死了...

程式碼:
int answer = sq(5+1) // 答案不是 36 啊.....

因為實際上是 5+1 * 5+1 ==> 5+5+1 = 11

所以要改成:

程式碼:
#define sq(a) ((a)*(a))

在 inline 內這類問題都不會發生就是...

拉回來,至於你說的問題....

程式碼:
#define function(x) do{...}while(0)

這寫法也是有特殊的意義,記得應該是 linux kernel FAQ 有寫.

程式碼:
#define swap(x,y) { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; }

但是這樣使用遇到這種情況會有問題:

程式碼:
if ( x > y )
  swap(x,y);
else
  otherthing();

但是程式碼展開就會....

程式碼:
if ( x > y )
   { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; };
else
  otherthing();

有無看到問題點?

程式碼:
if ( x > y ) {
   int tmp_n ;
   tmp_n = x
   x = y
   y = tmp_n;
  }
; <---- 這邊多分號,慘了 ~~~~
else
  otherthing();

這導致會編譯錯誤,因為 else 算是多出來的,已經不是與 else 配對的...

基於這個原因,所以才引入 function(x) do{...}while(0) 來解決

#define swap(a,b) do { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; } while(0)

那展開使用就是

程式碼:
if ( x > y )
   do {
                int tmp_n ;
                tmp_n = x;
                x = y;
                y = tmp_n;
          } while(0);
else
  otherthing();

這樣就不會出包了....

gcc與OS - User space/Kernel space

http://www.study-area.org/cyril/opentools/opentools/x952.html

Multitasking

http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html

Memory Barrier


Memory Barrier

static inline void barrier(void) { asm volatile("": : : "memory"); } 格式 : __asm__(組合語言:輸出:輸入:修飾詞") __volatile__ 代表這行指令(這些組合語言),不和前面的指令一起最佳化。 "memory" 告訴GCC這些組合語言會改變所有的RAM的資料。 因為沒組合語言,又告訴gcc所有RAM的內容都改變,所以這個memory barrier的效用,會讓這行之前被gcc所cache到暫存器的資料通通寫回RAM裡面,也告訴gcc會讓之後讀取RAM的資料,必須再從RAM裡讀取出來。