說明 shell 基本 command,後面有一些 system mantain 的command 介紹,當然也有shell script的教學。
是 CC 授權的電子書。
ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上
真誇張:最後是 這一篇 王聰 先生的blog : __umoddi3()的問題 有比較清楚的說明: (copy 一下,以免消失.. 對不起)busybox -- qemu boot with preload kernel -- ref jserv's tutorial -- build kernel fail -- workaround on CFLAG -- GCC 4.3 problem -- GCC 4.3 optimize functions -- example test code
繞了好大一圈,已經離 busybox 很遠了..
在編譯內核時有人遇到下面這個問題:
kernel/built-in.o: In function `getnstimeofday':
(.text+0xb6ae): undefined reference to `__umoddi3'
kernel/built-in.o: In function `getnstimeofday':
(.text+0xb6ce): undefined reference to `__udivdi3'
這個問題可以在用戶空間重現,不過不是很容易,我實驗了一下,在i386上,並不是所有的64位整數操作都會被轉化成
調用__umoddi3,gcc bugzilla上有演示程序,如下:
PLAIN TEXT
C:
  1.#define NSEC_PER_SEC  1000000000UL     
  2.int rmg(void);
  3.
  4.int main(void)
  5.{
  6.  /* int sec; */
  7.  return rmg();
  8.}
  9.
 10.int rmg(void)
 11.{
 12.  static unsigned long long nsec = 0;
 13.  static int sec = 0;
 14.  while (sec <1 ) {
 15.    nsec++;
 16.    while (__builtin_expect(nsec>= NSEC_PER_SEC, 0)) {
 17.    nsec -= NSEC_PER_SEC;
 18.    ++sec;
 19.    }
 20.  } 
 21.  return sec;
 22.}
這樣編譯它:% gcc -nostdlib -O2 -o umoddi3 umoddi3.c,就會得到:
/tmp/ccycM684.o: In function `rmg':
umoddi3.c:(.text+0x87): undefined reference to `__udivdi3'
collect2: ld returned 1 exit status
問題重現了。這裡的問題是,對於nsec來說,內層的循環其實等價於求模運算,gcc在優化時發現了這一點,而且硬件
本身也不支持對64位整數直接進行算術運算,所以gcc會把這一步優化成調用內部函數__udivdi3()和
__umoddi3(),這兩個函數在libgcc中(見gcc源代碼 gcc/libgcc2.c),libgcc默認和libc一樣是要被加載
的,但如果我們加了-nostdlib(Linux內核是更好的例子),這個問題就會出現了。
知道原因了,怎麼解決?網上有兩種方法,一種是像這個補丁那樣,在循環中插入下面這條內聯彙編:
asm("" : "+r"(ns));
這句是告訴gcc把ns這個變量放到寄存器中,並且既有讀操作也有寫操作,所以後面再用它時必須重新讀取,這樣就消
除了上面的優化。
另一種解決方法是添加新的編譯選項:-fno-tree-scev-cprop,這個選項似乎沒有文檔,至少我沒找到。說說它的
大體意思。scev 應該是SCalar EVolutions,什麼意思不知道。:( cprop應該是Copy PROPagation,這個應
該很容易理解,就是賦值的傳播,比如:
i = 10;
a = i;
b = i;
其實就是:
a = 10;
b = 10;
可見,編譯優化是門大學問,寫個編譯器絲毫不比寫個內核容易。:-P
============王聰先生的文章copy到此==============
cc1: error: unrecognized command line option "-mregparm=3" cc1: error: unrecognized command line option "-maccumulate-outgoing-args" arch/i386/kernel/asm-offsets.c:1: error: bad value (i686) for -march= switch make[1]: *** [arch/i386/kernel/asm-offsets.s] Error 1 make: *** [prepare0] Error 2原因呢?就跟 error 講的一樣.. -mach 錯了。 所以 用 export 查一下環境變數,果然有定義:
declare -x CROSS_COMPILE="arm-none-linux-gnueabi-"unset 掉就OK了...
果然是很無聊的 error 吧.....:(
所以?就是要用 virtual machine 來作就是?follow how-to,, 但是在 這一版 (1.2) 不一樣的地方: