- 論壇徽章:
- 0
|
由于產品設計的需要,我要在Davinci6446平臺移植thttpd-2.25b,在此過程中也出現(xiàn)一些問題,則在此記錄之。
我們知道,當 rootfs缺少必要的library時,會導致應用程序無法正確運行,嚴重的話可能導致系統(tǒng)無法正常啟動,解決庫依賴(library dependency)問題可參考如下三個要點:
1、先使用交叉編譯器的objdump觀察目標項目,加入library。
2、檢查這些library是不是依賴其他的library。
3、最后檢查應用程序是否用到特定的library的service。
thttpd 使用到 NSS (Name Service Switch),因此若沒有將 libnss_SERVICE.so 加到 root filesystem,thttpd 在執(zhí)行時可能會遇到一些奇怪的問題。例如,當 thttpd 依據(jù) /etc/passwd 去尋找 linux user 時,會用到 libnss_files.so (不讀 /etc/shadow),因此會看到以下錯誤信息:
unknown user - root
出現(xiàn)這個錯誤的原因是 thttpd 讀不到 'root' 使用者,要深入探討這個問題的原理,必須從以下的程序源代碼中了解:
403 /* If we're root and we're going to become another user, get the uid /gid
404 ** now.
405 */
406 if ( getuid() == 0 )
407 {
408 pwd = getpwnam( user );
409 if ( pwd == (struct passwd*) 0 )
410 {
411 syslog( LOG_CRIT, "unknown user - '%.80s'", user );
412 (void) fprintf( stderr, "%s: unknown user - '%s'\n", argv0, user );
413 exit( 1 );
414 }
415 uid = pwd->pw_uid;
416 gid = pwd->pw_gid;
417 }
以上代碼是 thttpd 2.25b 的程序源代碼,位于 thttpd.c 的 main() 函數(shù)。
由系統(tǒng)構建的角度來看這個問題。我們已經習慣用 objdump 來觀察程序library依賴,所以當 objdump 的輸出跟我們預期的不同時,還比較驚奇。例如:
root@microtiger:/home/microtiger/task/thttpd/thttpd-2.25b# arm_v5t_le-objdump -x thttpd|more
thttpd: file format elf32-littlearm
thttpd
architecture: armv5t, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00008180
Program Header:
0x70000001 off 0x00082d4c vaddr 0x0008ad4c paddr 0x0008ad4c align 2**2
filesz 0x000006e8 memsz 0x000006e8 flags r--
LOAD off 0x00000000 vaddr 0x00008000 paddr 0x00008000 align 2**15
filesz 0x000834b0 memsz 0x000834b0 flags r-x
LOAD off 0x000834b0 vaddr 0x000934b0 paddr 0x000934b0 align 2**15
filesz 0x00001ef8 memsz 0x0002a99c flags rw-
NOTE off 0x000000d4 vaddr 0x000080d4 paddr 0x000080d4 align 2**2
filesz 0x00000020 memsz 0x00000020 flags r--
NOTE off 0x000000f4 vaddr 0x000080f4 paddr 0x000080f4 align 2**2
filesz 0x00000074 memsz 0x00000074 flags r--
private flags = 4000002: [Version4 EABI] [has entry point]
Sections:
Idx Name Size VMA LMA File off Algn
0 .note.ABI-tag 00000020 000080d4 000080d4 000000d4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_CONTENTS
1 .note.numapolicy 00000074 000080f4 000080f4 000000f4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_CONTENTS
2 .init 00000018 00008168 00008168 00000168 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
3 .text 0006a3c4 00008180 00008180 00000180 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
4 __libc_freeres_fn 000009bc 00072544 00072544 0006a544 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
5 __libc_thread_freeres_fn 00000050 00072f00 00072f00 0006af00 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
6 .fini 00000018 00072f50 00072f50 0006af50 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
7 .rodata 00017cc4 00072f68 00072f68 0006af68 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 __libc_subfreeres 00000040 0008ac2c 0008ac2c 00082c2c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 __libc_atexit 00000004 0008ac6c 0008ac6c 00082c6c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 __libc_thread_subfreeres 00000004 0008ac70 0008ac70 00082c70 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
11 .ARM.extab 000000d8 0008ac74 0008ac74 00082c74 2**2
是相當?shù)拈L,只要了這么一段。
追溯這個問題:thttpd 調用 getpwnam() 函數(shù),此函數(shù)由 libnss_compat 提供,因此解決方案是把 libnss_files.so 加到 root filesystem 里面即可。
前面提到 libnss_compat,怎么后面是把 libnss_files 加到 root filesystem?原因在于libnss_compat 用來讀 /etc/shadow,但是現(xiàn)在我們只需要由 /etc/passwd 讀 linux user,所以使用 libnss_files.so 就行了。
執(zhí)行 thttpd 的話,再加上指定 username 的參數(shù)即可:
# thttpd -p 80 -d www -u root
libnss_SERVICE.so 是包含在 glibc 里的程序庫,因此可以直接由 cross toolchain 取得,不必再另行建置。
附帶一提,如果要讀 shadow passwd 的話,是使用 libnss_compat.so。
本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u1/37080/showart_2051483.html |
|