NuttX的Module探究 1

最近被問到Linux的驅動如何寫,想起以前在樹莓派上安裝無線網卡驅動編譯了很久最後加載Module。NuttX也是支持Module加載的。這樣我就可以不用燒錄固件使它打開某個串口或者SPI啥的。

首先,example裏有模塊的例子。menuconfig中開啓:

> RTOS Features > [Y] Enable loadable OS modules
> File Systems > [Y] ROMFS file system
> Binary Loader > [Y]   Enable the ELF Binary Format
> Application Configuration > Examples > [Y] Module Example
> Application Configuration > Examples > [Y]   Built-in File System

編譯運行,發現報錯

chardev.c:40:26: fatal error: nuttx/config.h: No such file or directory

順便,報錯之後再用單線程編譯,這樣好找錯誤源頭。

make[5]: Entering directory ‘/home/godenfreemans/NuttX/apps/examples/module/drivers/chardev’
CC: chardev.c
chardev.c:40:26: fatal error: nuttx/config.h: No such file or directory
#include <nuttx/config.h>
^
compilation terminated.

這個文件就是Module例子中的。明顯是找不到配置文件。說明它的makefile裏沒有包含配置文件,設置-D後編譯依舊出錯。詢問了Nutt後,得到解決方法:
apps/examples/module/drivers/chardev下創建文件Make.defs 寫入內容:

# ELF kernael module definitions

CMODULEFLAGS = $(CFLAGS) -mlong-calls # --target1-abs

LDMODULEFLAGS = -r -e module_initialize
ifeq ($(WINTOOL),y)
   LDMODULEFLAGS += -T "${shell cygpath -w 
$(TOPDIR)/libs/libc/modlib/gnu-elf.ld}"
else
   LDMODULEFLAGS += -T $(TOPDIR)/libs/libc/modlib/gnu-elf.ld
endif

在Make file開頭添加

include Make.defs

再編譯就通過了。
再次運行,出錯。

ERROR: insmod(/mnt/romfs/chardev, chardev) failed: 22

追溯一下,

apps\examples\module\module_main.c:295

  handle = insmod(BINDIR "/chardev", "chardev");

是在調用這個函數的時候出現了問題,再往裏發現了一個類似調試輸出的東西

berr("ERROR: Failed to initialize to load module: %d\n", ret);

查找定義,發現是這麼個東西:

#ifdef CONFIG_DEBUG_BINFMT_ERROR
#  define berr         _err
#else
#  define berr        (void)
#endif

看起來需要我定義CONFIG_DEBUG_BINFMT_ERROR了。
menuconfig中查找一下,按照順序開啓

> Build Setup > Debug Options > [Y] Enable Debug Features
> Build Setup > Debug Options > [Y]   Enable Error Output
> Build Setup > Debug Options > [Y]     Enable Warnings Output
> Build Setup > Debug Options > [Y]      Enable Informational Debug Output
> Build Setup > Debug Options > [Y]   Binary Loader Debug Features
> Build Setup > Debug Options > [Y]     Binary Loader Error Output
> Build Setup > Debug Options > [Y]     Binary Loader Warnings Output

再次編譯運行。依然是錯誤,不過這回顯示了最初生成錯誤的地方。對代碼分析半天無果。

感覺代碼有問題,git checkout .後,居然正常了。。。

nsh>module
main: Registering romdisk at /dev/ram0
main: Mounting ROMFS filesystem at target=/mnt/romfs with source=/dev/ram0
insmod: Loading file: /mnt/romfs/chardev
modlib_initialize: filename: /mnt/romfs/chardev loadinfo: 200040ec
modlib_read: Read 52 bytes from offset 0
mod_dumploadinfo: LOAD_INFO:
mod_dumploadinfo:   textalloc:    00000000
mod_dumploadinfo:   datastart:    00000000
mod_dumploadinfo:   textsize:     0
mod_dumploadinfo:   datasize:     0
mod_dumploadinfo:   filelen:      2204
mod_dumploadinfo:   filfd:        3
mod_dumploadinfo:   symtabidx:    0
mod_dumploadinfo:   strtabidx:    0
mod_dumploadinfo: ELF Header:
mod_dumploadinfo:   e_ident:      7f 45 4c 46
mod_dumploadinfo:   e_type:       0001
mod_dumploadinfo:   e_machine:    0028
mod_dumploadinfo:   e_version:    00000001
mod_dumploadinfo:   e_entry:      000000a9
mod_dumploadinfo:   e_phoff:      0
mod_dumploadinfo:   e_shoff:      1724
mod_dumploadinfo:   e_flags:      05000000
mod_dumploadinfo:   e_ehsize:     52
mod_dumploadinfo:   e_phentsize:  0
mod_dumploadinfo:   e_phnum:      0
mod_dumploadinfo:   e_shentsize:  40
mod_dumploadinfo:   e_shnum:      12
mod_dumploadinfo:   e_shstrndx:   9
modlib_load: loadinfo: 200040ec
modlib_read: Read 480 bytes from offset 1724
modlib_loadfile: Loaded sections:
modlib_read: Read 236 bytes from offset 52
modlib_loadfile: 1. 00000000->20004570
modlib_read: Read 244 bytes from offset 288
modlib_loadfile: 3. 000000ec->2000465c
modlib_read: Read 0 bytes from offset 532
modlib_loadfile: 5. 000001e0->20004750
modlib_loadfile: 6. 000001e0->20004750
mod_dumploadinfo: LOAD_INFO:
mod_dumploadinfo:   textalloc:    20004570
mod_dumploadinfo:   datastart:    20004750
mod_dumploadinfo:   textsize:     480
mod_dumploadinfo:   datasize:     0
mod_dumploadinfo:   filelen:      2204
mod_dumploadinfo:   filfd:        3
mod_dumploadinfo:   symtabidx:    0
mod_dumploadinfo:   strtabidx:    0
mod_dumploadinfo: ELF Header:
mod_dumploadinfo:   e_ident:      7f 45 4c 46
mod_dumploadinfo:   e_type:       0001
mod_dumploadinfo:   e_machine:    0028
mod_dumploadinfo:   e_version:    00000001
mod_dumploadinfo:   e_entry:      000000a9
mod_dumploadinfo:   e_phoff:      0
mod_dumploadinfo:   e_shoff:      1724
mod_dumploadinfo:   e_flags:      05000000
mod_dumploadinfo:   e_ehsize:     52
mod_dumploadinfo:   e_phentsize:  0
mod_dumploadinfo:   e_phnum:      0
mod_dumploadinfo:   e_shentsize:  40
mod_dumploadinfo:   e_shnum:      12
mod_dumploadinfo:   e_shstrndx:   9
mod_dumploadinfo: Sections 0:
mod_dumploadinfo:   sh_name:      00000000
mod_dumploadinfo:   sh_type:      00000000
mod_dumploadinfo:   sh_flags:     00000000
mod_dumploadinfo:   sh_addr:      00000000
mod_dumploadinfo:   sh_offset:    0
mod_dumploadinfo:   sh_size:      0
mod_dumploadinfo:   sh_link:      0
mod_dumploadinfo:   sh_info:      0
mod_dumploadinfo:   sh_addralign: 0
mod_dumploadinfo:   sh_entsize:   0
mod_dumploadinfo: Sections 1:
mod_dumploadinfo:   sh_name:      0000001f
mod_dumploadinfo:   sh_type:      00000001
mod_dumploadinfo:   sh_flags:     00000006
mod_dumploadinfo:   sh_addr:      20004570
mod_dumploadinfo:   sh_offset:    52
mod_dumploadinfo:   sh_size:      236
mod_dumploadinfo:   sh_link:      0
mod_dumploadinfo:   sh_info:      0
mod_dumploadinfo:   sh_addralign: 4
mod_dumploadinfo:   sh_entsize:   0
mod_dumploadinfo: Sections 2:
mod_dumploadinfo:   sh_name:      0000001b
mod_dumploadinfo:   sh_type:      00000009
mod_dumploadinfo:   sh_flags:     00000040
mod_dumploadinfo:   sh_addr:      00000000
mod_dumploadinfo:   sh_offset:    1452
mod_dumploadinfo:   sh_size:      168
mod_dumploadinfo:   sh_link:      10
mod_dumploadinfo:   sh_info:      1
mod_dumploadinfo:   sh_addralign: 4
mod_dumploadinfo:   sh_entsize:   8
mod_dumploadinfo: Sections 3:
mod_dumploadinfo:   sh_name:      00000029
mod_dumploadinfo:   sh_type:      00000001
mod_dumploadinfo:   sh_flags:     00000002
mod_dumploadinfo:   sh_addr:      2000465c
mod_dumploadinfo:   sh_offset:    288
mod_dumploadinfo:   sh_size:      244
mod_dumploadinfo:   sh_link:      0
mod_dumploadinfo:   sh_info:      0
mod_dumploadinfo:   sh_addralign: 4
mod_dumploadinfo:   sh_entsize:   0
mod_dumploadinfo: Sections 4:
mod_dumploadinfo:   sh_name:      00000025
mod_dumploadinfo:   sh_type:      00000009
mod_dumploadinfo:   sh_flags:     00000040
mod_dumploadinfo:   sh_addr:      00000000
mod_dumploadinfo:   sh_offset:    1620
mod_dumploadinfo:   sh_size:      16
mod_dumploadinfo:   sh_link:      10
mod_dumploadinfo:   sh_info:      3
mod_dumploadinfo:   sh_addralign: 4
mod_dumploadinfo:   sh_entsize:   8
mod_dumploadinfo: Sections 5:
mod_dumploadinfo:   sh_name:      00000031
mod_dumploadinfo:   sh_type:      00000001
mod_dumploadinfo:   sh_flags:     00000003
mod_dumploadinfo:   sh_addr:      20004750
mod_dumploadinfo:   sh_offset:    532
mod_dumploadinfo:   sh_size:      0
mod_dumploadinfo:   sh_link:      0
mod_dumploadinfo:   sh_info:      0
mod_dumploadinfo:   sh_addralign: 1
mod_dumploadinfo:   sh_entsize:   0
mod_dumploadinfo: Sections 6:
mod_dumploadinfo:   sh_name:      00000037
mod_dumploadinfo:   sh_type:      00000008
mod_dumploadinfo:   sh_flags:     00000003
mod_dumploadinfo:   sh_addr:      20004750
mod_dumploadinfo:   sh_offset:    532
mod_dumploadinfo:   sh_size:      0
mod_dumploadinfo:   sh_link:      0
mod_dumploadinfo:   sh_info:      0
mod_dumploadinfo:   sh_addralign: 1
mod_dumploadinfo:   sh_entsize:   0
mod_dumploadinfo: Sections 7:
mod_dumploadinfo:   sh_name:      0000003c
mod_dumploadinfo:   sh_type:      00000001
mod_dumploadinfo:   sh_flags:     00000030
mod_dumploadinfo:   sh_addr:      00000000
mod_dumploadinfo:   sh_offset:    532
mod_dumploadinfo:   sh_size:      50
mod_dumploadinfo:   sh_link:      0
mod_dumploadinfo:   sh_info:      0
mod_dumploadinfo:   sh_addralign: 1
mod_dumploadinfo:   sh_entsize:   1
mod_dumploadinfo: Sections 8:
mod_dumploadinfo:   sh_name:      00000045
mod_dumploadinfo:   sh_type:      70000003
mod_dumploadinfo:   sh_flags:     00000000
mod_dumploadinfo:   sh_addr:      00000000
mod_dumploadinfo:   sh_offset:    582
mod_dumploadinfo:   sh_size:      57
mod_dumploadinfo:   sh_link:      0
mod_dumploadinfo:   sh_info:      0
mod_dumploadinfo:   sh_addralign: 1
mod_dumploadinfo:   sh_entsize:   0
mod_dumploadinfo: Sections 9:
mod_dumploadinfo:   sh_name:      00000011
mod_dumploadinfo:   sh_type:      00000003
mod_dumploadinfo:   sh_flags:     00000000
mod_dumploadinfo:   sh_addr:      00000000
mod_dumploadinfo:   sh_offset:    1636
mod_dumploadinfo:   sh_size:      85
mod_dumploadinfo:   sh_link:      0
mod_dumploadinfo:   sh_info:      0
mod_dumploadinfo:   sh_addralign: 1
mod_dumploadinfo:   sh_entsize:   0
mod_dumploadinfo: Sections 10:
mod_dumploadinfo:   sh_name:      00000001
mod_dumploadinfo:   sh_type:      00000002
mod_dumploadinfo:   sh_flags:     00000000
mod_dumploadinfo:   sh_addr:      00000000
mod_dumploadinfo:   sh_offset:    640
mod_dumploadinfo:   sh_size:      592
mod_dumploadinfo:   sh_link:      11
mod_dumploadinfo:   sh_info:      20
mod_dumploadinfo:   sh_addralign: 4
mod_dumploadinfo:   sh_entsize:   16
mod_dumploadinfo: Sections 11:
mod_dumploadinfo:   sh_name:      00000009
mod_dumploadinfo:   sh_type:      00000003
mod_dumploadinfo:   sh_flags:     00000000
mod_dumploadinfo:   sh_addr:      00000000
mod_dumploadinfo:   sh_offset:    1232
mod_dumploadinfo:   sh_size:      218
mod_dumploadinfo:   sh_link:      0
mod_dumploadinfo:   sh_info:      0
mod_dumploadinfo:   sh_addralign: 1
mod_dumploadinfo:   sh_entsize:   0
modlib_bind: INFO: modlib_relocate(modp, loadinfo, 2)
modlib_read: Read 8 bytes from offset 1452
modlib_read: Read 16 bytes from offset 1136
modlib_read: Read 128 bytes from offset 1395
modlib_symvalue: SHN_ABS: name=syslog 00000000+08003219=08003219
up_relocate: Performing ABS32 link at addr=2000458c [00000000] to sym=200040b0 st_value=08003219
modlib_read: Read 8 bytes from offset 1460
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=20004590 [00000044] to sym=200040b0 st_value=2000465c
modlib_read: Read 8 bytes from offset 1468
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=20004594 [00000065] to sym=200040b0 st_value=2000465c
modlib_read: Read 8 bytes from offset 1476
modlib_read: Read 16 bytes from offset 976
modlib_read: Read 128 bytes from offset 1286
modlib_symvalue: SHN_ABS: name=lib_dumpbuffer 00000000+0800f2b1=0800f2b1
up_relocate: Performing ABS32 link at addr=20004598 [00000000] to sym=200040b0 st_value=0800f2b1
modlib_read: Read 8 bytes from offset 1484
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=200045d4 [00000000] to sym=200040b0 st_value=2000465c
modlib_read: Read 8 bytes from offset 1492
modlib_read: Read 16 bytes from offset 1200
modlib_read: Read 128 bytes from offset 1434
modlib_symvalue: SHN_ABS: name=strlen 00000000+080031cd=080031cd
up_relocate: Performing ABS32 link at addr=200045d8 [00000000] to sym=200040b0 st_value=080031cd
modlib_read: Read 8 bytes from offset 1500
modlib_read: Read 16 bytes from offset 1040
modlib_read: Read 128 bytes from offset 1330
modlib_symvalue: SHN_ABS: name=memcpy 00000000+080031dd=080031dd
up_relocate: Performing ABS32 link at addr=200045dc [00000000] to sym=200040b0 st_value=080031dd
modlib_read: Read 8 bytes from offset 1508
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=200045e0 [0000007c] to sym=200040b0 st_value=2000465c
modlib_read: Read 8 bytes from offset 1516
modlib_read: Read 16 bytes from offset 1136
modlib_read: Read 128 bytes from offset 1395
modlib_symvalue: SHN_ABS: name=syslog 00000000+08003219=08003219
up_relocate: Performing ABS32 link at addr=200045e4 [00000000] to sym=200040b0 st_value=08003219
modlib_read: Read 8 bytes from offset 1524
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=200045e8 [0000009e] to sym=200040b0 st_value=2000465c
modlib_read: Read 8 bytes from offset 1532
modlib_read: Read 16 bytes from offset 976
modlib_read: Read 128 bytes from offset 1286
modlib_symvalue: SHN_ABS: name=lib_dumpbuffer 00000000+0800f2b1=0800f2b1
up_relocate: Performing ABS32 link at addr=200045ec [00000000] to sym=200040b0 st_value=0800f2b1
modlib_read: Read 8 bytes from offset 1540
modlib_read: Read 16 bytes from offset 1136
modlib_read: Read 128 bytes from offset 1395
modlib_symvalue: SHN_ABS: name=syslog 00000000+08003219=08003219
up_relocate: Performing ABS32 link at addr=20004608 [00000000] to sym=200040b0 st_value=08003219
modlib_read: Read 8 bytes from offset 1548
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=2000460c [000000b6] to sym=200040b0 st_value=2000465c
modlib_read: Read 8 bytes from offset 1556
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=20004610 [000000d3] to sym=200040b0 st_value=2000465c
modlib_read: Read 8 bytes from offset 1564
modlib_read: Read 16 bytes from offset 1088
modlib_read: Read 128 bytes from offset 1353
modlib_symvalue: SHN_ABS: name=unregister_driver 00000000+08009363=08009363
up_relocate: Performing ABS32 link at addr=20004614 [00000000] to sym=200040b0 st_value=08009363
modlib_read: Read 8 bytes from offset 1572
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=20004644 [000000e0] to sym=200040b0 st_value=2000465c
modlib_read: Read 8 bytes from offset 1580
modlib_read: Read 16 bytes from offset 1136
modlib_read: Read 128 bytes from offset 1395
modlib_symvalue: SHN_ABS: name=syslog 00000000+08003219=08003219
up_relocate: Performing ABS32 link at addr=20004648 [00000000] to sym=200040b0 st_value=08003219
modlib_read: Read 8 bytes from offset 1588
modlib_read: Read 16 bytes from offset 784
modlib_symvalue: Other: 00000081+20004570=200045f1
up_relocate: Performing ABS32 link at addr=2000464c [00000000] to sym=200040b0 st_value=200045f1
modlib_read: Read 8 bytes from offset 1596
modlib_read: Read 16 bytes from offset 960
modlib_read: Read 128 bytes from offset 1355
modlib_symvalue: SHN_ABS: name=register_driver 00000000+08009331=08009331
up_relocate: Performing ABS32 link at addr=20004650 [00000000] to sym=200040b0 st_value=08009331
modlib_read: Read 8 bytes from offset 1604
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=20004654 [00000028] to sym=200040b0 st_value=2000465c
modlib_read: Read 8 bytes from offset 1612
modlib_read: Read 16 bytes from offset 656
modlib_symvalue: Other: 00000000+2000465c=2000465c
up_relocate: Performing ABS32 link at addr=20004658 [000000d3] to sym=200040b0 st_value=2000465c
modlib_bind: INFO: modlib_relocate(modp, loadinfo, 4)
modlib_read: Read 8 bytes from offset 1620
modlib_read: Read 16 bytes from offset 736
modlib_symvalue: Other: 0000002d+20004570=2000459d
up_relocate: Performing ABS32 link at addr=2000468c [00000000] to sym=200040b0 st_value=2000459d
modlib_read: Read 8 bytes from offset 1628
modlib_read: Read 16 bytes from offset 688
modlib_symvalue: Other: 00000001+20004570=20004571
up_relocate: Performing ABS32 link at addr=20004690 [00000000] to sym=200040b0 st_value=20004571
module_initialize:
chardev_read: Returning 36 bytes
chardev_read: Returning (20004168):
0000: 48692074686572652c20617070732f65 78616d706c65732f6d6f64756c652074 Hi there, apps/e xamples/module t
0020: 6573740a                                                          est.
main: Read 36 bytes: 196
main: Bytes read (20004168):
0000: 48692074686572652c20617070732f65 78616d706c65732f6d6f64756c652074 Hi there, apps/e xamples/module t
0020: 6573740a                                                          est.
chardev_write: Writing 27 bytes
chardev_write: Writing (801400f):
0000: 48692074686572652c20696e7374616c 6c6564206472697665720a           Hi there, instal led driver.
main: Wrote 27 bytes: 102
main: Bytes written (801400f):
0000: 48692074686572652c20696e7374616c 6c6564206472697665720a           Hi there, instal led driver.
module_uninitialize: arg=0

可以看到,這個例子先掛載了一個ramdisk,這個ramdisk裏的內容就是chardev的模塊文件,接下來掛載了名爲chardev的設備。但是在測試完成後居然卸載了模塊!這怎麼能行,我要用lsmod查看模塊啊。下面手動掛載模塊。

insmod /mnt/romfs/chardev chardev

注意。這裏使用的是絕對路徑,如果使用相對路徑的話會出錯。或許是有什麼參數沒有開啓吧。
經過一長串的調試信息後,沒有報錯。應該是成功了。

nsh>ls /dev
/dev:
 chardev
 console
 null
 ram0
 timer1
 timer2
 timer3
 timer4
 timer5
 ttyS0
 zero
nsh>lsmod
NAME                 INIT   UNINIT      ARG NEXPORTS     TEXT     SIZE     DATA     SIZE
chardev          200038c9 200038a1        0        0 20003820      480 20003a00        0
nsh>rmmod chardev
module_uninitialize: arg=0
nsh>ls /dev
/dev:
 console
 null
 ram0
 timer1
 timer2
 timer3
 timer4
 timer5
 ttyS0
 zero
nsh>lsmod
NAME                 INIT   UNINIT      ARG NEXPORTS     TEXT     SIZE     DATA     SIZE
nsh>

完全可以。沒有問題。
下來分析這個模塊的寫法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章