上個學期還好,上OS一的時候每個禮拜都覺得很有趣,而且老師每次提問題或是講到一個段落就會讓同學休息討論,不過這樣課程進度就有點慢了,但是那時候還是覺得:OS真的很有趣!!我終於了解OS內部的理論還有運作的機制了!
不過這個學期開始就…
一開始講的是μC/OS-II,雖然算是Linux的一種變形不過一直在講程式碼的話容易無聊,可能這是教材的前端,後面才主要是Linux,不過我覺得可以先大致講一遍,不用講得很深,內部要怎麼實作,主要來講Linux,然後讓他與μC/OS-II來比較當中的機制,比如說μC/OS-II他的scheduler是怎麼拿到最高優先權的task阿等等……,如果有時間的話最後再來深入的講,這樣對於上個學期的課程比較有連接,對有心想學μC/OS-II的同學也讓他們有個底可以開始學習。
每次作業的規定格式都不一樣,這在上一篇文章有講過了。
每次的小考對於上個禮拜的東西都要看一遍,不過如果說幾次的小考裡面有期考題目的概念或著類似的話可以讓同學更加的掌握資訊,上課時也可以透露一下小考可能會考之類的。
這個學期和上個學期比起來的停課次數變多了,但補課次數卻也更多了,且時間都是已經定下來的,我有同學因為星期一是社課一定得去所以少去了不少堂補課,但他就算星期三去也吃不到雞排,我想這不只是少數人的情形,這也引發了不少怨言。可能老師很忙,但是可以的話還是先請系辦或者助教在BBS板上公告或者寄信這樣比較好,不然早上的同學可能很早到結果等了很久又撲了個空,這時節常常下雨,對於這些同學很麻煩。
我想維持良好的教學品質很重要,請助教錄影很好,但是錄影出來的品質可能不是很好…。不過冷笑話也別看得太重,隨意看到幾個就記起來,上課的時候說有辦法提振同學的精神,沒辦法也不要太喪氣XD。
寫在這我不知道老師會不會接納我的意見,不過這是我這個學期的一點心得。
2009年6月18日 星期四
給老師的心得
這個學期的作業心得
(作業一~作業七的作業 + Final Project 心得 + 包含寫blog的心得)
先看作業繳交的格式
作業一:os2009_學號.pdf(寄信)
作業二:學號_OSHW2.doc(寄信)
作業三:[x86-asm] 學號 姓名.doc(寄信)
作業四:學號[systemtap].doc(FTP)
作業五:KGDB_學號.doc(寄信)
作業六:未規定(資料夾用學號)(寄信)
作業七:學號.rar(FTP)
Project:標題 : [OS2009S]學號(寄信+印出來拿到LAB)
可以看到每次作業的規定都不一樣,應該要統一格式及繳交的方法才比較好。
不然一下學號在前面一下學號在後面一下要pdf一下要doc一下用寄信的一下要上傳FTP……
然後每次助教預設的環境都不一樣,可能是Fedora 8,可能是Fedora 10,有些還有Debian 4,不過還好他還是有附Fedora的安裝方法,而且電腦最好預設都要有VMware,用Virtual Box有時候還是滿麻煩的,都要自己尋求解決辦法。
然後blog的心得就是直接修改Html比較好…不然google太強大了,怎麼複製他都可以抓到原來的格式,然後又要對於那些tag修修改改的,不過介面整合的還不錯,就是復原的快速鍵Ctrl+Z長常會一次復原兩個動作...不過可以新增google的小東西來玩,也算是有學到一點點的網頁script。
作業五~作業七 + Final Project
hw5_KGDB
hw6_pthread
hw7_uCOSII
OS_final_project
hw5_KGDB:
先clone一個Fedora 8(用Fedora8的步驟比Fedora 10簡單方便)
設定serial port,virtual box的設定比較麻煩,請看下圖(感謝TaiZai提供)
使用 cat/dev/ttyS0 及 echo [TestMsg] > /dev/ttyS0 測試serial port
下載Linux source,修改make menuconfig
make ; make modules ; make modules_install ; make install
把產生出來的三個檔 vmlinuz-~、initrd-~、System.map-~丟到target端
修改menu.lst開機選單,兩邊都重開,之後host開始對target做debug
gdb /linux-~下的vmlinux
用 l 跳到程式碼區,用 p 印出參數的值就結束。
hw6_pthread:
這個作業使用QT就滿分,感謝強者我同學指導。
對於動作要用slot來控制動作發生時的反應,使用socket來處理連線,對於一個狀態下
如果沒有用QT的話就要處理critical section的問題,要防止兩邊同時對socket寫入及印出。
傳送檔案的時候要先告知對方檔名或是順便告知檔案大小,傳檔時要對訊息的header特別處理以免被誤認為是一般文字。
hw7_uCOSII:
先修改 C:\SOFTWARE\uCOS-II\Ix86L\BC45\OS_CPU_A.ASM 當中,把原來的TickISR改成自己寫的HackISR,在HackISR中寫要CALL的C function
在 C:\SOFTWARE\uCOS-II\EX1_x86L\BC45\SOURCE\TEST.C 當中寫要被CALL的C function,內容自訂,可以加上顏色,顏色的宣告要自己找,不過基本上都差不多,BGND是背景,FGND是前景的顏色,BLINK好像是變亮,例子:PC_DispStr( 0, 4, " Hello! OS HACKED!! Hello! OS ", DISP_FGND_WHITE + DISP_BGND_PURPLE + DISP_BLINK);
我的結果:
OS_final_project:
這個也是開學講過的systemtap,不過這次要求要trace深一點,我一開始不會做,照著reference上面的網址,對一個system call會經過的特定路徑有的kernel function來trace,不過深一點的比如說set一個buffer由於不是kernel function因此就抓不到了,同學說似乎是要去該function所在的地方去trace才能trace到完整的流程。
一開始丟oslab上面的測試code去追蹤do_fork這個function還想說他怎麼卡在那邊很久都沒結果,
後來才知道要觸發才會有東西跑出來,我做的是 sys_sync (同步),測試方法很簡單,就打sync這個command就好了。
如果不確定什麼時候要開始打,可以在用systemtap的時候加上-v的參數,看到Pass 5: starting run就可以開始輸入了。
作業一~四
hw1_Using GDB
hw2_Set_up_servers
hw3_x86_asm
hw4_systemtap
hw1_Using GDB:
一開始沒有講得很清楚,結果還以為程式的bug出在NaN(Not a Number)...結果後來助教公佈說因為原本放出的source code有問題所以修改一下就可以解決NaN。
經由GDB可以看到在一個eval()當中result的值要用float型態轉回去時會出錯因此讓結果錯誤。
hw2_Set_up_servers:
一開始先關閉selinux的服務和防火牆以防止有限制權限之類的情形發生,按照PPT安裝openssh、httpd、vsftpd、samba並分別設定各自的.config檔,samba比較容易有問題。
hw3_x86_asm:
主要就是學會inline組語的寫法、input/output怎麼寫,然後register不能誤用,自己要了解使用的register是拿來幹麼的,用compare & jump來控制flow。
hw4_systemtap:
從助教給的tutorial當中去找各個變數在systemtap當中的意義然後推論出.stp的意思,首先還是要先安裝systemtap比較花時間,然後再從結果去推論自己的想法是不是對的。
patch檔的使用方法
- 為什麼要 patch?
1. 檔案( 版本 )之間的差異,可以指令 diff 儲存在一個 patch 檔案。
2. 若舊版本需要修改,只要將 patch 檔案釋出。
3. 使用者可以指令 patch,配合 patch 檔案中記錄之新舊版差異,將舊版程式更新。
4. 使用者若發現並修正一個程式的臭蟲,簡單、正確的方式是,寄一個 patch 檔案給作者,而不要只是說明修正的地方。
- diff 指令:比對兩個檔案之間的差異,一般是用在 ASCII 純文字檔的比對上。
diff 指令用法:
[root@linux ~]# diff [-bBiqn] from-file to-file
選項:
from-file :檔名,作為原始比對檔案的檔名;
to-file :檔名,作為目的比對檔案的檔名;
# from-file 或 to-file 可以 - 取代, - 代表『Standard input』。
-b :忽略一行當中,多個空白的差異
(例如 "about me" 與 "about me" 視為相同)
-B :忽略空白行的差異。
-i :忽略大小寫的不同。
-q :只列出檔案是否有差異。
-n :以 RCS 格式輸出檔案之差異。
-c (-C NUM) :兩個檔案皆加入差異部分前後 NUM 行,以增加輸出之可讀性。預設 NUM=3。
-u (-U NUM) :加入差異部分前後 NUM 行,以增加輸出之可讀性。預設 NUM=3。
- patch:檔案補丁。需與 diff 配合使用
[root@linux ~]# patch [OPTION]... [ORIGFILE [PATCHFILE]]
選項:
-pNUM :取消 NUM 層目錄。
例如:假設檔名 /u/howard/src/blurfl/blurfl.c
-p0 :代表 u/howard/src/blurfl/blurfl.c
-p4 :代表 blurfl/blurfl.c
-l :忽略空白之差異。
-i PATCHFILE :從 PATCHFILE 讀取補丁。
-o FILE :輸出補丁到檔案 FILE。
-r FILE :輸出錯誤到檔案 FILE。
# 預處理:建立兩個不同版本的檔案 /tmp/test/passwd 與 /etc/passwd。
[root@dywHome2 ~]# mkdir /tmp/old; cp /etc/passwd /tmp/old
[root@dywHome2 ~]# mkdir /tmp/new; cp /tmp/test/passwd /tmp/new
# 建立補丁檔案 /tmp/test.patch 記錄新舊檔案之間的差異。
[root@dywHome2 ~]# cd /tmp ; diff old/ new/ > test.patch
# diff 製作檔案時,舊的檔案必須是在前面,亦即是 diff oldfile newfile。
# 將舊的內容 (/tmp/old/passwd) 更新到新版 (/tmp/new/passwd) 的內容
[root@dywHome2 tmp]# cd /tmp/old
[root@dywHome2 old]# patch passwd -i /tmp/test.patch
patching file passwd
# 選項 -i 亦可省略
# 更新內容,並指定存於 passwd1
[root@dywHome2 old]# patch passwd /tmp/test.patch -o passwd1
patching file passwd
# 內容已更新,若再做一次補丁,系統會詢問是否執行?
1. 預設回答 n(o):系統會將錯誤訊息存在 passwd.rej
[root@dywHome2 old]# patch passwd -i /tmp/test.patch
patching file passwd
Reversed (or previously applied) patch detected! Assume -R? [n] n
Apply anyway? [n] n
Skipping patch.
2 out of 2 hunks ignored -- saving rejects to file passwd.rej
2. 回答 y(es):系統會將更新後的內容存在 passwd.orig
[root@dywHome2 old]# patch passwd -i /tmp/test.patch
patching file passwd
Reversed (or previously applied) patch detected! Assume -R? [n] y
3. 查詢檔案
[root@dywHome2 old]# ll passwd*
-rw-r--r-- 1 root root 1207 Apr 16 13:14 passwd
-rw------- 1 root root 1156 Apr 16 13:10 passwd1
-rw-r--r-- 1 root root 1156 Apr 16 13:11 passwd.orig
-rw-r--r-- 1 root root 149 Apr 16 13:12 passwd.rej
˙實例:
假設我們有兩個檔案,分別是 expatch.old 與 expatch.new ,他們的內容是這樣的:
[root@linux ~]# vi expatch.old
echo "check your postfix's body and header drop settings"
echo "postmap -q - regexp:header_checks <>
兩個檔案的不同點在於:
[root@linux ~]# diff expatch.old expatch.new
2c2
<> echo "postmap -q - regexp:header_checks <> echo "postmap -q - regexp:body_checks <>
上面顯示出兩個檔案的不同點。假如我以『 diff -c expatch.old expatch.new 』以及上面顯示的資訊,做成一個檔案,內容是這樣的:
[root@linux ~]# diff -Naur expatch.old expatch.new > expatch.patch
[root@linux ~]# vi expatch.patch
--- expatch.old 2005-09-30 15:47:54.000000000 +0800
+++ expatch.new 2005-09-30 15:48:06.000000000 +0800
@@ -1,5 +1,5 @@
echo "check your postfix's body and header drop settings"
-echo "postmap -q - regexp:header_checks <>
注意到,這個檔案的第一行顯示出舊版本的檔名,而第二行則為新版本的檔名與時間, 第三行以後則是兩個檔案的差異性。那麼我們將以 patch 來進行更新,將 expatch.old 更新到 expatch.new 看看。patch 的基本語法是這樣的:
patch -p數字 <>[root@linux ~]# patch -p0 <>
# 注意喔,這個時候我的工作目錄底下會存在 expatch.old 才對!
# 然後立刻察看一下,您會發覺, expatch.new 與 expatch.old 變成一模一樣的了!
很容易瞭解吧!
[ref] : patch程式
鳥哥的 Linux 私房菜 - 利用 patch 更新原始碼
vim的其他設定(2)
上一篇講的是vim的一些基本設定,都可以加在~/.vimrc當中
這篇講的是一些其他的設定
1. VIM 開啟檔案時, 自動到上次開啟的行數
手動回上次開啟檔案的行數
vim 開啟 file 後:手動按 `" 即可.
自動回上次開啟檔案的行數
每次開啟檔案, 都回復到上次的行數, 於 .vimrc 加入此段即可:if has("autocmd")
autocmd BufRead *.txt set tw=78
autocmd BufReadPost *
\ if line("'\"") > 0 && line ("'\"") <= line("$") | \ exe "normal g'\"" | \ endif endif
2. Vim 使用 Ctrl-K 輸入特殊符號
以下是幾個比較常見的特殊符號(大小寫有分別,所以要注意)Ctrl-K + << = « Ctrl-K + >> = »
Ctrl-K + Ct = ¢
Ctrl-K + SE = §
Ctrl-K + Co = ©
Ctrl-K + Rg = ®
Ctrl-K + +- = ±
Ctrl-K + 2S = ²
Ctrl-K + 3S = ³
Ctrl-K + '' = ´
Ctrl-K + DO = $
Ctrl-K + At = @
更多用法請見reference : vim文件的diagraph-table部份
3. 讓 Vim、Screen 支援 256 色
此篇設定於 Windows(putty) / Linux 都適用.
在 Linux 很少用 Gvim, 但是又覺得 Gvim 的顏色很不錯, 都想是因為 Terminal 的 Vim 只支援 16色, 原來 Terminal 的 Vim 早就支援 256 色了.
設定 Vim 支援 256 色
Vim 設定使用 256 色很簡單, 只要在 .vimrc 加一行設定就完成了.1. vim ~/.vimrc
2. set t_Co=256 加這行即可
但是設完後, 一直沒有作用, 離開 Screen 才發現 256 色有出現, 是 Screen 沒有支援 256 色的問題, 所以再來設定讓 Screen 支援 256 色.
設定 Screen 支援 256 色
Screen 設定 256 色的模式, 主要是 xterm 的問題, 設法也是一行就解決了.vim ~/.screenrc
termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm' # 開啟 256 色模式
這樣子就完成 Vim、Screen 的設定囉~ 於是就可以在 .vimrc 試試各種配色設定, ex:colorscheme darkblue
colorscheme desert
colorscheme default ... 等.
[ref] : Tsung's Blog
Vim document: diagraph
vim的其他設定
1. 先來一張vi/vim的中文圖解鍵盤按鍵圖~(by jserv 原連結->http://jserv.sayya.org/misc/vi-vim-cheat-sheet.png)
這張圖實在很實用!
2. vim的設定檔:vimrc 位置在
~/.vimrc
~/.gvimrc GUI 版本
$VIM/vimrc
$VIM/gvimrc GUI 版本
各種 set 功能說明:autoindent(ai)
自動縮排,也就是說如果本行是從第五個字元開始寫的,您按 Enter
後游標就會停在次行第五個字元處。預設是不打開的。cindent(cin)
寫 C 時很好用,indent 比一般敏感,專為 C 程式碼而設。預設 off。
編輯 C/C++ code 時會自動打開。cmdheight(ch)
狀態列的行數,預設一行,建議設成兩行。compatible(cp)
設為和原始 vi 相容的狀態,vim 的擴充功能會被抑制。預設 off。hlsearch(hls)
尋找時,符合字串會反白表示。預設 off。如果您是使用 vim 的
預設的 vimrc 檔的話,會設在 F8 鍵來切換。ruler(ru)
會在狀態列顯示游標所在處之行列狀態,預設不打開,但建議打開。
最右邊之代號的意義如下:
Top 檔案第一行在螢幕可見範圍。
Bot 檔案最後一行在螢幕可見範圍。
All 檔案首尾皆在一個螢幕範圍內。
如非以上三種情形,則會顯示相對百分比位置。shiftwidth(sw)
指由 >> 移動整行內容時,一次移動的字元寬度,一般是使用 Tab 的
值,但可由這個設定來改變。showmode(smd)
在狀態列顯示目前的模式,例如是 Insert mode 或是 Visual mode。
當然平常的 normal mode(commond mode)是不顯示的。number(nu)
顯示行號。注意,冒號命令也有 :nu 這是顯示游標所在行的行號,您
嫌多打一個字的話,:# 也行。不過如果 ruler 打開的話,在狀態列本
就會顯示目前游標所在處的行列值。fileencoding(fe)
首先先鼓掌一下,啪啪啪…,因為有支援 taiwan,也支援 XIM,也
就是說可以使用 xcin-2.5x 來作輸入,當然您用 xcin-2.3x 配合
XA 也是可以啦!目前支援簡繁中文、日文、韓文,unicode 尚未植
入。但前提是您要把 multi_byte 編譯進去,這在一開始就講過了。
預設是使用 ansi。softtapstop(sts)
幾乎所有的 OS 及軟體都設定 Tab 就是 8 個字元長,這已經是個公認值,您硬要去改變它的話恐怕帶來許多不便,但實際上關於程式風格,許多人又認為 8 個字元太長了,幾個巢狀迴圈下來就需折行,反而不方便。因此 vim 體貼您,內建了 softtabstop 的功能,就是由 vim 來代您製造出一個假的 Tab,實際上是空白字元組成的 Tab。
舉個例子來說明比較清楚。
set softtabstop=4
set shiftwidth=4
這樣會由 4 個空白字元取代一個 Tab,您按 Tab 鍵 vim 就跳 4 格,需注意的是,如果您按了三次 Tab 鍵,那就是一個實際的 Tab 加上四個空白字元,可不是 12 個空白字元喔!是混合 Tab 及 space 的。
問題來了!那我要按真正的 8 字元的 Tab 時怎麼辦?簡單,還記得怎麼按特殊字元嗎? Ctrl-v Tab 或 Ctrl-v I 就可以了,那就是如假包換的 8 字元長之 Tab。當然,您按兩次 Tab 不就得了!:-)
[ref] : 大家來學VIM
2009年6月14日 星期日
bash介紹(2)
bash當中如有用到色碼,有時候會發現如果打的是較長的指令,有時候會發生換行錯誤的問題,如:
若繼續打字下去會變成root@localhost> dddddddddddddddddddddddddddddddd
可以發現的是,第一行最前面的提示字元被蓋住了也沒有正確地換行,正確的應該是:dddddddddlhost> dddddddddddddddddddddddddddddddd
root@localhost> dddddddddddddddddddddddddddddddddddddddd
如果是 bash 的 line-wrap 的問題可以使用
$> shopt -s checkwinsize
或是把下面這行加在 ~/.bashrc 裡
echo "shopt -s checkwinsize" >> ~/.bashrc
來打開 winsize 的功能
但也有可能是另一種情形:設定變數PS1又加上跳脫字元所產生的計算錯誤
解法:
在色碼前後加上\[和\]才不會產生計算錯誤,如:
PS1='\033[01;34m\u@\033[01;31m\h \$'
要改為
PS1='\[\033[01;34m\]\u@\[\033[01;31m\]\h \$'
以下是一個簡單的 .bashrc :
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias ll='ls -al'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
export LS_OPTIONS='--color=auto'
eval `dircolors`
alias ls='ls $LS_OPTIONS'
#Define some colors first:
red='\e[0;31m'
RED='\e[1;31m'
green='\e[0;32m'
GREEN='\e[1;32m'
yellow='\e[0;33m'
YELLOW='\e[1;33m'
blue='\e[0;34m'
BLUE='\e[1;34m'
purple='\e[0;35m'
PURPLE='\e[1;35m'
cyan='\e[0;36m'
CYAN='\e[1;36m'
white='\e[0;37m'
WHITE='\e[1;37m'
gray='\e[1;30m'
NC='\e[0m' # No Color
# --> Nice. Has the same effect as using "ansi.sys" in DOS.
# Looks best on a black background.....
echo -e "${gray}This is BASH ${white}${BASH_VERSION%.*}${gray} - DISPLAY on
${white}$DISPLAY${NC}" date
if [ -x /usr/games/fortune ]; then
/usr/games/fortune -s # makes our day a bit more fun.... :-)
fi
function _exit() # function to run upon exit of shell
{
echo -e "${WHITE}Good bye, root!${NC}"
}
trap _exit 0
#---------------
# Shell prompt
#---------------
function fastprompt()
{
unset PROMPT_COMMAND
{
LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g")
TIME=$(date +%H:%M)
}
case $TERM in
*term | rxvt )
PS1="[\[${WHITE}\]\$TIME]\[${YELLOW}\]\u\[${GREEN}\]@\[${CYAN}\]\w> \[$NC\]"
;;
linux )
PS1="${cyan}[\$TIME - \$LOAD]$NC\n[\h \#] \w > " ;;
* )
PS1="[\$TIME - \$LOAD]\n[\h \#] \w > " ;;
esac
}
fastprompt
[ref] : bash在終端機上換行的問題
The Non-Annoying Terminal Mini How-To & Fun with shopt
bash介紹
設定檔通常會放在家目錄 (~/)下面,看自己 shell 的方法為
$> echo $SHELL
- .bash_login
.bash_login 源自 C shell 的 .login、.profile 源自 Bourne shell 的 .profile,兩者對於 bash 的意義相等。
當使用者 login 進來的時候,如果設定的 shell 是 bash 則會依照 .bash_profile > .bash_login > .profile 讀取,讀取到其中一個之後就會跳過剩餘的讀取。
[NOTE]
修改完 .bash_profile 完並不能立即看到結果,快速的方法是直接下 command 重新執行 .bash_profile 中所寫的命令。
$> source .bash_profile
- .bashrc
當在命令列上執行 bash 時,bash 會去讀取 .bashrc 檔,用途在將登入系統時執行的命令跟執行subshell 所需執行的命令區隔開來。
$> source .bashrc
或是將以下code加在 .bash_profile 中:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
如此可以讓 login 時也會去讀取 .bashrc 的內容
- .bash_logout
顧名思義,logout 時就會去執行 .bash_logout 中所寫的命令,較少見。
一般為拿來清除一些紀錄檔或是紀錄登出的狀態。
[ref] : Bash - DebianWiki