ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

顯示具有 make 標籤的文章。 顯示所有文章
顯示具有 make 標籤的文章。 顯示所有文章

2013年12月3日 星期二

"No such file or directory" -- 可是 file 明明就在

執行一個程式,卻說 :
/bin/sh: no such file or directory
這是因為 loader 無法載入的關係。
並不一定是找不到檔案。

ref: http://unix.stackexchange.com/questions/13391/getting-not-found-message-when-running-a-32-bit-binary-on-a-64-bit-system/13409#13409

When you fail to execute a file that depends on a “loader”, the error you get may refer to the loader rather than the file you're executing.

The loader of a dynamically-linked native executable is the part of the system that's responsible for loading dynamic libraries. It's something like /lib/ld.so or /lib/ld-linux.so.2, and should be an executable file.
The loader of a script is the program mentioned on the shebang line, e.g. /bin/sh for a script that begins with #!/bin/sh. (Bash and zsh give a message “bad interpreter” instead of “command not found” in this case.)

The error message is rather misleading in not indicating that the loader is the problem. Unfortunately, fixing this
would be hard because the kernel interface only has room for reporting a numeric error code, not for also indicating that the error in fact concerns a different file. Some shells do the work themselves for scripts (reading the #! line on the script and re-working out the error condition), but none that I've seen attempt to do the same for native binaries.

ldd won't work on the binaries either because it works by setting some special environment variables and then running the program, letting the loader do the work. strace wouldn't provide any meaningful information either, since it wouldn't report more than what the kernel reports, and as we've seen the kernel can't report everything it knows.

This situation often arises when you try to run a binary for the right system (or family of systems) and superarchitecture but the wrong subarchitecture. Here you have ELF binaries on a system that expects ELF binaries, so the kernel loads them just fine. They are i386 binaries running on an x86_64 processor, so the instructions make sense and get the program to the point where it can look for its loader. But the program is a 32-bit program (as the file output indicates), looking for the 32-bit loader /lib/ld-linux.so.2, and you've presumably only installed the 64-bit loader /lib64/ld-linux-x86-64.so.2 in the chroot.

You need to install the 32-bit runtime system in the chroot: the loader, and all the libraries the programs need. On Debian amd64, the 32-bit loader is in the libc6-i386 package. You can install a bigger set of 32-bit libraries by installing ia32-libs.

這常常發生在, 64 bit 系統,沒有裝 32 bit library,在 run 32bit 執行檔時,...

2011年6月14日 星期二

Write additional rules on Android.mk

上篇,要在 Android.mk 加入某個 rule. 還挺麻煩˙




應用範例是

這樣:



因為用了某
大陸廠的 3g module,然後 usb-uart com port 的 access 說明又不清楚。

只好請他們提供 android 3g script,結果.. 他們就改了 hardware/ril 下的幾個檔。


因為是大陸廠商,所以修改後的 code 當然是不會給 (也還好,因為是 apache license)。


所以拿到的只是幾個 so.




這下就麻煩,要整合進 Android Makefile 里。

用 BUILD_PREBUILT - 結果這個不會建立 dependent ta
rget。
所以make system 會出現 no rule to make ***.so




在 build/core/ 里又找不到適合的 build rule。
所以只好自己寫在 Android.mk 里...

先從 build error 來看:


make: *** No rule to make target `out/target/product/stingy/obj/lib/libstingy.so',
needed by `out/target/product/stingy/obj/EXECUTABLES/rild_intermediates/LINKED/stingyd'
. Stop.

所以知道需要建立的 rule target 是



out/target/product/stingy/obj/lib/libstingy.so :
acp -e hardware/ril/stingy/libstingy.so out/targ
et/product/stingy/obj/lib/libstingy.so



要注意,使
用 Android.mk 中的 LOCAL_MODULE, TARGET_OUT 這些變數,在 #include (XXX) 後,會改變。
所以就直接寫出來..

繼續 make..
error 變成:
make: *** No rule to make target `out/target/product/stingy/system/lib/libstingy.so', needed by `out/target/product/stingy/system/bin/stingyd'. Stop. 所以要再加一個 target: out/target/product/stingy/obj/lib/libstingy.so : out/target/product/stingy/system/lib/libstingy.so : acp acp -e $(MODULE_SRC) $(TARGET_OUT_INTERMEDIATES)/lib/libstingy.so

2011年6月13日 星期一

Android Makefile : findleaves.py

Android 的 make system 由 build/ 下的 Makefile 處理各 subproject 自己的 Android.mk。

build 的 Makefile 處理各 project 的 Android.mk 的方法是:

build/core/main.mk:
subdir_makefiles := \ $(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk) #include $(subdir_makefiles) 看看 build/tools/findleaves.py ,就是把所有目錄的 Android.mk 找出來。

所以之後的 include .. 就把所有的 makefile include 進來..

也就是說..整個 android project makefile 被合併成一個大的 Makefile。

所以...

invoke make 時很慢.. 因為要 run findleaves.py, 還要把所有 Android.mk read 進來。
.... findleaves.py 應該不是主因..

但是

也就是說,所有的 project dep 都在 Makefile 中,所以可以自行 build 任一個 project target.
例如:
$make rild 就會 build hardware/ril/rild



另外,因為各 Project 的 Android.mk 是 Makefile 的一部分,所以可以直接寫 dep rule,不用管 Android build system 的 變數與 script。

run shell command in Android.mk

有時候需要調整一下 project 的 build 動作,所以需要在 Android.mk 中執行一些 shell command。
可以參考 /boot/recovery/updater/Android.mk 的方法
junk := $(shell mkdir -p $(dir $(inc));\ echo $(TARGET_RECOVERY_UPDATER_LIBS) > $(inc).temp;\ diff -q $(inc).temp $(inc).list || cp -f $(inc).temp $(inc).list) 用一個 dummy 的 target (junk) ,把要執行的 shell command 寫進去就可以

2010年10月27日 星期三

insmod : init_module failed (Exec format error)

手動insmod ,結果出現 error,說是 init_module failed (Exec format error).
用 file 看 format 是正確的 arm..

用 hello.ko 測試 build 環境是否 OK -- 一樣也是 Exec format error。

後來重 build uImage,在這個 uImage 上 insmod 就 OK 了 !!

猜是改了 kernel 的 .config,但是確沒有重 build kernel image。

2010年10月26日 星期二

LOCAL_BUILT_MODULE and LOCAL_INSTALLED_MODULE must not be defined by component makefiles

出現在 base_rule.mk

binary.mk dynamic_binary.mk prebuild.mk 都有 include base_rule.mk
在上面的 mk 開頭都加上 $(info in binary.mk) 或 dynamic_binary.mk,,
prebuild.mk..

再 make 一次,發現是 binary.mk include base_rule.mk 後出現 error message.

找 binary.mk
有 dynamic_binary.mk executable.mk ...
猜是 executable.mk



印出來看,是哪一個 variable 被 define..
out/target/product/myBBG/system/bin/unifi_helper build/core/base_rules.mk:112: *** hardware/libhardware_legacy/unifi-linux/unifi_helper: LOCAL_BUILT_MODULE and LOCAL_INSTALLED_MODULE must not be defined by component makefiles. Stop. 另一個是: out/target/product/imx51_BBG/system/bin/unifi_manager build/core/base_rules.mk:112: *** hardware/libhardware_legacy/unifi-linux/os_linux: LOCAL_BUILT_MODULE and LOCAL_INSTALLED_MODULE must not be defined by component makefiles. Stop.



好像是擺放位置的問題:
hardware\libhardware_legacy 目的在 build 出 libhardware_legacy.so
所以該目錄下的 各 folder 都不能再define LOCAL_MODULE.

所以把 unifi_wifi 擺在 hardware/libhardware_legacy 下是不行的

果然,搬移到 external 後 就 OK 了。

2010年6月25日 星期五

Build UML (User Mode Linux) error : asm/user.h not found

build UML kernel 的時候,出現這個 error:arch/um/sys-i386/user-offsets.c:4:22: 錯誤: asm/user.h:沒有此一檔案或目錄查了一下,2.6.23 後改掉了: release notes:Jeff Dike (3): UML - Stop using libc asm/page.h UML - Fix kernel vs libc symbols clash UML - stop using libc asm/user.h

2010年3月16日 星期二

driver module for kernel 2.6

在 LDP (Linux Document Plane) 有一篇文章(http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN245) The Linux Kernel Module Programming Guide有教學: 取得 目前安裝 的 kernel source code: (後來發現不需要 source,只要header就可以 : ref )
$aptitude install linux-source
會 download 在 /usr/src/linux-source-2.6.31.19.tar.bz 然後把他就地解開 - 在 /usr/src 2.6 版的 driver module 要用 kernel source 的 kbuild 系統來 build。 所以要 build driver module,要download kernel source。 詳細的 build 方法在 kernel source code 的 Document\kbuild\modules.txt 有說明。 大概是說,Makefile 只要寫成: obj-m += mymod.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 就可以
如果要 build '另一個 kernel source ' 的 driver module: all: make -C /home/checko/linux-2.6.32.19 M=$(PWD) modules 但是 自己目錄下的 linux-2.6.32.19 要 configure 好。 但是他還是會 complain 說沒有 configure 好, ERROR: Kernel configuration is invalid. include/linux/autoconf.h or include/config/auto.conf are missing. Run 'make oldconfig && make prepare' on kernel src to fix it. run 過 make oldconfig && make prepare 後,又說找不到 : Building modules, stage 2. MODPOST 1 modules /bin/sh: scripts/mod/modpost: 沒有此一檔案或目錄 make[2]: *** [__modpost] Error 127 make[1]: *** [modules] Error 2 make[1]: Leaving directory `/home/checko/linux-2.6.32.9' make: *** [all] Error 2 所以就要buld script 出來: make scripts這樣再 make module就 OK 了
到 /lib/modules/$(shell uname -r)/ 去看,可以看到 build link 到 /usr/src/linux-headers-$(shell uname -r) .config 就在這個 folder 裡。
所以..實際上只需要 linux-header 就可以?
的確,有linux-header 就可以。不需要 linux-source .config 也可以在 /boot 下找到,只是檔名變成 config-`uname -r`
make 完 install 的時候如果fail 可以 dmesg 出來看 eror message。 如果是: no symbol version for module_layout 大概是你的 kernel source 和你的 running kernel 版本不一樣吧..
在 debian, ubuntu 下就要 apt-get update, upgrade 一下。

有關教學的補充: cat 的 sample.. 在 insmod 完後,用 dmesg 看一下取得的 Major number 是多少 (我的是251)。 然後用 mknod /dev/chardev c 251 0 建好 device node。 然後才可以用 cat /dev/chardev 呼叫到 device_read( ) function。

2010年2月25日 星期四

kernel building error on gcc 4.3 - __umoddi3()

真誇張:
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 很遠了..
最後是 這一篇 王聰 先生的blog : __umoddi3()的問題 有比較清楚的說明: (copy 一下,以免消失.. 對不起)

以下 copy 自 王聰 先生的 blog 文章:
===========================================================
在編譯內核時有人遇到下面這個問題:

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到此==============

無聊的 kernel build error -- 自找的

算是很無聊的 build kernel 錯誤訊息:
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 吧.....:(

2009年7月3日 星期五

gnu make 的 call function

這只是節錄 nmake 的 documentation:
The syntax of the call function is:    
$(call variable,param,param,...)
make 執行這道命時,會賦予param...一個暫時的變數名稱 $(1), $(2), etc. 變數 $(0) 則是 variable.

Then variable is expanded as a make variable in the context of these temporary assignments. Thus, any reference to $(1) in the value of variable will resolve to the first param in the invocation of call.

If variable is the name of a builtin function, the builtin function is always invoked (even if a make variable by that name also exists).

examples

This macro simply reverses its arguments:

reverse = $(2) $(1)
foo = $(call reverse,a,b)

foo 會是 `b a'.

This one is slightly more interesting: it defines a macro to search for the first instance of a program in PATH:

pathsearch = $(firstword $(wildcard $(addsufix /$(1),$(subst :, ,$(PATH)))))
LS := $(call pathsearch,ls)

Now the variable LS contains /bin/ls or similar.

The call function can be nested. Each recursive invocation gets its own local values for $(1), etc. that mask the values of higher-level call. For example, here is an implementation of a map function:

map = $(foreach a,$(2),$(call $(1),$(a)))

Now you can map a function that normally takes only one argument, such as origin, to multiple values in one step:

o = $(call map,origin,o map MAKE)

and end up with o containing something like `file file default'.

A final caution: be careful when adding whitespace to the arguments to call. As with other functions, any whitespace contained in the second and subsequent arguments is kept; this can cause strange effects. It's generally safest to remove all extraneous whitespace when providing parameters to call.

標籤

網誌存檔