Linux


之前參考這篇文章

[ubuntu] TFTP Server 安裝

來設定Host的 tftp server 環境,只可惜我怎樣試了又試,還是體會不到成功的快感!

一度以為是防火牆的問題,似乎也不是,inetd 也裝了,就是不給面子。

後來乾脆全部移除掉:

~$:sudo -s

~$:apt-get remove –purge tftpd tftp inetutils-inetd

然後重裝 xinetd 與 tftpd, tftp

~$:apt-get install xinetd tftpd tftp

原先已經系統中還保留舊的 inetd.conf 檔,需要 mark 掉 tftpd 的啟動命令如下:

#tftp        dgram    udp    wait    nobody    /usr/sbin/tcpd    /usr/sbin/in.tftpd /tftpboot

接著用 vim 新增一個檔案:

~$:vim /etc/xinet.d/tftp

檔案內容如下:

service tftp
{
protocol        = udp
port            = 69
socket_type     = dgram
wait            = yes
user            = nobody
server          = /usr/sbin/in.tftpd
server_args     = /tftpboot
disable         = no
}

再來,重新啟動 xinetd(tftpd必須透過 xinetd 這不用廢話了吧,當然也可有standalone的方式):

~$:/etc/init.d/xinetd restart

關於伺服器的目錄設定:

~$:mkdir /tftpboot

~$:chown -R nobody:\  /tftpboot

~$:chmod -R 777 /tftpboot

接著可以利用 client 端程式 tfpt 127.0.0.1 利用 get 指令下載檔案!

#我真的很討厭重複做無聊的事情……………….

意外的發現一件事情,使用指令將某裝置 mount 到根目錄底下以後,然後再 mount 另外一個裝置,例如:

~$: sudo mount -t ntfs-3g /dev/sda1 /mnt

~$: ls          // 將會列出位於 /dev/sda1 裝置裡面的資料

~$: sudo mount /dev/sdb1 /mnt

~$: ls          // 會列出位於 /dev/sdb1 裝置中的資料

然而,上一個掛載的資料似乎被覆蓋掉了,有點像是堆疊的行為,後來掛上去的資料才會顯示出來,

千萬不要以為原先掛載上去的裝置被悄悄的卸載了,利用 df 指令觀察:

~$: df

會發現兩者同樣都掛載在 /mnt 目錄!

既然剛剛說這行為像是堆疊,所以只要把後來的裝置卸載(umount)掉,

原來的檔案就會跑出來見人了~

這看起來是個藏東西的好辦法,透過掛載到相同目錄,原來的資料就會瞬間消失啦~

最近幹點正經事起來了,不過正經事總是比較難搞,我在編譯 Buildroot[*註一] 的時候遇到錯誤訊息如下:

WARNING: `makeinfo' is missing on your system.  You should only need it
if
         you modified a `.texi' or `.texinfo' file, or any other file
         indirectly affecting the aspect of the manual.  The spurious
         call might also be the consequence of using a buggy `make' (AIX,
         DU, IRIX).  You might want to install the `Texinfo' package or
         the `GNU make' package.  Grab either from any GNU archive site.
make[4]: ***
[..............................略/bfd.info]
Error 1

終於,在我細心的爬文後,從 mailing list 找到了解法了,只要將 toolchain_build_arm/ 底下的子目錄

binutils-*-build 移除掉,並執行 make clean ,再度重新執行 make 即可!

  • *1:Buildroot 是一組 Makefile 可以用來輕鬆產生 Toolchain 與 Root Filesystem 並且使用 uclibc 函式庫。安裝可以透過匿名方式存取 svn
    svn co svn://uclibc.org/trunk/buildroot
  • 其他資訊參考:http://buildroot.uclibc.org/

在隨身碟上安裝作業系統並不是一件愚蠢的事,反而現在的隨身碟容量越來越肥,動輒 4G、8G 的,而我最早用來安裝 Linux 的一顆 Transcend 的 1G 隨身碟,要價 $2200 大洋,現在想起來,真的有些呆!

以現在的容量來說,加上目前的電腦應該都支援 USB 開機功能,所以利用任何一種發行版的 Linux 直接把它當成硬碟裝置來安裝,應該都可以,不過那也不需要什麼技術性,只要懂得調整 BIOS 開機優先順序就好了,而我的作法是透過修改 Live CD,變成 Live USB。

需要用到的工具:

  • Live CD:建議是 “PUD Linux” or “slax”
  • syslinux

以在我的工作環境(LinuxMint-Darya/Ubuntu 7.10)為例:

  1. 首先把隨身碟淨空一番,可以用 fdisk 這個指令:
  2. ~$:fdisk -l #找到隨身碟的裝置代號

    原則上我們會以 fdisk 工具來設定分割區:

    ~$:fdisk /dev/sdb #參數為裝置名稱,不需含分割區代號

    接著會進入提示模式,只需依照說明方式即可!

    之後在利用下列指令建立出 FAT16 分割區:

    ~$:mkdosfs /dev/sdb1 #參數需包含分割區代號

  3. 接著安裝 Bootloader – syslinux:
  4. ~$:syslinux /dev/sdb1

    如此一來將會產生 “ldlinux.sys” 這個檔案,必須放在根目錄底下。

  5. 掛載 Live CD 到系統中,並抽取其中的所需檔案:
  6. ~$:sudo mount -o loop ~/pud-0.4.8.5.iso /media/cdrom0 #參數-o loop 掛載映像檔

    可以看到根目錄有如下檔案:

    isolinux/ 目錄下包含了含有開機所需的核心壓縮檔以及 bootloader 說明訊息還有 initrd.img

    必須全部複製到隨身碟的根目錄底下:

    ~$:cp /media/cdrom0/isolinux/* /media/sdb1/

    其他的檔案則可以原封不動的複製到隨身碟上。

  7. 接著更名 isolinux.bin, isolinux.cfg 為 syslinux.bin, syslinux.cfg
  8. ~$:mv isolinux.bin syslinux.bin

    ~$:mv isolinux.cfg syslinux.cfg

    syslinux.bin 是你的 bootloader,而 syslinux.cfg 則是可文字編輯的 syslinux.bin 設定檔案,當使用 vim 打開 syslinux.cfg 可以發現任何一種開機模式的方案下幾乎都會有下列訊息:

    kernel vmlinuz
    append initrd=initrd.img

    vmlinuz 是核心檔,而 initrd.img 是初始化記憶體檔案,並不需要去做更動。

  9. 大致上步驟應該都已經完成,如果不能夠完成或許是主機板的問題,或者可以透過 install-mbr 來試看看!接下來妳只需要利用隨身碟開機試看看即可!

雖然我們這麼辛苦的手動複製、修改這些檔案,但是現有的部份 Live CD 發行版幾乎都有支援圖形化介面,可以直接把 Live CD 整個安裝到隨身碟上而無須任何修改!像是以下兩個發行版都有:

即便如此,我相信會手動的人,還是喜歡自己操作的感覺吧!

我一直認為 Windows 下的網路設定工具相當的好用,而在 Linux 底下可以透過 NetworkManager 這個工具來設定無線網路或者是 Wired Connection 甚至是電話撥接,相當的有親切感!不過對於 ADSL 的撥接用戶來說,你還需要透過其他工具來設定帳號、密碼以及相關設定等!

在 Ubuntu 底下要設定撥接可以透過 pppoeconf :

~$:sudo pppoeconf eth0

注意!後面的 eth0 則是你的網路介面,可以透過 ifconfig 來觀察,而這些介面的參數都紀錄在 /etc/network/interface 之中!

然而 pppoeconf 後面的網路介面參數也是可以留白不加,只是它就會掃描全部的網路介面(除了 LoopBack) 之外,我是覺得挺花時間的啦,所以之後就養成了這個習慣。

搞完一堆選項之後,你就可以透過 pon dsl-provider 來啟動網路,用 plog 來觀察訊息,用 poff 來切斷連線。

不管怎樣,每次使用 pppoeconf 設定帳號以後,預設的設定檔名稱一定都是 dsl-provider ,所以每當我換個地方上網,就要重新執行 pppoeconf 一次,相當的費時費力。

因此我想到一個辦法,就是把 dsl-provider 更名,但這步驟需在你換地方上網之前:

~$: mv /etc/ppp/peer/dsl-provider /etc/ppp/peer/SomePlace

mv 指令可以讓你做更名動作,然後你就可以在執行一次 pppoeconf ,這樣就可以新增一個撥接帳號,也不會被覆寫了!

而要選擇哪一個帳號上網時,只需把設定檔名稱作為 pon 的參數即可:

~$: pon SomePlace

注意!在 Fedora 下似乎沒有 pppoeconf 這工具,設定方式如下:

  1. pppoe-setup:設定
  2. pppoe-start:啟動撥接
  3. pppoe-stop:中斷

先前我從來沒在 Linux 下列印過檔案,因為昨天敗了一台學生特惠機($1190)–D2460,所以就想說來安裝看看,

而我的 HP Compaq 小黑NB的第一次列印,竟然是獻給了 Linux 而不是 Windows!

其實在 X Window 設定印表機的步驟相當簡單,而且這次的無痛安裝經驗相當愉快,連驅動程式光碟都免了,呵!

  1. 首先必須要開啟 cups (Common Unix Printing System) 服務,指令如下:
  2. ~$:sudo /etc/init.d/cupsys start

  3. 接下來你可以用快捷鍵 “alt+F2″ 配上指令:gnome-cups-manager 來開啟印表機管理程式或者從控制中心開啟管理程式,如下圖:
  4. 安裝前只有兩個 Icon ,分別是 “New Printer” 以及 “Print_to_PDF” ,這裡設定方式就跟 Windows 差不多了
  5. 這個步驟會偵測連接到電腦的印表機
  6. 選擇適當的驅動程式,大部分都已經列在清單中,否則就要從光碟片中取得
  7. 由此可以發現新增的印表機已經出現在清單之中了!
  8. 我們也可以從 Firefox 的印表機選單中找到

應該發現,Linux 其實很親近大家,所以要多多推廣才是的~!

在Linux底下砍掉記憶體中的程序(process),其實有很多種方式,

最簡單的方式,就是使用圖形化的「系統監控」程式來砍掉 target,

這是大多數人都能接受的方式,因為在Windows作業系統也通常這麼做!

針對沒有使用 X Window 的使用者而言,要砍掉程序就無法透過上述的工具了,

所以在 shell 底下,透過下列方式來做:

  • 利用 Top 程序觀察器:
  • ~$: kill -s 9 pid
  • killall processname

其實第一個指令的用意,並非純粹只是用來砍掉程序,進一步的說, kill 的用途是送 signal 給程序

詳細的參數可以利用 man kill 來查詢,而可以發現 -s 9 的意義是砍掉程序,所以可以透過該指令加上該程序的 PID ,

就可以砍掉了!至於如何取得該程序的 pid 呢?以emesene為例!

  1. 透過 top :文字介面觀察程式搜尋
  2. ~$: ps -e | grep emesene
  3. ~$:echo $(pidof emesene)

相對的,利用 killall 就顯得簡單多了,只要用 killall 參數以該程序的名稱即可,例如要砍掉 gnome 桌面的工具列,

~$: kill gnome-panel 即可!

thread 可以被認為是使用者程式當中的一個執行流程,Multi-thread process當中還可以包含更多的執行流程!

而在 Unix* 作業系統底下還存在一種特殊的 thread 稱之為 kernel thread(核心執行緒),

kernel thread 未必只有執行核心的某種功能,亦可能與某個 User program 有關係,

然而 kernel thread 與一般的 process 比較起來具有較輕鬆的環境切換代價,通常稱之為 Context switch,

發生在 process 調用 scheduler 進行排程的時候,要把當前 process 所用到的 CPU 資訊給儲存起來,

包含了 Register(暫存器)等等。

因為 thread 屬於簡單的 execution flow 所以每當要進行 Context switch 時,要儲存的資料會比較少,因此負擔會輕一些!

kernel thread 的特性如下:

  • 運作在 Kernel space & Kernel Mode
  • 不與 User 進行互動,因此不需要終端機設備
  • 於系統啟動時期建立,存活到系統關閉為止

在傳統的 Unix 作業系統,偶爾會將一些關鍵的任務委派給執行中的 process ,比如像是 Page swapping、服務網路連線、Disk cache等等之類的。

不過現在的作業系統大多都會把這些任務放在背景去執行,避免使用線性的方式而得到不好的效能,

特別是 kernel thread 只運作在 kernel space 之中,因此這些工作最好都交給 kernel thread 來做最適當不過了!

kernel_thread()函式可以用來建立新的 kernel thread,函式存在 linux/arch/i386/kernel/process.c 之中:

int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
struct pt_regs regs;
memset(&regs, 0, sizeof(regs));

regs.ebx = (unsigned long) fn;
regs.edx = (unsigned long) arg;

regs.xds = __USER_DS;
regs.xes = __USER_DS;
regs.xfs = __KERNEL_PERCPU;
regs.orig_eax = -1;
regs.eip = (unsigned long) kernel_thread_helper;
regs.xcs = __KERNEL_CS | get_kernel_rpl();
regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0×2;

/* Ok, create the new process.. */
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
}
EXPORT_SYMBOL(kernel_thread);

可以看到 kernel_thread() 函式的參數包括:

  • fn:要被執行的核心函式位置
  • arg:該函式的引數
  • 第三個是一組 Clone flags

而在 kernel_thread() 之中可以看到調用了 do_fork() 建立新的process,然而該參數的意義如下:

  • CLONE_VM:避免浪費時間在複製呼叫這個函式的行程的 Page 對映表
  • CLONE_UNTRACED:確保新的 kernel thread 不會被任何行程追蹤
  • pregs 指向了 &regs 這個結構的位址,當中包含了相應於 Kernel Mode Stack 裡面的位址

一些典型的例子,例如 Swapper, init process 都是屬於 kernel thread,雖然在Linux 使用 kernel thread 地方很有限,但是卻是用來執行幾個重要的核心功能。

Ref: Understanding the Linux Kernel 3e

所謂的 Kernel Control Path 指的是一連串的指令,核心用來處理 System Call, Exception, Interrupt

一件例外發生後,比如CPU執行某個 process 發生了 Page Fault 了,

那麼接下來則是一段KCP,用來調回適當的Page,好讓該 process 可以繼續被執行,

原則上,最簡單的情況是,CPU會循序的執行 KCP 從第一個指令,執行到最後一個,

不過 KCP 在以下幾種情況是可以被其他 KCP 插入的:

  1. 當 User-mode 的 process 請求 System call,而未必該 System call 的需求條件滿足了,因此會調用 Scheduler 選擇一個新的 process 來執行,發生了 Context switch,原本的 KCP 被中斷了。
  2. 當系統允許 Kernel Preemption 功能,而且中斷事件發生,並且具有較高優先權的 process 可執行
  3. 若 KCP 是可被中斷的,而且發生了硬體中斷事件,則CPU會轉而處理中斷事件的KCP,等待處理完以後,才回來繼續處理原先的KCP
  4. 執行KCP時,CPU偵測到Exception

每個 Exception 或 Interrupt 事件發生都會引起一個 KCP,

然而Interrupt handler(中斷事件處理器)可以被另外一個 Interrupt handler 中斷,所以KCP可以是巢狀執行的。

因為老闆要求投影片的英文字體要使用 Times New Roman,中文字體要使用標楷體的關係,

又我的編輯環境是 Openoffice + Ubuntu,系統預設是沒有 Times New Roman的,

所以必須要自己增加字型囉!

首先可以從 Windows 作業系統中複製 times.ttfkaiu.ttf 這兩個字型檔,

路徑位置是: C:\windows\fonts\

在Ubuntu中,字型檔案的存放目錄是在 /usr/share/fonts/truetype 底下,

然後在該目錄下建立一個目錄把剛剛的檔案也複製到這裡來

然後執行下列 command,讓 ubuntu 重新讀取字型檔,

vincent~:$ fc-cache -f -v

最後登出即可!

另外,如果覺得這個方式太麻煩,事實上可以透過 apt-get 安裝下列東東

vincent~:$ sudo apt-get install msttcorefonts

裡面包含了11種微軟的英文字型。

至於其他種字型的安裝可以參考這個網站看看!

適用於 GNU/Linux 的字型

下一頁 »