(1) rtems6默认没有networking
(2) rtems和 bsd版本匹配问题
master - branch intended for the RTEMS master which tracks the FreeBSD master branch. This branch must be used for libbsd development. Back ports to the 6-freebsd-12 are allowed. 6-freebsd-12 - branch intended for RTEMS 6 which tracks the FreeBSD stable/12 branch. This branch is maintained and regular updates from FreeBSD are planned. It is recommended for production systems. 5-freebsd-12 - branch belongs to the RTEMS 5 release. It is based on FreeBSD stable/12 branch. It is recommended for production systems that use RTEMS 5. 5 - branch belongs to the RTEMS 5 release. It is based on a FreeBSD development version. freebsd-9.3 - branch for some RTEMS version with a FreeBSD 9.3 baseline. This branch is unmaintained. It is recommended to update to RTEMS 5 or 6. 4.11 - branch for the RTEMS 4.11 release series. This branch is unmaintained. It is recommended to update to RTEMS 5 or 6.
[root@centos7 rtems]# ls aclocal.m4 config.ini Doxyfile LICENSE.BSD-2-Clause LICENSE.NET Makefile.in spec autom4te.cache config.ini.bak gccdeps.py LICENSE.BSD-3-Clause LICENSE.RPCXDR Makefile.maint testsuites bsps config.log gccdeps.pyc LICENSE.CC-BY-SA-4.0 long_gcc.py README waf build configure INSTALL LICENSE.GPL-2.0 MAINTAINERS rtems-bsps wscript c cpukit LICENSE LICENSE.JFFS2 make rtemslogo.png yaml [root@centos7 rtems]# git branch 5 master * remotes/origin/5
[root@centos7 rtems-libbsd]# git branch --all master * remotes/origin/5 remotes/origin/6-freebsd-12 remotes/origin/4.11 remotes/origin/5 remotes/origin/5-freebsd-12 remotes/origin/6-freebsd-12 remotes/origin/HEAD -> origin/master remotes/origin/freebsd-9.3 remotes/origin/master
[root@centos7 rtems-libbsd]# qemu-system-riscv64 -M virt -kernel build/riscv-rtems6-rv64imafdc_medany-default/selectpollkqueue01.exe -bios none -serial stdio -display none *** BEGIN OF TEST LIBBSD SELECT AND POLL AND KQUEUE AND PIPE 1 *** *** TEST VERSION: 6.0.0.822ebb4cae2bb8bc9fe55915bd4acc4942fcd8ce *** TEST STATE: EXPECTED_PASS *** TEST BUILD: RTEMS_POSIX_API *** TEST TOOLS: 10.3.1 20210409 (RTEMS 6, RSB 889cf95db0122bd1a6b21598569620c40ff2069d, Newlib eb03ac1) nexus0: <RTEMS Nexus device> [zone: unpcb] kern.ipc.maxsockets limit reached info: lo0: link state changed to UP test select timeout test select connect worker: create new connect socket worker: connect test select read worker: write test select write worker: read test select close worker: close test pselect sigmask test pselect timeout test poll timeout test poll connect worker: create new connect socket worker: connect test poll read worker: write test poll write worker: read test poll close worker: close test kqueue timer test kqueue timer test kqueue connect worker: create new connect socket worker: connect test kqueue read worker: write test kqueue write worker: read test kqueue close worker: shutdown test kqueue user STACK USAGE BY THREAD ID NAME LOW HIGH CURRENT AVAIL USED 0x09010001 IDLE 0x80196480 0x8019847f 0x801982c0 8176 488 0x0a010001 UI1 0x8019a900 0x801a28ff 0x801a22f0 32752 4976 0x0a010002 TIME 0x801a2ea0 0x801aae9f 0x801aad90 32752 480 0x0a010003 IRQS 0x801aaeb0 0x801b2eaf 0x801b2d90 32752 336 0x0a010004 config_0 0x801d91f0 0x801e11ef 0x801e10c0 32752 352 0x0a010005 swi5: fast task 0x801e1520 0x801e951f 0x801e93d0 32752 384 0x0a010006 thread taskq 0x801e96f0 0x801f16ef 0x801f15c0 32752 352 0x0a010007 swi6: Giant tas 0x801f1a20 0x801f9a1f 0x801f98d0 32752 384 0x0a010008 swi6: task queu 0x801f9d50 0x80201d4f 0x80201c00 32752 1872 0x0a010009 kqueue_ctx task 0x80201f20 0x80209f1f 0x80209df0 32752 352 0x0a01000a swi1: netisr 0 0x8020a170 0x8021216f 0x80211d20 32752 1800 0x0a01000b bufdaemon 0x8023c3f0 0x802443ef 0x80244260 32752 880 0x0a01000c vnlru 0x802444c0 0x8024c4bf 0x8024c2f0 32752 512 0x0a01000d syncer 0x8024c590 0x8025458f 0x802543c0 32752 512 0x0a01000e softirq_0 0x80254760 0x8025c75f 0x8025c630 32752 352 0x0a01000f bufspacedaemon- 0x8025c830 0x8026482f 0x802646d0 32752 400 0x0a010010 WORK 0x80264900 0x802668ff 0x802663b0 8176 1576 0x00000000 Interrupt Stack 0x80198480 0x8019a47f 0x00000000 8176 432 *** END OF TEST LIBBSD SELECT AND POLL AND KQUEUE AND PIPE 1 *** [ RTEMS shutdown ] RTEMS version: 6.0.0.822ebb4cae2bb8bc9fe55915bd4acc4942fcd8ce RTEMS tools: 10.3.1 20210409 (RTEMS 6, RSB 889cf95db0122bd1a6b21598569620c40ff2069d, Newlib eb03ac1) executing thread ID: 0x08a010001 executing thread name: UI1
[root@centos7 development]# rpm -ivh tunctl-1.5-lp150.1.2.aarch64.rpm warning: tunctl-1.5-lp150.1.2.aarch64.rpm: Header V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY Preparing... ################################# [100%] Updating / installing... 1:tunctl-1.5-lp150.1.2 ################################# [100%]
[root@centos7 development]# tunctl -p -t qtap -u $(whoami) Set 'qtap' persistent and owned by uid 0 [root@centos7 development]# ip link set dev qtap up [root@centos7 development]# ip addr add 169.254.1.1/16 dev qtap [root@centos7 development]# ip addr show qtap 11: qtap: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 link/ether 3e:01:b5:63:ad:69 brd ff:ff:ff:ff:ff:ff inet 169.254.1.1/16 scope global qtap valid_lft forever preferred_lft forever [root@centos7 development]#
[root@centos7 rtems-libbsd]# qemu-system-riscv64 -M virt -kernel build/riscv-rtems6-rv64imafdc_medany-default/media01.exe -bios none -serial stdio -display none *** BEGIN OF TEST LIBBSD MEDIA 1 *** *** TEST VERSION: 6.0.0.822ebb4cae2bb8bc9fe55915bd4acc4942fcd8ce *** TEST STATE: USER_INPUT *** TEST BUILD: RTEMS_POSIX_API *** TEST TOOLS: 10.3.1 20210409 (RTEMS 6, RSB 889cf95db0122bd1a6b21598569620c40ff2069d, Newlib eb03ac1) nexus0: <RTEMS Nexus device> info: lo0: link state changed to UP info: ftpd: FTP daemon started (4 sessions max) info: telnetd: started successfully on port 23 RTEMS Shell on /dev/console. Use 'help' to list commands. SHLL [/] # info: version 6.2.1 starting err: no valid interfaces found warning: no interfaces have a carrier SHLL [/] # telnet 169.254.159.156 telnet: command not found SHLL [/] # ip a ip: command not found SHLL [/] #
[root@centos7 rtems-libbsd]# qemu-system-riscv64 -M virt -kernel build/riscv-rtems6-rv64imafdc_medany-default/media01.exe -bios none -serial stdio -display none -net tap,ifname=qtap,script=no,downscript=no -net nic,model=cadence_gem,macaddr=0e:b0:ba:5e:ba:12 qemu-system-riscv64: warning: hub port hub0port1 has no peer qemu-system-riscv64: warning: hub 0 with no nics qemu-system-riscv64: warning: netdev hub0port1 has no peer qemu-system-riscv64: warning: requested NIC (anonymous, model cadence_gem) was not created (not supported by this machine?) *** BEGIN OF TEST LIBBSD MEDIA 1 *** *** TEST VERSION: 6.0.0.822ebb4cae2bb8bc9fe55915bd4acc4942fcd8ce *** TEST STATE: USER_INPUT *** TEST BUILD: RTEMS_POSIX_API *** TEST TOOLS: 10.3.1 20210409 (RTEMS 6, RSB 889cf95db0122bd1a6b21598569620c40ff2069d, Newlib eb03ac1) nexus0: <RTEMS Nexus device> info: lo0: link state changed to UP info: ftpd: FTP daemon started (4 sessions max) info: telnetd: started successfully on port 23 RTEMS Shell on /dev/console. Use 'help' to list commands. SHLL [/] # info: version 6.2.1 starting err: no valid interfaces found warning: no interfaces have a carrier
[root@centos7 rtems-libbsd]# bash start.sh qemu-system-riscv64: could not configure /dev/net/tun (qtap): Device or resource busy [root@centos7 rtems-libbsd]# ps -elf | grep qemu-system-riscv64 2 T root 35458 114368 1 80 0 - 6854 do_sig 06:07 pts/1 00:00:02 qemu-system-riscv64 -M virt -kernel build/riscv-rtems6-rv64imafdc_medany-default/media01.exe -bios none -serial stdio -display none 2 T root 35480 114368 0 80 0 - 6856 do_sig 06:08 pts/1 00:00:01 qemu-system-riscv64 -M virt -kernel build/riscv-rtems6-rv64imafdc_medany-default/media01.exe -bios none -serial stdio -display none -net tap,ifname=qtap,script=no,downscript=no -net nic,model=cadence_gem,macaddr=0e:b0:ba:5e:ba:12 0 S root 35543 114368 0 80 0 - 1729 pipe_w 06:11 pts/1 00:00:00 grep --color=auto qemu-system-riscv64 [root@centos7 rtems-libbsd]# kill -9 35458 [root@centos7 rtems-libbsd]# kill -9 35480 [1]- Killed qemu-system-riscv64 -M virt -kernel build/riscv-rtems6-rv64imafdc_medany-default/media01.exe -bios none -serial stdio -display none [root@centos7 rtems-libbsd]#
emu-system-riscv64 \ > --machine virt \ > --nographic \ > --bios default OpenSBI v0.5 (Oct 9 2019 12:03:04) ____ _____ ____ _____ / __ \ / ____| _ \_ _| | | | |_ __ ___ _ __ | (___ | |_) || | | | | | '_ \ / _ \ '_ \ \___ \| _ < | | | |__| | |_) | __/ | | |____) | |_) || |_ \____/| .__/ \___|_| |_|_____/|____/_____| | | |_| Platform Name : QEMU Virt Machine Platform HART Features : RV64ACDFIMSU Platform Max HARTs : 8 Current Hart : 0 Firmware Base : 0x80000000 Firmware Size : 116 KB Runtime SBI Version : 0.2 PMP0: 0x0000000080000000-0x000000008001ffff (A) PMP1: 0x0000000000000000-0xffffffffffffffff (A,R,W,X) QEMU: Terminated
qemu-system-riscv64 -cpu help any rv64 rv64gcsu-v1.10.0 rv64gcsu-v1.9.1 rv64imacu-nommu sifive-e51 sifive-u54
qemu-system-riscv64 -nic \? Available netdev backend types: socket hubport tap user l2tpv3 bridge vhost-user
(gdb) b bsp_interrupt_vector_enable Breakpoint 1 at 0x800e5780: file ../../../bsps/riscv/riscv/irq/irq.c, line 284. (gdb) c The program is not being run. (gdb) target rmote:1234 Undefined target command: "rmote:1234". Try "help target". (gdb) target remote:1234 Remote debugging using :1234 0x0000000000001000 in ?? () (gdb) c Continuing. Breakpoint 1, bsp_interrupt_vector_enable (vector=vector@entry=1) at ../../../bsps/riscv/riscv/irq/irq.c:284 284 if (RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) { (gdb) bt #0 bsp_interrupt_vector_enable (vector=vector@entry=1) at ../../../bsps/riscv/riscv/irq/irq.c:284 #1 0x00000000800e6560 in bsp_interrupt_entry_install_first (entry=0x80386c40, options=1, vector=1) at ../../../bsps/shared/irq/irq-generic.c:201 #2 bsp_interrupt_entry_install (entry=0x80386c40, options=1, vector=1) at ../../../bsps/shared/irq/irq-generic.c:226 #3 rtems_interrupt_entry_install (vector=vector@entry=1, options=options@entry=1, entry=entry@entry=0x80386c40) at ../../../bsps/shared/irq/irq-generic.c:280 #4 0x00000000800e65b0 in rtems_interrupt_handler_install (vector=vector@entry=1, info=info@entry=0x8015e600 "Clock", options=options@entry=1, routine=routine@entry=0x800e4f54 <Clock_isr>, arg=arg@entry=0x0) at ../../../bsps/shared/irq/irq-handler-install.c:107 #5 0x00000000800e4fc2 in riscv_clock_handler_install () at ../../../bsps/riscv/riscv/clock/clockdrv.c:109 #6 _Clock_Initialize () at ../../../bsps/riscv/riscv/clock/../../../shared/dev/clock/clockimpl.h:216 #7 0x00000000800f3c90 in rtems_initialize_executive () at ../../../cpukit/sapi/src/exinit.c:116 #8 0x00000000800e49cc in boot_card (cmdline=<optimized out>) at ../../../bsps/shared/start/bootcard.c:55 #9 0x0000000080000042 in bsp_section_start_begin () at ../../../bsps/riscv/shared/start/start.S:86 Backtrace stopped: frame did not save the PC (gdb) c Continuing. Breakpoint 1, bsp_interrupt_vector_enable (vector=vector@entry=12) at ../../../bsps/riscv/riscv/irq/irq.c:284 284 if (RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) { (gdb) bt #0 bsp_interrupt_vector_enable (vector=vector@entry=12) at ../../../bsps/riscv/riscv/irq/irq.c:284 #1 0x00000000800e6560 in bsp_interrupt_entry_install_first (entry=0x8038fbc0, options=0, vector=12) at ../../../bsps/shared/irq/irq-generic.c:201 #2 bsp_interrupt_entry_install (entry=0x8038fbc0, options=0, vector=12) at ../../../bsps/shared/irq/irq-generic.c:226 #3 rtems_interrupt_entry_install (vector=vector@entry=12, options=options@entry=0, entry=entry@entry=0x8038fbc0) at ../../../bsps/shared/irq/irq-generic.c:280 #4 0x00000000800e65b0 in rtems_interrupt_handler_install (vector=<optimized out>, info=info@entry=0x8019e8c0 "NS16550", options=options@entry=0, routine=0x800e6104 <ns16550_isr>, arg=0x8038f6f0) at ../../../bsps/shared/irq/irq-handler-install.c:107 #5 0x00000000800e60d8 in ns16550_initialize_interrupts (ctx=<optimized out>, ctx=<optimized out>, isr=<optimized out>, tty=<optimized out>) at ../../../bsps/shared/dev/serial/ns16550-context.c:366 #6 ns16550_open (tty=0x8038f6f0, base=0x8037e540 <ns16550_instances>, term=<optimized out>, args=<optimized out>) at ../../../bsps/shared/dev/serial/ns16550-context.c:432 #7 0x00000000800ec926 in rtems_termios_open_tty (major=<optimized out>, minor=<optimized out>, args=args@entry=0x803868f0 <_ISR_Stack_area_begin+7728>, tty=0x8038f6f0, device_node=device_node@entry=0x80386c70, callbacks=callbacks@entry=0x0) at ../../../cpukit/libcsupport/src/termios.c:549 #8 0x00000000800ecd70 in rtems_termios_imfs_open (iop=<optimized out>, path=<optimized out>, oflag=<optimized out>, mode=<optimized out>) at ../../../cpukit/libcsupport/src/termios.c:2093 #9 0x00000000800eb620 in do_open (mode=<optimized out>, oflag=0, path=0x8012a730 "/dev/console", iop=0x8034dd70 <rtems_libio_iops>) at ../../../cpukit/libcsupport/src/open.c:123 #10 open (path=path@entry=0x8012a730 "/dev/console", oflag=oflag@entry=0) at ../../../cpukit/libcsupport/src/open.c:165 #11 0x00000000800eb734 in rtems_libio_post_driver () at ../../../cpukit/libcsupport/src/open_dev_console.c:31 #12 0x00000000800f3c90 in rtems_initialize_executive () at ../../../cpukit/sapi/src/exinit.c:116 #13 0x00000000800e49cc in boot_card (cmdline=<optimized out>) at ../../../bsps/shared/start/bootcard.c:55 #14 0x0000000080000042 in bsp_section_start_begin () at ../../../bsps/riscv/shared/start/start.S:86 Backtrace stopped: frame did not save the PC (gdb) c Continuing.
(gdb) c Continuing. Breakpoint 1, _bsd_device_attach (dev=dev@entry=0x80542e60) at ../../freebsd/sys/kern/subr_bus.c:2993 2993 device_sysctl_init(dev); (gdb) bt #0 _bsd_device_attach (dev=dev@entry=0x80542e60) at ../../freebsd/sys/kern/subr_bus.c:2993 #1 0x000000008005abe8 in _bsd_device_probe_and_attach (dev=0x80542e60) at ../../freebsd/sys/kern/subr_bus.c:2953 #2 _bsd_bus_generic_new_pass (dev=<optimized out>) at ../../freebsd/sys/kern/subr_bus.c:4187 #3 0x00000000800599b2 in BUS_NEW_PASS (_dev=0x80541ac0) at ../../rtemsbsd/include/rtems/bsd/local/bus_if.h:1046 #4 _bsd_bus_set_pass (pass=<optimized out>) at ../../freebsd/sys/kern/subr_bus.c:994 #5 0x0000000080051e1a in _bsd_mi_startup () at ../../freebsd/sys/kern/init_main.c:331 #6 0x000000008003f332 in rtems_bsd_initialize () at ../../rtemsbsd/rtems/rtems-kernel-init.c:235 #7 0x0000000080005136 in Init (arg=<optimized out>) at ../../testsuite/include/rtems/bsd/test/default-network-init.h:239 #8 0x00000000800f6bce in _Thread_Handler () at ../../../cpukit/score/src/threadhandler.c:145 #9 0x00000000800f6b7c in _Thread_Get (id=<optimized out>, lock_context=0x802db438 <nexus_driver>) at ../../../cpukit/score/src/threadget.c:44 Backtrace stopped: frame did not save the PC (gdb) c Continuing.
_bsd_device_probe_and_attach (dev=0x80542e60) at ../../freebsd/sys/kern/subr_bus.c:2955
qemu-system-aarch64 -no-reboot -nographic -serial mon:stdio -machine virt,gic-version=3 -cpu cortex-a53 -m 4096 -kernel build/aarch64-rtems6-a53_lp64_qemu-default/media01.exe -netdev tap,id=net0,ifname=qtap,script=no,downscript=no -device e1000,netdev=net0,id=net0,mac=52:54:00:c9:18:24 *** BEGIN OF TEST LIBBSD MEDIA 1 *** *** TEST VERSION: 6.0.0.671f126a3a8e6ce5da87aa75c7205fb764e95c78 *** TEST STATE: USER_INPUT *** TEST BUILD: RTEMS_POSIX_API *** TEST TOOLS: 10.3.1 20210409 (RTEMS 6, RSB 889cf95db0122bd1a6b21598569620c40ff2069d, Newlib eb03ac1) nexus0: <RTEMS Nexus device> info: lo0: link state changed to UP info: ftpd: FTP daemon started (4 sessions max) info: telnetd: started successfully on port 23 RTEMS Shell on /dev/console. Use 'help' to list commands. SHLL [/] # info: version 6.2.1 starting err: no valid interfaces found warning: no interfaces have a carrier
[root@centos7 rtems-libbsd-a64]# ls ./build/aarch64-rtems6-a53_lp64_qemu-default/testsuite/include/rtems/bsd/test/ network-config.h
typedef enum { RTEMS_BSD_RES_IRQ = 1, RTEMS_BSD_RES_MEMORY = 3 } rtems_bsd_device_resource_type; typedef struct { rtems_bsd_device_resource_type type; unsigned long start_request; unsigned long start_actual; } rtems_bsd_device_resource; typedef struct { const char *name; int unit; size_t resource_count; const rtems_bsd_device_resource *resources; const struct sysinit *driver_reference; } rtems_bsd_device; #define RTEMS_BSD_DEFINE_NEXUS_DEVICE(name, unit, resource_count, resources) \ extern struct sysinit SYSINIT_ENTRY_NAME(name##_nexusmodule); \ RTEMS_BSD_DEFINE_SET_ITEM(nexus, name##unit, rtems_bsd_device) = \ { #name, unit, (resource_count), (resources), \ &SYSINIT_ENTRY_NAME(name##_nexusmodule) }
qemu-system-aarch64 -no-reboot -nographic -serial mon:stdio -machine virt,gic-version=3 -cpu cortex-a53 -m 4096 -net none -kernel build/aarch64-rtems6-a53_lp64_qemu-default/selectpollkqueue01.exe -netdev tap,id=mynet0,ifname=qtap,script=no,downscript=no -device e1000,netdev=mynet0,mac=52:55:00:d1:55:01 *** BEGIN OF TEST LIBBSD SELECT AND POLL AND KQUEUE AND PIPE 1 *** *** TEST VERSION: 6.0.0.671f126a3a8e6ce5da87aa75c7205fb764e95c78 *** TEST STATE: EXPECTED_PASS *** TEST BUILD: RTEMS_POSIX_API *** TEST TOOLS: 10.3.1 20210409 (RTEMS 6, RSB 889cf95db0122bd1a6b21598569620c40ff2069d, Newlib eb03ac1) nexus0: <RTEMS Nexus device> [zone: unpcb] kern.ipc.maxsockets limit reached info: lo0: link state changed to UP test select timeout test select connect worker: create new connect socket worker: connect test select read worker: write test select write worker: read test select close worker: close test pselect sigmask test pselect timeout test poll timeout test poll connect worker: create new connect socket worker: connect test poll read worker: write test poll write worker: read test poll close worker: close test kqueue timer test kqueue timer test kqueue connect worker: create new connect socket worker: connect test kqueue read worker: write test kqueue write worker: read test kqueue close worker: shutdown test kqueue user STACK USAGE BY THREAD ID NAME LOW HIGH CURRENT AVAIL USED 0x09010001 IDLE 0x4025fc00 0x402623ff 0x402620b0 10224 944 0x0a010001 UI1 0x40264fc0 0x4026cfbf 0x4026c990 32752 5056 0x0a010002 TIME 0x4026d530 0x4027552f 0x40275410 32752 528 0x0a010003 IRQS 0x40275540 0x4027d53f 0x4027d420 32752 384 0x0a010004 config_0 0x402a3880 0x402ab87f 0x402ab720 32752 448 0x0a010005 swi5: fast task 0x402abbb0 0x402b3baf 0x402b3a60 32752 432 0x0a010006 thread taskq 0x402b3d80 0x402bbd7f 0x402bbc20 32752 448 0x0a010007 swi6: Giant tas 0x402bc0b0 0x402c40af 0x402c3f60 32752 432 0x0a010008 swi6: task queu 0x402c43e0 0x402cc3df 0x402cc290 32752 1968 0x0a010009 kqueue_ctx task 0x402cc5b0 0x402d45af 0x402d4450 32752 448 0x0a01000a swi1: netisr 0 0x402d4800 0x402dc7ff 0x402dc3b0 32752 2096 0x0a01000b bufdaemon 0x40306a80 0x4030ea7f 0x4030e8a0 32752 1264 0x0a01000c vnlru 0x4030eb50 0x40316b4f 0x403168e0 32752 720 0x0a01000d syncer 0x40316c20 0x4031ec1f 0x4031e9e0 32752 672 0x0a01000e softirq_0 0x4031edf0 0x40326def 0x40326c90 32752 448 0x0a01000f bufspacedaemon- 0x40326ec0 0x4032eebf 0x4032ed20 32752 512 0x0a010010 WORK 0x4032ef90 0x4033178f 0x40331230 10224 1616 0x00000000 Interrupt Stack 0x40262400 0x40264bff 0x00000000 10224 480 *** END OF TEST LIBBSD SELECT AND POLL AND KQUEUE AND PIPE 1 ***
testsuite/include/rtems/bsd/test/network-config.h
#ifndef _RTEMS_BSD_TEST_NETWORK_CONFIG_H_ #define _RTEMS_BSD_TEST_NETWORK_CONFIG_H_ //#define LIBBSP_ARM_XILINX_ZYNQ_BSP_H #include <bsp.h> #if defined(LIBBSP_ARM_ALTERA_CYCLONE_V_BSP_H) #define NET_CFG_INTERFACE_0 "dwc0" //#elif defined(LIBBSP_AARCH64_A53_QEMU_BSP_H) // #define NET_CFG_INTERFACE_0 "dwc0" #elif defined(LIBBSP_ARM_REALVIEW_PBX_A9_BSP_H) #define NET_CFG_INTERFACE_0 "smc0" #elif defined(LIBBSP_ARM_XILINX_ZYNQ_BSP_H) #define NET_CFG_INTERFACE_0 "cgem0" #elif defined(LIBBSP_M68K_GENMCF548X_BSP_H) #define NET_CFG_INTERFACE_0 "fec0" #elif defined(LIBBSP_ARM_LPC32XX_BSP_H) #define NET_CFG_INTERFACE_0 "lpe0" #elif defined(LIBBSP_POWERPC_QORIQ_BSP_H) #if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) #define NET_CFG_INTERFACE_0 "fm1m3" #else #define NET_CFG_INTERFACE_0 "tsec0" #endif #elif defined(LIBBSP_ARM_ATSAM_BSP_H) #define NET_CFG_INTERFACE_0 "if_atsam0" #else #define NET_CFG_INTERFACE_0 "lo0" #endif #define NET_CFG_SELF_IP "192.168.0.10" #define NET_CFG_NETMASK "255.255.0.0" #define NET_CFG_PEER_IP "192.168.0.20" #define NET_CFG_GATEWAY_IP "192.168.0.1"
LIBBSP_ARM_XILINX_ZYNQ_BSP_H
rtemsbsd/include/bsp/nexus-devices.h
#elif defined(LIBBSP_ARM_XILINX_ZYNQ_BSP_H) #include <bsp/irq.h> RTEMS_BSD_DRIVER_XILINX_ZYNQ_SLCR; RTEMS_BSD_DRIVER_XILINX_ZYNQ_SDHCI0; RTEMS_BSD_DRIVER_XILINX_ZYNQ_SDHCI1; RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); RTEMS_BSD_DRIVER_E1000PHY; RTEMS_BSD_DRIVER_MMC; #elif defined(LIBBSP_AARCH64_XILINX_ZYNQMP_BSP_H) #include <bsp/irq.h> RTEMS_BSD_DRIVER_XILINX_ZYNQMP_SLCR; /* Qemu only applies user-mode networking to the first interface by default, so * all 4 CGEM instances must be configured in the Qemu arguments using * "-nic user,model=cadence_gem" for each nic. * * CGEM3 is used for LibBSD because all Zynq Ultrascale+ MPSoC dev boards treat * the highest-mapped CGEM as the primary interface. */ RTEMS_BSD_DRIVER_XILINX_ZYNQMP_CGEM0(ZYNQMP_IRQ_ETHERNET_0); RTEMS_BSD_DRIVER_XILINX_ZYNQMP_CGEM1(ZYNQMP_IRQ_ETHERNET_1); RTEMS_BSD_DRIVER_XILINX_ZYNQMP_CGEM2(ZYNQMP_IRQ_ETHERNET_2); RTEMS_BSD_DRIVER_XILINX_ZYNQMP_CGEM3(ZYNQMP_IRQ_ETHERNET_3); RTEMS_BSD_DRIVER_E1000PHY; RTEMS_BSD_DRIVER_UKPHY; RTEMS_BSD_DRIVER_XILINX_ZYNQMP_SDHCI0; RTEMS_BSD_DRIVER_XILINX_ZYNQMP_SDHCI1; RTEMS_BSD_DRIVER_MMC;
#if !defined(RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0) #define RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(_irq) \ RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM(0, 0xe000b000, _irq)
#if !defined(RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM) #define RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM(_num, _base, _irq) \ static const rtems_bsd_device_resource cgem ## _num ## _res[] = { \ { \ .type = RTEMS_BSD_RES_MEMORY, \ .start_request = 0, \ .start_actual = (_base) \ }, { \ .type = RTEMS_BSD_RES_IRQ, \ .start_request = 0, \ .start_actual = (_irq) \ } \ }; \ RTEMS_BSD_DEFINE_NEXUS_DEVICE(cgem, _num, \ RTEMS_ARRAY_SIZE(cgem ## _num ## _res), \ &cgem ## _num ## _res[0]) #endif /* RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM */
#define RTEMS_BSD_DEFINE_NEXUS_DEVICE(name, unit, resource_count, resources) \ extern struct sysinit SYSINIT_ENTRY_NAME(name##_nexusmodule); \ RTEMS_BSD_DEFINE_SET_ITEM(nexus, name##unit, rtems_bsd_device) = \ { #name, unit, (resource_count), (resources), \ &SYSINIT_ENTRY_NAME(name##_nexusmodule) }
#define RTEMS_BSD_DEFINE_SET_ITEM(set, sym, type) \ static RTEMS_BSD_SET_ALIGN( type ) type \ const __set_##set##_sym_##sym \ __section(".rtemsroset.bsd." __STRING(set) ".content.1") __used
/* * E1000 PHY */ #if !defined(RTEMS_BSD_DRIVER_E1000PHY) #define RTEMS_BSD_DRIVER_E1000PHY \ SYSINIT_DRIVER_REFERENCE(e1000phy, miibus); #endif /* RTEMS_BSD_DRIVER_E1000PHY */
./build/aarch64-rtems6-a53_lp64_qemu-default/testsuite/include/rtems/bsd/test/network-config.h
#ifndef _RTEMS_BSD_TEST_NETWORK_CONFIG_H_ #define _RTEMS_BSD_TEST_NETWORK_CONFIG_H_ #define LIBBSP_ARM_XILINX_ZYNQ_BSP_H #include <bsp.h> #if defined(LIBBSP_ARM_ALTERA_CYCLONE_V_BSP_H) #define NET_CFG_INTERFACE_0 "dwc0" #elif defined(LIBBSP_ARM_REALVIEW_PBX_A9_BSP_H) #define NET_CFG_INTERFACE_0 "smc0" #elif defined(LIBBSP_ARM_XILINX_ZYNQ_BSP_H) #define NET_CFG_INTERFACE_0 "cgem0" #elif defined(LIBBSP_M68K_GENMCF548X_BSP_H) #define NET_CFG_INTERFACE_0 "fec0" #elif defined(LIBBSP_ARM_LPC32XX_BSP_H) #define NET_CFG_INTERFACE_0 "lpe0" #elif defined(LIBBSP_POWERPC_QORIQ_BSP_H) #if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) #define NET_CFG_INTERFACE_0 "fm1m3" #else #define NET_CFG_INTERFACE_0 "tsec0" #endif #elif defined(LIBBSP_ARM_ATSAM_BSP_H) #define NET_CFG_INTERFACE_0 "if_atsam0"
In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-network-init.h:297, from ../../testsuite/debugger01/test_main.c:78: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-network-init.h:297, from ../../testsuite/lagg01/test_main.c:106: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-network-init.h:297, from ../../testsuite/pf02/test_main.c:193: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-network-init.h:297, from ../../testsuite/ping01/test_main.c:75: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-init.h:122, from ../../testsuite/rcconf02/test_main.c:294: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-network-init.h:297, from ../../testsuite/pf01/test_main.c:504: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-network-init.h:297, from ../../testsuite/nfs01/test_main.c:411: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-network-init.h:297, from ../../testsuite/telnetd01/test_main.c:86: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-network-init.h:297, from ../../testsuite/vlan01/test_main.c:123: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ../../rtemsbsd/include/machine/rtems-bsd-config.h:58, from ../../testsuite/include/rtems/bsd/test/default-network-init.h:297, from ../../testsuite/zerocopy01/test_main.c:252: ../../rtemsbsd/include/bsp/nexus-devices.h:102:36: error: 'ZYNQ_IRQ_ETHERNET_0' undeclared here (not in a function) 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~ ../../rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:481:26: note: in definition of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM' 481 | .start_actual = (_irq) \ | ^~~~ ../../rtemsbsd/include/bsp/nexus-devices.h:102:1: note: in expansion of macro 'RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0' 102 | RTEMS_BSD_DRIVER_XILINX_ZYNQ_CGEM0(ZYNQ_IRQ_ETHERNET_0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Waf: Leaving directory `/root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default' Build failed -> task in 'debugger01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'lagg01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'pf02.exe' failed with exit status 1 (run with -v to display more information) -> task in 'ping01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'rcconf02.exe' failed with exit status 1 (run with -v to display more information) -> task in 'pf01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'nfs01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'telnetd01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'vlan01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'zerocopy01.exe' failed with exit status 1 (run with -v to display more information)
添加
#define ZYNQ_IRQ_ETHERNET_0 54
#ifndef _RTEMS_BSD_TEST_NETWORK_CONFIG_H_ #define _RTEMS_BSD_TEST_NETWORK_CONFIG_H_ #define LIBBSP_ARM_XILINX_ZYNQ_BSP_H #define ZYNQ_IRQ_ETHERNET_0 54 #include <bsp.h> #if defined(LIBBSP_ARM_ALTERA_CYCLONE_V_BSP_H) #define NET_CFG_INTERFACE_0 "dwc0" #elif defined(LIBBSP_ARM_REALVIEW_PBX_A9_BSP_H) #define NET_CFG_INTERFACE_0 "smc0" #elif defined(LIBBSP_ARM_XILINX_ZYNQ_BSP_H) #define NET_CFG_INTERFACE_0 "cgem0" #elif defined(LIBBSP_M68K_GENMCF548X_BSP_H) #define NET_CFG_INTERFACE_0 "fec0" #elif defined(LIBBSP_ARM_LPC32XX_BSP_H) #define NET_CFG_INTERFACE_0 "lpe0" #elif defined(LIBBSP_POWERPC_QORIQ_BSP_H) <s6-a53_lp64_qemu-default/testsuite/include/rtems/bsd/test/network-config.h" 71L, 2685C written [root@centos7 rtems-libbsd-a64]# ./waf Waf: Entering directory `/root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default' [1903/2024] Compiling testsuite/debugger01/test_main.c [1924/2024] Compiling testsuite/lagg01/test_main.c [1939/2024] Compiling testsuite/nfs01/test_main.c [1944/2024] Compiling testsuite/pf01/test_main.c [1945/2024] Compiling testsuite/pf02/test_main.c [1946/2024] Compiling testsuite/ping01/test_main.c [1953/2024] Compiling testsuite/rcconf02/test_main.c [1967/2024] Compiling testsuite/telnetd01/test_main.c [2013/2024] Compiling testsuite/vlan01/test_main.c [2014/2024] Compiling testsuite/zerocopy01/test_main.c [2015/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/debugger01.exe [2016/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/lagg01.exe [2017/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/ping01.exe [2018/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/telnetd01.exe [2019/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/rcconf02.exe [2020/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/pf02.exe [2021/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/vlan01.exe [2022/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/zerocopy01.exe [2023/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/pf01.exe [2024/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/nfs01.exe /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(if_cgem.c.20.o): in function `cgem_mediachange': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760: undefined reference to `_bsd_cgem_set_ref_clk' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/cadence/if_cgem.c:1760:(.text.cgem_miibus_statchg+0xb8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_bsd_cgem_set_ref_clk' collect2: error: ld returned 1 exit status Waf: Leaving directory `/root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default' Build failed -> task in 'lagg01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'ping01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'vlan01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'pf01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'debugger01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'pf02.exe' failed with exit status 1 (run with -v to display more information) -> task in 'telnetd01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'rcconf02.exe' failed with exit status 1 (run with -v to display more information) -> task in 'zerocopy01.exe' failed with exit status 1 (run with -v to display more information) -> task in 'nfs01.exe' failed with exit status 1 (run with -v to display more information) [root@centos7 rtems-libbsd-a64]#
注释rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
./waf 成功
[2020/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/usbkbd01.exe [2021/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/usbmouse01.exe [2022/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/usbserial01.exe [2023/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/vlan01.exe [2024/2024] Linking build/aarch64-rtems6-a53_lp64_qemu-default/zerocopy01.exe Waf: Leaving directory `/root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default' 'build-aarch64-rtems6-a53_lp64_qemu-default' finished successfully (13.420s)
SYSINIT
SYSINIT是一个通用的调用排序与分别执行机制的框架。FreeBSD目前使用它来进行内核的动态初始化。SYSINIT使得FreeBSD的内核各子系统可以在内核或模块动态加载链接时被重整、添加、删除、替换,这样,内核和模块加载时就不必去修改一个静态的有序初始化安排表甚至重新编译内核。这个体系也使得内核模块(现在称为KLD可以与内核不同时编译、链接、在引导系统时加载,甚至在系统运行时加载。这些操作是通过"内核链接器"(kernel linker)和"链接器集合"(linker set)完成的。链接器集合(Linker Set)是一种链接方法。这种方法将整个程序源文件中静态申明的数据收集到一个可邻近寻址的数据单元中。 SYSINIT要依靠链接器获取遍布整个程序源代码多处申明的静态数据并把它们组成一个彼此相邻的数据块。这种链接方法被称为"链接器集合"(linker set)。SYSINIT使用两个链接器集合以维护两个数据集合,包含每个数据条目的调用顺序、函数、一个会被提交给该函数的数据指针。
freebsd/sys/sys/linker_set.h
FreeBSD为了应付这种情况, 使用一种叫做SYSINIT的机制. 我们知道FreeBSD使用一种叫做 ELF的二进制目标执行文件格式. 这种文件格式允许文件内部组织成结构化的方式, 文件内部可以由不同的组成部分(section), FreeBSD正是利用了这种机制.
FreeBSD使用GNU GCC作为其C语言编译器, 这种编译器允许在C源程序中嵌入汇编语言代码, FreeBSD通过在C源程序中加入汇编指令来在目标文件中增加额外的section, 在文件 /sys/sys/linker_set.h中定义如下:
[root@centos7 rtems-libbsd]# find ./ -name linker_set.h ./freebsd/sys/sys/linker_set.h [root@centos7 rtems-libbsd]# cat ./freebsd/sys/sys/linker_set.h /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1999 John D. Polstra * Copyright (c) 1999,2001 Peter Wemm <peter@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _SYS_LINKER_SET_H_ #define _SYS_LINKER_SET_H_ #ifndef _SYS_CDEFS_H_ #error this file needs sys/cdefs.h as a prerequisite #endif #ifdef __rtems__ #include <sys/_types.h> #endif /* __rtems__ */ /* * The following macros are used to declare global sets of objects, which * are collected by the linker into a `linker_set' as defined below. * For ELF, this is done by constructing a separate segment for each set. */ #if defined(__powerpc64__) /* * Move the symbol pointer from ".text" to ".data" segment, to make * the GCC compiler happy: */ #define __MAKE_SET_CONST #else #define __MAKE_SET_CONST const #endif /* * Private macros, not to be used outside this header file. */ #ifdef __GNUCLIKE___SECTION #ifndef __rtems__ #define __MAKE_SET_QV(set, sym, qv) \ __GLOBL(__CONCAT(__start_set_,set)); \ __GLOBL(__CONCAT(__stop_set_,set)); \ static void const * qv \ __set_##set##_sym_##sym __section("set_" #set) \ __used = &(sym) #define __MAKE_SET(set, sym) __MAKE_SET_QV(set, sym, __MAKE_SET_CONST) #else /* __rtems__ */ #define RTEMS_BSD_DEFINE_SET(set, type) \ type const __CONCAT(_bsd__start_set_,set)[0] \ __section(".rtemsroset.bsd." __STRING(set) ".begin") __used; \ type const __CONCAT(_bsd__stop_set_,set)[0] \ __section(".rtemsroset.bsd." __STRING(set) ".end") __used #define RTEMS_BSD_DECLARE_SET(set, type) \ extern type const __CONCAT(_bsd__start_set_,set)[0]; \ extern type const __CONCAT(_bsd__stop_set_,set)[0] #define RTEMS_BSD_DEFINE_SET_ITEM(set, sym, type) \ static type const __set_##set##_sym_##sym \ __section(".rtemsroset.bsd." __STRING(set) ".content.1") __used #define RTEMS_BSD_DEFINE_SET_ITEM_ORDERED(set, sym, order, type) \ static type const __set_##set##_sym_##sym \ __section(".rtemsroset.bsd." __STRING(set) ".content.0." RTEMS_XSTRING( order )) __used #define __MAKE_SET(set, sym) \ RTEMS_BSD_DEFINE_SET_ITEM(set, sym, const void *) = &sym #define RTEMS_BSD_DEFINE_RWSET(set, type) \ type __CONCAT(_bsd__start_set_,set)[0] \ __section(".rtemsrwset.bsd." __STRING(set) ".begin") __used; \ type __CONCAT(_bsd__stop_set_,set)[0] \ __section(".rtemsrwset.bsd." __STRING(set) ".end") __used #define RTEMS_BSD_DECLARE_RWSET(set, type) \ extern type __CONCAT(_bsd__start_set_,set)[0]; \ extern type __CONCAT(_bsd__stop_set_,set)[0] #define RTEMS_BSD_DEFINE_RWSET_ITEM(set, sym, type) \ static type __set_##set##_sym_##sym \ __section(".rtemsrwset.bsd." __STRING(set) ".content") __used #define __MAKE_RWSET(set, sym) \ RTEMS_BSD_DEFINE_RWSET_ITEM(set, sym, const void *) = &sym #endif /* __rtems__ */ #else /* !__GNUCLIKE___SECTION */ #error this file needs to be ported to your compiler #endif /* __GNUCLIKE___SECTION */ /* * Public macros. */ #define TEXT_SET(set, sym) __MAKE_SET(set, sym) #define DATA_SET(set, sym) __MAKE_SET(set, sym) #ifndef __rtems__ #define DATA_WSET(set, sym) __MAKE_SET_QV(set, sym, ) #else /* __rtems__ */ #define DATA_WSET(set, sym) __MAKE_RWSET(set, sym) #endif /* __rtems__ */ #define BSS_SET(set, sym) __MAKE_SET(set, sym) #define ABS_SET(set, sym) __MAKE_SET(set, sym) #define SET_ENTRY(set, sym) __MAKE_SET(set, sym) /* * Initialize before referring to a given linker set. */ #ifndef __rtems__ #define SET_DECLARE(set, ptype) \ extern ptype __weak_symbol *__CONCAT(__start_set_,set); \ extern ptype __weak_symbol *__CONCAT(__stop_set_,set) #define SET_BEGIN(set) \ (&__CONCAT(__start_set_,set)) #define SET_LIMIT(set) \ (&__CONCAT(__stop_set_,set)) #else /* __rtems__ */ #define SET_DECLARE(set, ptype) \ RTEMS_BSD_DECLARE_SET(set, ptype *) #define RWSET_DECLARE(set, ptype) \ RTEMS_BSD_DECLARE_RWSET(set, ptype *) static __inline __uintptr_t _linker_set_obfuscate(const void *marker) { /* Obfuscate the variable, so that the compiler cannot optimize */ __asm__("" : "+r" (marker)); return ((__uintptr_t)marker); } #define SET_BEGIN(set) \ ((__typeof(&__CONCAT(_bsd__start_set_,set)[0])) \ _linker_set_obfuscate(__CONCAT(_bsd__start_set_,set))) #define SET_LIMIT(set) \ ((__typeof(&__CONCAT(_bsd__stop_set_,set)[0])) \ _linker_set_obfuscate(__CONCAT(_bsd__stop_set_,set))) #endif /* __rtems__ */ /* * Iterate over all the elements of a set. * * Sets always contain addresses of things, and "pvar" points to words * containing those addresses. Thus is must be declared as "type **pvar", * and the address of each set item is obtained inside the loop by "*pvar". */ #define SET_FOREACH(pvar, set) \ for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++) #define SET_ITEM(set, i) \ ((SET_BEGIN(set))[i]) /* * Provide a count of the items in a set. */ #define SET_COUNT(set) \ (SET_LIMIT(set) - SET_BEGIN(set)) #endif /* _SYS_LINKER_SET_H_ */j
简单的DATA_SET
#ifdef __alpha__ #define MAKE_SET(set, sym) static void const * const __set_##set##_sym_##sym = &sym; __asm(".align 3"); __asm(".section .set." #set ",\"aw\""); __asm(".quad " #sym); __asm(".previous") #else #define MAKE_SET(set, sym) #define MAKE_SET(set, sym) static void const * const __set_##set##_sym_##sym = &sym; __asm(".section .set." #set ",\"aw\""); __asm(".long " #sym); __asm(".previous") #endif #define TEXT_SET(set, sym) MAKE_SET(set, sym) #define DATA_SET(set, sym) MAKE_SET(set, sym)
程序一旦在某处调用DATA_SET宏指令, 就会将相应的汇编符号加入到目标文件. 例如: int myint;DATA_SET(myset, myint);
这两句话将导致在目标文件中创建一个myset section, 并且myint的地址将被放入这个 section中.
系统的初始化必须按严格的顺序进行, 为此FreeBSD定义了很多子系统的顺序号, 这些顺序连同SYSINIT的许多相关定义在/sys/sys/kernel.h头文件中:
[root@centos7 rtems-libbsd]# cat ./freebsd/sys/sys/kernel.h
enum sysinit_sub_id { SI_SUB_DUMMY = 0x0000000, /* not executed; for linker*/ SI_SUB_DONE = 0x0000001, /* processed*/ SI_SUB_TUNABLES = 0x0700000, /* establish tunable values */ SI_SUB_COPYRIGHT = 0x0800001, /* first use of console*/ SI_SUB_VM = 0x1000000, /* virtual memory system init*/ SI_SUB_KMEM = 0x1800000, /* kernel memory*/ SI_SUB_HYPERVISOR = 0x1A40000, /* * Hypervisor detection and * virtualization support * setup. */ SI_SUB_WITNESS = 0x1A80000, /* witness initialization */ SI_SUB_MTX_POOL_DYNAMIC = 0x1AC0000, /* dynamic mutex pool */ SI_SUB_LOCK = 0x1B00000, /* various locks */ SI_SUB_EVENTHANDLER = 0x1C00000, /* eventhandler init */ SI_SUB_VNET_PRELINK = 0x1E00000, /* vnet init before modules */ SI_SUB_KLD = 0x2000000, /* KLD and module setup */ SI_SUB_CPU = 0x2100000, /* CPU resource(s)*/ SI_SUB_RACCT = 0x2110000, /* resource accounting */ SI_SUB_KDTRACE = 0x2140000, /* Kernel dtrace hooks */ SI_SUB_RANDOM = 0x2160000, /* random number generator */ SI_SUB_MAC = 0x2180000, /* TrustedBSD MAC subsystem */ SI_SUB_MAC_POLICY = 0x21C0000, /* TrustedBSD MAC policies */ SI_SUB_MAC_LATE = 0x21D0000, /* TrustedBSD MAC subsystem */ SI_SUB_VNET = 0x21E0000, /* vnet 0 */ SI_SUB_INTRINSIC = 0x2200000, /* proc 0*/ SI_SUB_VM_CONF = 0x2300000, /* config VM, set limits*/ SI_SUB_DDB_SERVICES = 0x2380000, /* capture, scripting, etc. */ SI_SUB_RUN_QUEUE = 0x2400000, /* set up run queue*/ SI_SUB_KTRACE = 0x2480000, /* ktrace */ SI_SUB_OPENSOLARIS = 0x2490000, /* OpenSolaris compatibility */ SI_SUB_AUDIT = 0x24C0000, /* audit */ SI_SUB_CREATE_INIT = 0x2500000, /* create init process*/ SI_SUB_SCHED_IDLE = 0x2600000, /* required idle procs */ SI_SUB_MBUF = 0x2700000, /* mbuf subsystem */ SI_SUB_INTR = 0x2800000, /* interrupt threads */ SI_SUB_TASKQ = 0x2880000, /* task queues */ #ifdef EARLY_AP_STARTUP SI_SUB_SMP = 0x2900000, /* start the APs*/ #endif SI_SUB_SOFTINTR = 0x2A00000, /* start soft interrupt thread */ SI_SUB_DEVFS = 0x2F00000, /* devfs ready for devices */ SI_SUB_INIT_IF = 0x3000000, /* prep for net interfaces */ SI_SUB_NETGRAPH = 0x3010000, /* Let Netgraph initialize */ SI_SUB_DTRACE = 0x3020000, /* DTrace subsystem */ SI_SUB_DTRACE_PROVIDER = 0x3048000, /* DTrace providers */ SI_SUB_DTRACE_ANON = 0x308C000, /* DTrace anon enabling */ SI_SUB_DRIVERS = 0x3100000, /* Let Drivers initialize */ SI_SUB_CONFIGURE = 0x3800000, /* Configure devices */ SI_SUB_VFS = 0x4000000, /* virtual filesystem*/ SI_SUB_CLOCKS = 0x4800000, /* real time and stat clocks*/ SI_SUB_SYSV_SHM = 0x6400000, /* System V shared memory*/ SI_SUB_SYSV_SEM = 0x6800000, /* System V semaphores*/ SI_SUB_SYSV_MSG = 0x6C00000, /* System V message queues*/ SI_SUB_P1003_1B = 0x6E00000, /* P1003.1B realtime */ SI_SUB_PSEUDO = 0x7000000, /* pseudo devices*/ SI_SUB_EXEC = 0x7400000, /* execve() handlers */ SI_SUB_PROTO_BEGIN = 0x8000000, /* VNET initialization */ SI_SUB_PROTO_PFIL = 0x8100000, /* Initialize pfil before FWs */ SI_SUB_PROTO_IF = 0x8400000, /* interfaces*/ SI_SUB_PROTO_DOMAININIT = 0x8600000, /* domain registration system */ SI_SUB_PROTO_MC = 0x8700000, /* Multicast */ SI_SUB_PROTO_DOMAIN = 0x8800000, /* domains (address families?)*/ SI_SUB_PROTO_FIREWALL = 0x8806000, /* Firewalls */
子系统内还有顺序号:
enum sysinit_elem_order {
SI_ORDER_FIRST = 0x0000000, /* first*/
SI_ORDER_SECOND = 0x0000001, /* second*/
SI_ORDER_THIRD = 0x0000002, /* third*/
SI_ORDER_MIDDLE = 0x1000000, /* somewhere in the middle */
SI_ORDER_ANY = 0xfffffff /* last*/
};
DATA_SET(sysinit_set,uniquifier ## _sys_init)
FreeBSD为每个想要在系统初始化时被调用的函数, 定义两个函数类型: typedef void (*sysinit_nfunc_t) __P((void *)); typedef void (*sysinit_cfunc_t) __P((const void *)); 它们是系统初始化被调用时使用的函数原型. 两个重要的宏使得初始化函数能够在系统开始时被执行: #define C_SYSINIT(uniquifier, subsystem, order, func, ident) static struct sysinit uniquifier ## _sys_init = { subsystem, order, func, ident }; DATA_SET(sysinit_set,uniquifier ## _sys_init); #define SYSINIT(uniquifier, subsystem, order, func, ident) C_SYSINIT(uniquifier, subsystem, order, (sysinit_cfunc_t)(sysinit_nfunc_t)func, (void *)ident) 其中每个初始化函数被存储成这样一个结构: struct sysinit { unsigned int subsystem; /* subsystem identifier*/ unsigned int order; /* init order within subsystem*/ sysinit_cfunc_t func; /* function */ const void *udata; /* multiplexer/argument */ };
这个结构包含了子系统编号, 子系统中的顺序号, 初始化函数的地址, 以及这个函数使用的参数.
现在如果有个函数想要在系统启动时自动被调用, 并且知道这个函数是为VM子系统做准备工作, 可以这样申明:
long myvar;
void init_myvar(void *p)
{
*(long *)p = 2;
}
SYSINIT(init_myvar, SI_SUB_VM, 1000, init_myvar, &myvar)
这样声明的初始化过程分布在很多目标文件中, 当gcc的连接编辑器ld运行时就会把属于同一个section的数据合并到一个连续的地址块中. 由于在这个section中包含的只能是指向sysinit结构的指针,这样FreeBSD就可以把这个地址当成一个sysinit* 的数组, FreeBSD找出这个sysinit_set地址, 边历这个数组并调用其中的初始化函数. 为了确切知道这个section的大小(直接读ELF是可能的,但是那样太复杂,要知道kernel调用初始化过程时文件系统可能还没有初始化呢), 系统中包含一个工具 gensetdefs, 这个工具能扫描给出的一组.o目标文件, 并找到任何名字是由.set.开头的 section, 它统计有多少个这样的的初始化函数, 并在sysinit_set的开头生成一个长整形计数器. gensetdefs生成三个文件:
setdef0.c setdef1.c setdefs.h
文件setdef0.c的内容:
-------------------------------------------------------- /* THIS FILE IS GENERATED, DO NOT EDIT. */ #define DEFINE_SET(set, count) __asm__(".section .set." #set ",\"aw\""); __asm__(".globl " #set); __asm__(".type " #set ",@object"); __asm__(".p2align 2"); __asm__(#set ":"); __asm__(".long " #count); __asm__(".previous") #include "setdefs.h" /* Contains a `DEFINE_SET' for each set */ -------------------------------------------------------- 这里的DEFINE_SET效果就是申明一C结构: struct linker_set { int ls_length; void *ls_items[1]; /* really ls_length of them, * trailing NULL */ };
文件setdef1.c的内容:
-------------------------------------------------------- /* THIS FILE IS GENERATED, DO NOT EDIT. */ #define DEFINE_SET(set, count) __asm__(".section .set." #set ",\"aw\""); __asm__(".long 0"); __asm__(".previous") #include "setdefs.h" /* Contains a `DEFINE_SET' for each set */ 这个DEFINE_SET在某个section中放入一个 long 0. --------------------------------------------------------
文件setdefs.h的内容:
DEFINE_SET(cons_set, 3);
DEFINE_SET(kbddriver_set, 2);
DEFINE_SET(periphdriver_set, 5);
DEFINE_SET(scrndr_set, 9);
DEFINE_SET(scterm_set, 1);
DEFINE_SET(sysctl_set, 552);
DEFINE_SET(sysinit_set, 323);
DEFINE_SET(sysuninit_set, 155);
DEFINE_SET(vga_set, 9);
DEFINE_SET(videodriver_set, 4);
当kernel被连接时, 在Makefile中setdef0.o被安排最前面, 这样ld就把这个初始化函数的计数器安排在这个section的最前面. FreeBSD kernel就能从这个section的开头读到这个计数器, 也就知道了有多少个初始化函数. 在Makefile中被安排在中间的的是FreeBSD的其他 .o文件, 最后由setdef1.o压阵. setdef1.c定义了一个空指针,用以表示这个section的结束 ,这种安排, 我把它叫做夹三明治.
初始化过程的调用被安排在内核 /sys/kern/init_main.c的mi_startup函数中, mi_startup 是系统启动过程中, 第一个被执行的C语言函数, 它做的第一件事情就是调用这些初始化函数, 开始时对所有的初始化过程做优先级排序, 然后顺序调用它们.
void mi_startup(void) { register struct sysinit **sipp; /* system initialization*/ register struct sysinit **xipp; /* interior loop of sort*/ register struct sysinit *save; /* bubble*/ restart: 这是优先级别排序, 这里没有使用那个在setdef0.c中定义的计数器, 而是使用 了setdef1.c中定义的空指针作为结束标志. /* * Perform a bubble sort of the system initialization objects by * their subsystem (primary key) and order (secondary key). */ for (sipp = sysinit; *sipp; sipp++) { for (xipp = sipp + 1; *xipp; xipp++) { if ((*sipp)->subsystem < (*xipp)->subsystem || ((*sipp)->subsystem == (*xipp)->subsystem && (*sipp)->order <= (*xipp)->order)) continue; /* skip*/ save = *sipp; *sipp = *xipp; *xipp = save; } } /* * Traverse the (now) ordered list of system initialization tasks. * Perform each task, and continue on to the next task. * * The last item on the list is expected to be the scheduler, * which will not return. */ for (sipp = sysinit; *sipp; sipp++) { if ((*sipp)->subsystem == SI_SUB_DUMMY) continue; /* skip dummy task(s)*/ 这是按顺序调用: /* * Traverse the (now) ordered list of system initialization tasks. * Perform each task, and continue on to the next task. * * The last item on the list is expected to be the scheduler, * which will not return. */ for (sipp = sysinit; *sipp; sipp++) { if ((*sipp)->subsystem == SI_SUB_DUMMY) continue; /* skip dummy task(s)*/ if ((*sipp)->subsystem == SI_SUB_DONE) continue; /* Call function */ (*((*sipp)->func))((*sipp)->udata); /* Check off the one we're just done */ (*sipp)->subsystem = SI_SUB_DONE; /* Check if we've installed more sysinit items via KLD */ if (newsysinit != NULL) { if (sysinit != (struct sysinit **)sysinit_set.ls_items) free(sysinit, M_TEMP); sysinit = newsysinit; newsysinit = NULL; goto restart; } } panic("Shouldn't get here!"); }
rtems struct sysinit
grep SYSINIT -rn * | grep rtems | grep e1000 rtemsbsd/include/machine/rtems-bsd-nexus-bus.h:615: SYSINIT_DRIVER_REFERENCE(e1000phy, miibus);
#ifndef __rtems__ #define C_SYSINIT(uniquifier, subsystem, order, func, ident) \ static struct sysinit uniquifier ## _sys_init = { \ subsystem, \ order, \ func, \ (ident) \ }; \ DATA_SET(sysinit_set,uniquifier ## _sys_init) #else /* __rtems__ */ #define SYSINIT_ENTRY_NAME(uniquifier) \ _bsd_ ## uniquifier ## _sys_init #define SYSINIT_REFERENCE_NAME(uniquifier) \ _bsd_ ## uniquifier ## _sys_init_ref #define C_SYSINIT(uniquifier, subsystem, order, func, ident) \ struct sysinit SYSINIT_ENTRY_NAME(uniquifier) = { \ subsystem, \ order, \ func, \ (ident) \ }; \ DATA_SET(sysinit_set,SYSINIT_ENTRY_NAME(uniquifier)) //////// DATA_SET #define SYSINIT_REFERENCE(uniquifier) \ extern struct sysinit SYSINIT_ENTRY_NAME(uniquifier); \ static struct sysinit const * const \ SYSINIT_REFERENCE_NAME(uniquifier) __used \ = &SYSINIT_ENTRY_NAME(uniquifier) #define SYSINIT_MODULE_REFERENCE(mod) \ SYSINIT_REFERENCE(mod ## module) #define SYSINIT_DRIVER_REFERENCE(driver, bus) \ SYSINIT_MODULE_REFERENCE(driver ## _ ## bus) #endif /* __rtems__ */
arm-rtems6-objdump -t build/arm-rtems6-xilinx_zynq_a9_qemu-default/media01.exe > objdump.txt
[root@centos7 rtems-libbsd-a64]# cat objdump.txt | grep gem 00228820 l O .rodata 00000018 cgem0_res 00377af4 l O .rtemsroset 00000014 __set_nexus_sym_cgem0 00000000 l df *ABS* 00000000 if_cgem.c 0010523c l F .text 0000000e cgem_getaddr 0010524c l F .text 00000092 cgem_reset 001052e0 l F .text 000000a4 cgem_miibus_statchg 00105384 l F .text 00000004 cgem_miibus_linkchg 00105388 l F .text 00000060 cgem_miibus_writereg 001053e8 l F .text 00000060 cgem_miibus_readreg 00105448 l F .text 000000be cgem_stop 00105508 l F .text 00000110 cgem_detach 00105618 l F .text 000000de cgem_clean_tx 001056f8 l F .text 000000b2 cgem_fill_rqueue 001057ac l F .text 0000003e cgem_get_segs_for_tx 001057ec l F .text 0000018a cgem_start_locked 00105978 l F .text 0000002c cgem_start 001059a4 l F .text 0000003e cgem_ifmedia_sts 001059e4 l F .text 00000056 cgem_ifmedia_upd 00105a3c l F .text 0000038c cgem_tick 00105dc8 l F .text 0000014a cgem_rx_filter 00105f14 l F .text 0000010a cgem_init_locked.part.0 00106020 l F .text 00000226 cgem_ioctl 00106248 l F .text 00000256 cgem_intr 001064a0 l F .text 00000078 cgem_probe 00106518 l F .text 00000032 cgem_init 0010654c l F .text 00000ff4 cgem_attach 0045aa40 l O .bss 00000004 cgem_devclass 00400894 l O .data 0000000c _cgem_depend_on_ether 004008a0 l O .data 0000000c _cgem_depend_on_miibus 004008ac l O .data 0000000c _miibus_cgem_depend_on_kernel 004008b8 l O .data 0000000c _cgem_nexus_depend_on_kernel 00400974 l O .data 0000000c cgem_nexus_mod 00400998 l O .data 0000000c miibus_cgem_mod 004008e4 l O .data 00000010 _mod_metadata_md_cgem_nexus 004008f4 l O .data 00000010 _mod_metadata_md_cgem_nexus_on_kernel 00400904 l O .data 00000010 _mod_metadata_md_cgem_on_ether 00400914 l O .data 00000010 _mod_metadata_md_cgem_on_miibus 00400924 l O .data 00000010 _mod_metadata_md_miibus_cgem 00400934 l O .data 00000010 _mod_metadata_md_miibus_cgem_on_kernel 00400944 l O .data 00000018 cgem_driver 00229cd4 l O .rodata 00000040 cgem_methods 0040095c l O .data 00000018 cgem_nexus_driver_mod 00400980 l O .data 00000018 miibus_cgem_driver_mod 00377a1c l O .rtemsroset 00000004 __set_modmetadata_set_sym__mod_metadata_md_cgem_on_ether 00377a20 l O .rtemsroset 00000004 __set_modmetadata_set_sym__mod_metadata_md_cgem_on_miibus 00377a24 l O .rtemsroset 00000004 __set_modmetadata_set_sym__mod_metadata_md_miibus_cgem 00377a28 l O .rtemsroset 00000004 __set_modmetadata_set_sym__mod_metadata_md_miibus_cgem_on_kernel 00377a2c l O .rtemsroset 00000004 __set_modmetadata_set_sym__mod_metadata_md_cgem_nexus 00377a30 l O .rtemsroset 00000004 __set_modmetadata_set_sym__mod_metadata_md_cgem_nexus_on_kernel 00414284 l O .rtemsrwset 00000004 __set_sysinit_set_sym__bsd_miibus_cgemmodule_sys_init 00414288 l O .rtemsrwset 00000004 __set_sysinit_set_sym__bsd_cgem_nexusmodule_sys_init 00414390 l O .rtemsrwset 00000004 __set_sysinit_set_sym__bsd_if_bridgemodule_sys_init 0013ab18 l F .text 000000be in_purgemaddrs 00411128 l O .data 00000040 _bsd_sysctl___vfs_ncpurgeminvnodes 00411234 l O .data 00000004 ncpurgeminvnodes 00378298 l O .rtemsroset 00000004 __set_sysctl_set_sym__bsd_sysctl___vfs_ncpurgeminvnodes 00000000 l df *ABS* 00000000 sigemptyset.c 004008d4 g O .data 00000010 _bsd_miibus_cgemmodule_sys_init 004008c4 g O .data 00000010 _bsd_cgem_nexusmodule_sys_init 00105150 g F .text 000000ec _bsd_cgem_set_ref_clk 001f5120 g F .text 0000001e sigemptyset 004087a8 g O .data 00000010 _bsd_if_bridgemodule_sys_init
e1000
#define RTEMS_BSD_DRIVER_E1000PHY #define SYSINIT_NEED_NET_IF_EM
rtemsbsd/include/machine/rtems-bsd-sysinit.h:109: SYSINIT_DRIVER_REFERENCE(igb, pci)
#define SYSINIT_NEED_NET_IF_EM \ SYSINIT_DRIVER_REFERENCE(em, pci) #define SYSINIT_NEED_NET_IF_IGB \ SYSINIT_DRIVER_REFERENCE(igb, pci)
rtemsbsd/include/machine/rtems-bsd-nexus-bus.h
#if !defined(RTEMS_BSD_DRIVER_PCI_LEM) #define RTEMS_BSD_DRIVER_PCI_LEM \ SYSINIT_DRIVER_REFERENCE(lem, pci); #endif /* RTEMS_BSD_DRIVER_PCI_LEM */ /* * Intel's Gigabit Driver. */ #if !defined(RTEMS_BSD_DRIVER_PCI_IGB) #define RTEMS_BSD_DRIVER_PCI_IGB \ SYSINIT_DRIVER_REFERENCE(igb, pci); #endif /* RTEMS_BSD_DRIVER_PCI_IGB */ /* * Intel's EM Driver. */ #if !defined(RTEMS_BSD_DRIVER_PCI_EM) #define RTEMS_BSD_DRIVER_PCI_EM \ SYSINIT_DRIVER_REFERENCE(em, pci); #endif /* RTEMS_BSD_DRIVER_PCI_EM */
添加em驱动初始化代码
#if !defined(RTEMS_BSD_DRIVER_PCI_EM) #define RTEMS_BSD_DRIVER_PCI_EM \ RTEMS_BSD_DEFINE_NEXUS_DEVICE(ofwbus, 0, 0, NULL); SYSINIT_DRIVER_REFERENCE(simplebus, ofwbus); SYSINIT_DRIVER_REFERENCE(em, simplebus); //SYSINIT_DRIVER_REFERENCE(em, pci); #endif /* RTEMS_BSD_DRIVER_PCI_EM */
bsps/shared/start/bsp-fdt.c:64:const void *bsp_fdt_get(void)
/root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status /root/development/rtems/compiler/6/lib/gcc/aarch64-rtems6/10.3.1/../../../../aarch64-rtems6/bin/ld: ./libbsd.a(openfirm.c.20.o): in function `xrefinfo_init': /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154: undefined reference to `bsp_fdt_get' /root/development/rtems/rtems-libbsd-a64/build/aarch64-rtems6-a53_lp64_qemu-default/../../freebsd/sys/dev/ofw/openfirm.c:154:(.text.xrefinfo_init+0x8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `bsp_fdt_get' collect2: error: ld returned 1 exit status
需要把
bsps/aarch64/a53/include/bsp.h:65:#define BSP_FDT_IS_SUPPORTED 关掉
[root@centos7 rtems]# grep BSP_FDT_IS_SUPPORTED -rn * bsps/aarch64/a53/include/bsp.h:65:#define BSP_FDT_IS_SUPPORTED bsps/arm/altera-cyclone-v/start/bspgetworkarea.c:43:#ifdef BSP_FDT_IS_SUPPORTED bsps/arm/altera-cyclone-v/start/bspgetworkarea.c:216:#else /* !BSP_FDT_IS_SUPPORTED */ bsps/arm/altera-cyclone-v/start/bspgetworkarea.c:222:#endif /* BSP_FDT_IS_SUPPORTED */ bsps/arm/altera-cyclone-v/start/bspstart.c:30:#ifdef BSP_FDT_IS_SUPPORTED bsps/arm/altera-cyclone-v/start/bspstart.c:108:#ifdef BSP_FDT_IS_SUPPORTED bsps/arm/beagle/include/bsp.h:207:#define BSP_FDT_IS_SUPPORTED bsps/arm/imx/include/bsp.h:38:#define BSP_FDT_IS_SUPPORTED bsps/arm/imxrt/include/bsp.h:59:#define BSP_FDT_IS_SUPPORTED bsps/arm/raspberrypi/include/bsp.h:45:#define BSP_FDT_IS_SUPPORTED bsps/arm/raspberrypi/start/bspstart.c:105:#ifdef BSP_FDT_IS_SUPPORTED bsps/arm/raspberrypi/start/bspstart.c:126:#endif /* BSP_FDT_IS_SUPPORTED */ bsps/include/bsp/fdt.h:20:#define BSP_FDT_IS_SUPPORTED bsps/include/bsp/fdt.h:27: * BSP_FDT_IS_SUPPORTED. bsps/powerpc/qoriq/include/bsp.h:56:#define BSP_FDT_IS_SUPPORTED bsps/shared/start/bsp-fdt.c:22:#ifndef BSP_FDT_IS_SUPPORTED build/c4che/spec_build.pickle:134940:S'BSP_FDT_IS_SUPPORTED' spec/build/bsps/arm/altera-cyclone-v/optfdten.yml:14:name: BSP_FDT_IS_SUPPORTED testsuites/libtests/ofw01/init.c:71:#ifdef BSP_FDT_IS_SUPPORTED
FreeBSD设备驱动管理
在FreeBSD操作系统中,注册按先总线设备后叶设备的顺序进行,设备的启动过程如下图所示:
1.root_bus
2.nexus/simplebus
3.ACPI设备
4.PCI设备
系统统中的root_bus设备并不执行具体的设备驱动,它实际上是提供给其它设备一个根结点,以便所有的设备都能够通过它联系在一起,形成一个有机的整体。Nexus设备负责初始化系统资源的大小,同时提供ACPI资源链支持。
也就是说FreeBSD的设备驱动管理是按照树节点方法,一层一层往上挂载。文章后面会根据具体例子详细介绍设备树
FreeBSD下PCI总线类设备驱动
FreeBSD下PCI总线类设备驱动程序框架:
这里采用PCI总线进行分析
PCI类设备驱动的组成主要包括以下4个部分:
(1) DRIVER_MODULE;
(2) 结构driver_t;
(3) 设备标识表;
(4) 设备类。
首先是DRIVER_MODULE设备宏,该定义非常重要:
每个设备驱动一般被定义为一个内核模块,声明方式如下:
DRIVER_MODULE(name,busname,driver,devclass,evh,arg)
name: 模块名
busname: 挂接的总线(PCI、NEXUS、ISA等)
driver: 驱动程序结构的变量
devclass: 设备类
evh: 驱动程序加载/卸载时的事件处理函数
arg: evh的参数
比如USB中存储设备umass驱动的设备宏定义如下:
DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, NULL, 0);
模块名是umass, 挂接的总线是uhub(uhub也是挂接在usbus总线上,而usbus挂接在musbotg总线上,最后musbotg挂接在usbss上,usbss挂接到最后的总线nexus上。完成了一个完整的设备树挂接),驱动变量是umass_driver,设备类是umass_devclass。
结构driver_t
设备驱动由结构driver_t描述,driver_t定义如下:
struct driver{
const char *name;
kobj_method_t *method;
size_t size;
u_int refs;
kobj_ops_t ops;
void *priv; };
name: 设备驱动名
priv: 对应设备实例的私有数据,主要用于存放设备的私有数据结构
methods: 定义操作该设备的方法
数组中的每个元素是通过使用宏DEVMETHOD来声明的,如DEVMETHOD(device_probe,ata_pci_probe),其中第1个参数是系统保留的符号,第2个参数是驱动程序中的函数。至于数组中定义了哪些方法是由两方面决定的:设备所在的总线和设备的具体功能。驱动程序中的方法可以分为两类:设备接口和总线方法。
设备接口:
设备接口负责识别、检测、连接设备,另外还可以关闭、挂起、恢复设备。在这些接口中,部分接口因设备的不同而不同,需要单独实现,而有的接口有缺省实现。要根据设备的功能实现部分或全部的接口,设备不支持的接口没有必要实现也无法实现。主要的接口包括:
device_identify: 仅用于不能自识别的总线,如ISA、ACPI,总线利用该操作识别设备并将其加入到总线中;
device_probe: 为设备在设备类中寻找合适的驱动,确定能否操作该设备、是否有足够的资源;
device_attach: 为该设备分配系统资源,将设备加入到系统中,注册设备的中断处理函数;
device_shutdown: 关闭设备; device_suspend: 挂起设备; device_resume: 恢复设备;
总线方法:
总线方法是总线在处理该设备时所需要的方法,一般因总线不同而不同。系统提供了缺省的定义,用户可以根据设备的具体需要,遵照方法的语义另外定义部分方法,主要方法有:
bus_print_child: 打印显示总线的一个子设备信息
bus_alloc_resource: 为总线的设备分配资源;
bus_release_resource: 为总线的设备释放资源;
bus_activate_resource: 激活资源;
bus_deactivate_resource: 实效资源;
bus_setup_intr: 注册设备中断处理函数;
bus_teardown_intr: 注销设备中断处理函数;
设备类数据结构
一类设备一般具有相似的属性,如网卡设备一般都同网络协议栈交互,所有的声卡也都具有相似的属性。设备类数据结构主要包括一个驱动程序结构链表和一个设备数组,具体的定义如下所示:
struct devclass{
TAILQ_ENTRY(devclass) link;
driver_list_t drivers;
char *name;
device_t *devices;
int maxuint; };
设备类主要用于系统管理设备驱动使用,用户自己可以为设备声明设备类,并没有严格的规定,例如在ata驱动程序中声明了一个设备类的实例:
static devclass_t ata_pci_devclass;
DRIVER_MODULE(atapci,pci,ata_pci_driver,ata_pci_devclass,0,0);
struct driver_module_data and struct sysinit
-------------------------------------------------------------------------- DRIVER_MODULE(if_fxp, pci, fxp_driver, fxp_devclass, 0, 0); -> static driver_t *if_fxp_pci_driver_list[] = { &fxp_driver }; static struct driver_module_data if_fxp_pci_driver_mod = { 0, 0, "pci", if_fxp_pci_driver_list, (sizeof if_fxp_pci_driver_list) / (sizeof if_fxp_pci_driver_list[0]), &fxp_devclass }; static moduledata_t if_fxp_pci_mod = { "pci/if_fxp", driver_module_handler, &if_fxp_pci_driver_mod }; DECLARE_MODULE(if_fxp_pci, if_fxp_pci_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE) -> SYSINIT(if_fxp_pcimodule, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, module_register_init, &if_fxp_pci_mod) -> struct sysinit if_fxp_pcimodule_sys_init { SI_SUB_DRIVERS, SI_ORDER_MIDDLE, module_register_init, &if_fxp_pci_mod }; -> in init_main.c: module_register_init( &if_fxp_pci_mod); /-------------------------------------------------------------------------- So the answer is that it calls the function "module_register_init" with the address of the moduledata_t structure whose contents are: -------------------------------------------------------------------------- static moduledata_t if_fxp_pci_mod = { "pci/if_fxp", driver_module_handler, &{ 0, 0, "pci", if_fxp_pci_driver_list, 1, &fxp_devclass } }; /-------------------------------------------------------------------------- | If the 'fxp' device is exist, the kernel will try to attach | it(fxp_attach), right? This *eventually* calls the probe, and, if it finds a device, the attach, so yes, many function calls deep. | Another, If we do not compile the 'vr' device into the kernel | and we do not load the corresponding 'ko', so the kernel will | not check the device, that is to say, the 'vr' device does not | registe to kernel, right? Yes. Unless the .ko (kernel module) version gets loaded, a driver must be statically linked into the kernel, or it will not be called to try and probe for devices that it matches. | 1. When the kernel process the specified device, the 'func' | means what? For example: the member 'if_ioctl' of the | structure 'ifnet', when the kernel process the 'fxp' device, | I know it should call the function 'fxp_ioctl'. But I do not | the 'func' means what when it check SI_SUB_DRIVERS. In this case, the macros make it mean the function named module_register_init(). | 2. In NetBSD, I can find main() function in init_main.c, but | in FreeBSD, I could not find it, I am puzzled about the place | of the FreeBSD main process. This is not well documented, and it has changed recently, as people have gained an understanding for the boot process, and screwed around with the code there, so any documentation is out of date pretty quickly. That's the problem with documenting things: there is so little documentation that as soon as something is documented, people understand it and jump on it and change it because they now understand it. Unfortunately people can't seem to leave working code alone, expecially if it's the only code they understand (understanding broken code would be too much like work, I guess...). The short answer is: mi_startup(). The longer answer is: bootstrap code (boot0, boot1+boot2) -- this is the entry point from the BIOS btext() (in locore.s; called locorestart() on Alpha) -- this is the entry point from the bootstrap identify_cpu() create_pagetables() begin() (in relocated address space) mi_startup() -- this is the entrypoint to the machine independent startup code that will be the same no matter what type of machine you run FreeBSD on.
nexus
DRIVER_MODULE(cgem, simplebus, cgem_driver, cgem_devclass, NULL, NULL);
DRIVER_MODULE(cgem, nexus, cgem_driver, cgem_devclass, NULL, NULL);
DRIVER_MODULE(miibus, cgem, miibus_driver, miibus_devclass, NULL, NULL);
static struct driver_module_data name##_##busname##_driver_mod = { \ evh, arg, \ #busname, \ (kobj_class_t) &driver, \ &devclass, \ pass \ }; \ \ static moduledata_t name##_##busname##_mod = { \ #busname "/" #name, \ driver_module_handler, \ &name##_##busname##_driver_mod \ }; \ DECLARE_MODULE(name##_##busname, name##_##busname##_mod, \ SI_SUB_DRIVERS, order)