我想接觸 kernel 的人一定聽過或看過 Understanding the Linux Kernel 這本書,這本書也已經堂堂進入到第三版了,今天下午到天瓏去逛了一下書局,順便看看最近有什麼值得買的工具書,意外的發現原來 Understanding the Linux Kernel 第三版竟然有中譯本這個月(2006/8)出版了,而且翻的還不錯(至少對於英文不好的我是這麼認為的),相信對於要更瞭解 kernel 的玩家絕對是個好消息。
印象中,前兩版似乎沒有中譯本,而第三本才有中譯本出來,而且還是這個月出版的,但意外的天瓏並沒有將他擺到門口進來的新書區(或者我沒看到?),我還是在中段的 Unix/Linux 這區才發現他的蹤跡,至少是放在書台上而不是在架上,當下看到是蠻心動的但礙於身上盤纏不足,就先寄放在店家吧...
不過有另一本上奇出版 The Linux Kernel Primer: A Top-Down Approach for x86 and PowerPC Architectures 也是翻譯書(書名:The Linux Kernel Primer 中文版),當然他的主打是針對較為高階的 kernel maintainer,但是在書的一開始前兩章介紹了很多 kernel 裡面的 data structure ,例如 kernel 裡面用到最多的 LIST 系列的 macro & function 都有詳細的圖文說明也非常適合入門的新手,可以很容易瞭解到這些 data structure 的使用
...
Read more.
Tuesday, August 29, 2006
Tuesday, August 15, 2006
[+/-] : IP address & network order
雖然我知道 Network order 與 Host order 的關係不見得一樣,在一般 Host (windows/linux) 的 order 和 Network order 剛好相反,而 Apple 的系統 OS 則與 Network order 一樣(現在新的 0S X 之後以 Unix/Linux 為 base 的系統我就不清楚了,不過既然以 Unix/Linux 為 base,那應該和一般的 Unix/Linu order 一樣吧)
為什麼要特別一提呢?我發現真正要用的時候自己還是忍不住寫個小程式測試一下....用最簡單的例子,我們計算數學時,當數字發生進位的情況,進位的數字會往前加,而前面是那邊呢?沒錯,就是左邊,以這方向來看,越左邊數字代表含意越大,這表示方式就跟 Network order 一樣,而相反,越右邊表示越大則就跟 Windows/Linux 的 Order 一樣,後面提到 Host order 皆以 windows/linux 情況來討論
而一般 IP 表示法都是用 4 個 1Byte 的十進位數字來表示,所以數字範圍在 0~255 之間,所以當 127.0.0.1 以 4Byte 來存放並以「數字」方式解析就會變成
最後得到 0x7F000001 ,這表示法就是 network order,而如果以 Host order 來看就成了 0x0100007F 了,也就是 Host order 真正擺在記憶體的順序是如此
在 C 我們常常用的技巧就是將 4Bytes 的 unsigned int 透過 cast 方式變成 4 個 entry 的 unsigned char array,這時候就容易搞混到底我要改 127.0.0.1 的 127 是在 index 0 還是 index 3 的 entry,直覺一點的記法,當出現在第一個,就是在 array 的第一個位置,同理在第四個就是在 array 第四個位置,這時不要再考慮 order 問題反而會把自己搞混..
寫個小程式來測試一下
...
Read more.
為什麼要特別一提呢?我發現真正要用的時候自己還是忍不住寫個小程式測試一下....用最簡單的例子,我們計算數學時,當數字發生進位的情況,進位的數字會往前加,而前面是那邊呢?沒錯,就是左邊,以這方向來看,越左邊數字代表含意越大,這表示方式就跟 Network order 一樣,而相反,越右邊表示越大則就跟 Windows/Linux 的 Order 一樣,後面提到 Host order 皆以 windows/linux 情況來討論
而一般 IP 表示法都是用 4 個 1Byte 的十進位數字來表示,所以數字範圍在 0~255 之間,所以當 127.0.0.1 以 4Byte 來存放並以「數字」方式解析就會變成
127x16^3 + 0x16^2 + 0x16^1 + 1x16^0
最後得到 0x7F000001 ,這表示法就是 network order,而如果以 Host order 來看就成了 0x0100007F 了,也就是 Host order 真正擺在記憶體的順序是如此
在 C 我們常常用的技巧就是將 4Bytes 的 unsigned int 透過 cast 方式變成 4 個 entry 的 unsigned char array,這時候就容易搞混到底我要改 127.0.0.1 的 127 是在 index 0 還是 index 3 的 entry,直覺一點的記法,當出現在第一個,就是在 array 的第一個位置,同理在第四個就是在 array 第四個位置,這時不要再考慮 order 問題反而會把自己搞混..
寫個小程式來測試一下
#include
#include
int main()
{
struct in_addr addr;
addr.s_addr = inet_addr("127.0.0.1");
printf("==>%u.%u.%u.%u\n",
((unsigned char *)&addr.s_addr)[0],
((unsigned char *)&addr.s_addr)[1],
((unsigned char *)&addr.s_addr)[2],
((unsigned char *)&addr.s_addr)[3]);
printf("===>%8x\n", add.s_addr);
}
...
Read more.
Sunday, August 13, 2006
[+/-] : System.map 變革與多 kernel 並存
在 nctuns engine 的 裡面,mykvm.cc 會負責在 System.map 尋找要做 memory mapping 的 key word ,而這檔案會根據不同 release version 而命名,因此之前的作法都是在 package 的 install.sh 將 System.map-$KERNELVERSION link 成 System.map,而在之後 20060503 之後的版本我又將其 link name 改成 System.map-nctuns
雖然如此可以區別原使用者已經存在 System.map 檔案情況下,但當有不同版本 kernel 同時在開發時(這次我就是一次 porting 到 2.6.16.1 之後又 porting 到 2.6.17.8)還是會造成錯誤,我這次porting 到 2.6.17.8 一開始一直發生 panic ,後來才發現 System.map-nctuns 是 link 到舊版本 (2.6.16.1) 的檔案,所以造成 memory mapping 錯誤的情況
因此現在將這段 code 改成如下:
如此一來,nctuns engine 就會根據目前開機所使用的 engine 來讀取對應的 System.map 檔案,減少多版本存在時錯誤的發生。
...
Read more.
雖然如此可以區別原使用者已經存在 System.map 檔案情況下,但當有不同版本 kernel 同時在開發時(這次我就是一次 porting 到 2.6.16.1 之後又 porting 到 2.6.17.8)還是會造成錯誤,我這次porting 到 2.6.17.8 一開始一直發生 panic ,後來才發現 System.map-nctuns 是 link 到舊版本 (2.6.16.1) 的檔案,所以造成 memory mapping 錯誤的情況
因此現在將這段 code 改成如下:
#include <sys/utsname.h>
…
…
Off_t search_kvm(char *name)
{
…
…
struct utsname version;
if (uname(&version) < 0) {
perror(“uname”);
exit(1);
}
sprintf(path, “/boot/System.map-$s”, version.release);
Pt = fopen(path, “r”);
…
}
如此一來,nctuns engine 就會根據目前開機所使用的 engine 來讀取對應的 System.map 檔案,減少多版本存在時錯誤的發生。
...
Read more.
Thursday, August 10, 2006
[+/-] : make rpm landmine & kernel.spec
kernel source 的 Makefile 寫的好是眾所皆知的,但我還是採到地雷了….
首先先說明一般 source 編譯過程,從 http://www.kernel.org/ download source code 下來之後,解開來依序做完下面的事情重開機應該就可以看到他出現在你的 grub 選項裡了:
因此當我已經有 kernel.spec file 之後,在修改上面提到任一檔案的話,再重新做 make rpm並不會檢查 version 資訊更改而重新建出 kernel.spec,因此過程中就會有 error 產生,所以這時就得先刪掉 kernel.spec 再重來一次..@@
為了這問題搞掉我兩個小時的時間….
此外為了讓 NCTUns engine 讀取的 /boot/System.Map-nctuns 可以在安裝 rpm 就自動產生,本來試圖在 kernel.spec 中加入建立 link 的動作,但發現這樣做在編 rpm 都會有找不到檔案的訊息發生,最後不得已只好採用「再多複製一份」的方式,將 System.map-$KERNELRELEASE 複製一份成 System.map-nctuns
...
Read more.
首先先說明一般 source 編譯過程,從 http://www.kernel.org/ download source code 下來之後,解開來依序做完下面的事情重開機應該就可以看到他出現在你的 grub 選項裡了:
- make menuconfig
- make (這指令會做 make modules && make bzImage)
- make modules_install
- make install
- 完成重開
因此當我已經有 kernel.spec file 之後,在修改上面提到任一檔案的話,再重新做 make rpm並不會檢查 version 資訊更改而重新建出 kernel.spec,因此過程中就會有 error 產生,所以這時就得先刪掉 kernel.spec 再重來一次..@@
為了這問題搞掉我兩個小時的時間….
此外為了讓 NCTUns engine 讀取的 /boot/System.Map-nctuns 可以在安裝 rpm 就自動產生,本來試圖在 kernel.spec 中加入建立 link 的動作,但發現這樣做在編 rpm 都會有找不到檔案的訊息發生,最後不得已只好採用「再多複製一份」的方式,將 System.map-$KERNELRELEASE 複製一份成 System.map-nctuns
...
Read more.
[+/-] : 為何新版 kernel 使用 select 沒反應
這次porting在軍事網路這邊花的很多時間才搞定,原因主要出在select沒有反應!?
以往在舊的 kernel 中,使用 select 的 library 時,第一個參數需給定要 monitor的socket最大值加一,代表後面的 fd_set 要看多「長」,而以往較偷懶的寫法會將這值直接給一個較大的值,例如給個 4096 如此一般,進到 kernel 後會根據這個 task 的 file descriptor table 的最大值自己做修正
但測試新的kernel (2.6.16.1) 發現過大的值竟然會產生 bad file descriptor 的訊息,而在 nctuns code 裡面是直接給定 nfds = 4096 ,如此就一直產生 error ,所以一直沒有反應..
在 command_server.c 裡 cmd_server::checkIPCmessages() 將 select 的部分改以自己計算已經開啟過 socket 的最大值加一就回復正常了…
...
Read more.
以往在舊的 kernel 中,使用 select 的 library 時,第一個參數需給定要 monitor的socket最大值加一,代表後面的 fd_set 要看多「長」,而以往較偷懶的寫法會將這值直接給一個較大的值,例如給個 4096 如此一般,進到 kernel 後會根據這個 task 的 file descriptor table 的最大值自己做修正
但測試新的kernel (2.6.16.1) 發現過大的值竟然會產生 bad file descriptor 的訊息,而在 nctuns code 裡面是直接給定 nfds = 4096 ,如此就一直產生 error ,所以一直沒有反應..
在 command_server.c 裡 cmd_server::checkIPCmessages() 將 select 的部分改以自己計算已經開啟過 socket 的最大值加一就回復正常了…
...
Read more.
Subscribe to:
Posts (Atom)
