source: rtems-libbsd/libbsd.txt @ 362782e

4.115-freebsd-12freebsd-9.3
Last change on this file since 362782e was 362782e, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 16, 2012 at 10:43:49 AM

Explain why we need the interrupt server

  • Property mode set to 100644
File size: 15.9 KB
Line 
1RTEMS BSD USB and TCP/IP Developers Guide
2=========================================
3Joel Sherrill <joel.sherrill@oarcorp.com>
4:Author Initials: JRS
5:toc:
6:icons:
7:numbered:
8:website: http://www.rtems.org/
9
10RTEMS uses FreeBSD as the source of its TCP/IP and USB stacks.
11This is a developers guide which captures information on the
12process of merging code from FreeBSD, building this library,
13RTEMS specific support files, and general guidelines on what
14modifications to the FreeBSD source are permitted.
15
16Goals of this effort are:
17
18* Update TCP/IP and provide USB in RTEMS
19* Ease updating to future FreeBSD versions
20* Ease tracking changes in FreeBSD code
21* Minimize manual changes in FreeBSD code
22* Define stable kernel/device driver API which is implemented
23by both RTEMS and FreeBSD. This is the foundation of the port.
24
25We will work to push our changes upstream to the FreeBSD Project
26and minimize changes required at each update point.
27
28**************************************************************
29This is a work in progress and is very likely to be incomplete.
30Please help by adding to it.
31**************************************************************
32
33== Source Code Version Information
34
35* FreeBSD 8.2 SVN r222496
36* RTEMS 4.11
37  - BSP must have support for all new BSD sys sections
38  - It is preferable if the BSP uses linkcmds.base.
39  - BSP must be from an architecture with Programmable Interrupt Controller
40    interrupt model.
41
42The FreeBSD 8.2 SVN checkout will generally be referred to as the
43FreeBSD source in this document. An archive of the FreeBSD 8.2 SVN
44archive used is located at
45  http://www.rtems.org/ftp/pub/rtems/people/joel/freebsd/
46The SVN checkout command is this
47  svn co http://svn.freebsd.org/base/releng/8.2/sys/ -r222496 freebsd-8.2
48
49== Issues and To Do
50* Sebastian Huber: mentioned some simple test code which would verify
51  that the BSD code/and or USB stack was initialized.  This has been
52  sent to Joel Sherrill and is pending merger.
53
54* Sebastian Huber and Joel Sherrill discussed the need for a a basic USB
55  functionality test that is known to work on qemu pc.
56
57* Adapt generic IRQ PIC interface code to Simple Vectored Interrupt Model
58  so that those architectures can use new TCP/IP and USB code.
59
60* in_cksum implementations for architectures not supported by FreeBSD.
61  This will require figuring out where to put implementations that do
62  not originate from FreeBSD and are populated via the script.
63
64* FreeBSD generic in_cksum implementation is missing in_cksum_split so
65  currently cannot be used.
66
67* How does one initialize the TCP/IP stack?
68
69* linker section issues: I have undefined symbols for
70  `_bsd__start_set_sysinit_set` and `_bsd__stop_set_sysinit_set`.
71  Is this the only type of new section magic?  What about the old sysctl_set?
72  I added this to my linkcmds. 
73
74[listing]
75----
76    /* sysinit section? */
77    . = ALIGN (16);
78    _bsd__start_set_sysinit_set = .;
79    *(set_sys_init_*);
80    _bsd__stop_set_sysinit_set = .;
81
82----
83
84* Why is the interrupt server used?  The BSD interrupt handlers can block on
85synchronization primitives like mutexes.  This is in contrast to RTEMS
86interrupt service routines.  The BSPs using the generic interrupt support must
87implement the `bsp_interrupt_vector_enable()` and
88`bsp_interrupt_vector_disable()` routines.  They normally enable/disable a
89particular interrupt source at the interrupt controller.  This can be used to
90implement the interrupt server.  The interrupt server is a task that wakes-up
91in case an associated interrupt happens.  The interrupt source is disabled in
92a generic interrupt handler that wakes-up the interrupt server task.   Once the
93postponed interrupt processing is performed in the interrupt server the
94interrupt source is enabled again.
95
96* Convert all BSP linkcmds to use a linkcmds.base so the sections are
97easier to insert.
98
99* rtems-bsd-init-with-irq.c:
100  rtems_bsd_initialize_with_interrupt_server() has reference to
101    rtems_interrupt_server_initialize() and this method is unimplemented
102    - XXX BSP implements pieces
103    - BSPs using this software stack must support it apparently.
104    - What about Simple Vectored architectures?
105
106* maxproc variable referenced by rtems-bsd-resource.c.  What should it
107be set to?
108
109* ngroups_max variable referenced by rtems-bsd-prot.c.  - What should
110it be set to?
111
112* NIC Device Drivers
113- Only common NIC drivers have been included in the initial set. These do not
114include any system on chip or ISA drivers.
115- The ISA drivers require more BSD infrastructure to be addressed. This was
116outside the scope of the initial porting effort.
117
118== FreeBSD Source
119
120You should be able to rely on FreebSD manual pages and documentation
121for details on the code itself.
122
123=== Automatically Generated FreeBSD Files
124
125The FreeBSD source tarball includes a file named Makefile.rtems which
126has stanzas to automatically generate some files using awk. For details
127on this, see http://www.freebsd.org/cgi/man.cgi?query=kobj&apropos=0&sektion=0&manpath=FreeBSD+9.0-RELEASE&arch=default&format=html
128
129XXX This needs more detail.
130
131=== Rules for Modifying FreeBSD Source
132
133* Only add lines.  Subtract code by added "ifndef __rtems__". This makes
134merging easier in the future.
135
136== libbsd Source
137
138=== What is in git
139
140The git source is a self-contained kit with FreeBSD and RTEMS components
141pre-merged. The Makefile in this kit is automatically generated.
142
143Any changes to sources in the freebsd or contrib directories will need to
144be merged upstream into our master FreeBSD svn checkout.
145
146The FreeBSD sources managed in RTEMS libbsd git repository (e.g. contrib
147and freebsd directories) contain the "managed" version of the
148FreeBSD source.  The FreeBSD SVN source is the "master" version. The
149freebsd-to-rtems.py script is used to transfer files between the two
150trees. In general terms, if you have modified FreeBSD in the RTEMS libbsd
151tree, you want to run the script in "revert" or "reverse" mode to move
152the source back so you can run an "svn diff" against the upstream FreeBSD
153source. If you want to transfer source from the FreeBSD SVN checkout to
154the RTEMS libbsd tree, then you want to run the script in "forward" or
155default mode.
156
157=== Building RTEMS libbsd source
158
159You need to configure RTEMS for the desired BSP and install it. The
160following is the script used to build the powerpc/psim BSP for our
161internal testing purposes:
162
163[listing]
164----
165#! /bin/sh
166
167cd ${HOME}/newbsd
168rm -rf b-psim
169mkdir b-psim
170cd b-psim
171../git/rtems/configure --target=powerpc-rtems4.11 \
172  --enable-rtemsbsp=psim --disable-networking \
173  --enable-tests=samples \
174  --prefix=${HOME}/newbsd/bsp-install >c.log 2>&1 && \
175  make >b.log 2>&1 && \
176  make install >i.log 2>&1
177echo $?
178----
179
180Then edit the file config.inc to set RTEMS_MAKEFILE_PATH appropriately
181to indicate the ${prefix}/${target}/${BSP}.  Continuing on the above,
182the config.inc used to match the above is:
183
184[listing]
185----
186RTEMS_MAKEFILE_PATH = ${HOME}/newbsd/bsp-install/powerpc-rtems4.11/psim/
187INSTALL_BASE = ${HOME}/newbsd/install
188----
189
190The above installs the RTEMS libbsd kit into a separate place from
191RTEMS and the BSP. The RTEMS libbsd tests are built against an installed
192image of the RTEMS libbsd. By keeping it in a separate installation point
193from RTEMS itself, this makes it easier to remove a libbsd installation
194and have a clean test point.
195
196[listing]
197----
198make
199make install
200make -C testsuite
201----
202
203At this point, we expect multiple linker errors. That is what we are
204currently working on.
205
206=== Organization
207
208The top level directory contains a few directories and files. The following
209are important to understand:
210
211* freebsd-to-rtems.py - script to convert to and free FreeBSD and RTEMS trees
212* Makefile - automatically generated
213* contrib/ - from FreeBSD by script.
214* freebsd/ - from FreeBSD by script.
215* rtemsbsd/ - RTEMS specific implementations of FreeBSD kernel support routines.
216* testsuite/ - RTEMS specific tests
217* libbsd.txt - Documentation in Asciidoc
218
219== Moving Code Between FreeBSD SVN and RTEMS libbsd
220
221The script freebsd-to-rtems.py is used to copy code from FreeBSD to the
222RTEMS libbsd tree and to reverse this process. This script attempts to
223automate this process as much as possible and performs some transformations
224on the FreeBSD code. Its command line arguments are shown below:
225
226[listing]
227----
228freebsd-to-rtems.py [args]
229  -?|-h|--help     print this and exit
230  -d|--dry-run     run program but no modifications
231  -D|--diff        provide diff of files between trees
232  -e|--early-exit  evaluate arguments, print results, and exit
233  -m|--makefile    just generate Makefile
234  -R|--reverse     default FreeBSD -> RTEMS, reverse that
235  -r|--rtems       RTEMS directory
236  -f|--freebsd     FreeBSD directory
237  -v|--verbose     enable verbose output mode
238----
239
240In its default mode of operation, freebsd-to-rtems.py is used to copy code
241from FreeBSD to the RTEMS libbsd tree and perform transformations.  In forward
242mode, the script may be requested to just generate the Makefile.
243
244In "reverse mode", this script undoes those transformations and copies
245the source code back to the FreeBSD SVN tree. This allows us to do
246'svn diff', evaluate changes made by the RTEMS Project, and report changes
247back to FreeBSD upstream.
248
249In either mode, the script may be asked to perform a dry-run or be verbose.
250Also, in either mode, the script is also smart enough to avoid copying over
251files which have not changed. This means that the timestamps of files are
252not changed unless the contents change. The script will also report the
253number of files which changed. In verbose mode, the script will print
254the name of the files which are changed.
255
256The following is an example forward run with no changes.
257
258[listing]
259----
260$ ~/newbsd/git/libbsd-8.2/freebsd-to-rtems.py \
261    -r /home/joel/newbsd/git/libbsd-8.2 \
262    -f /home/joel/newbsd/libbsd/freebsd-8.2 -v
263Verbose:                yes
264Dry Run:                no
265Only Generate Makefile: no
266RTEMS Directory:        /home/joel/newbsd/git/libbsd-8.2
267FreeBSD Directory:      /home/joel/newbsd/libbsd/freebsd-8.2
268Direction:              forward
269Generating into /home/joel/newbsd/git/libbsd-8.2
2700 files were changed.
271----
272
273The script may also be used to generate a diff in either forward or reverse
274direction.
275
276== Initialization of RTEMS libbsd
277
278The initialization of the RTEMS libbsd is based on the FreeBSD SYSINIT(9)
279infrastructure.  The key to initializing a system is to ensure that the desired
280device drivers are explicitly pulled into the linked application.  This plus
281linking against the libbsd library will pull in the necessary FreeBSD
282infrastructure.
283
284The FreeBSD kernel is not a library like the RTEMS kernel.  It is a bunch of
285object files linked together.  If we have a library, then creating the
286executable is simple.  We begin with a start symbol and recursively resolve all
287references.  With a bunch of object files linked together we need a different
288mechanism.  Most object files don't know each other.  Lets say we have a driver
289module.  The rest of the system has no references to this driver module.  The
290driver module needs a way to tell the rest of the system: Hey, kernel I am
291here, please use my services!
292
293This registration of independent components is performed by SYSINIT(9) and
294specializations:
295
296http://www.freebsd.org/cgi/man.cgi?query=SYSINIT
297
298The SYSINIT(9) uses some global data structures that are placed in a certain
299section.  In the linker command file we need this:
300
301[listing]
302----
303.robsdsets : {
304    _bsd__start_set_modmetadata_set = .;
305    *(_bsd_set_modmetadata_set);
306    _bsd__stop_set_modmetadata_set = .;
307    _bsd__start_set_sysctl_set = .;
308    *(_bsd_set_sysctl_set);
309    _bsd__stop_set_sysctl_set = .;
310} > REGION_RODATA AT > REGION_RODATA_LOAD
311
312.rwbsdsets : {
313    _bsd__start_set_sysinit_set = .;
314    *(_bsd_set_sysinit_set);
315    _bsd__stop_set_sysinit_set = .;
316} > REGION_DATA AT > REGION_DATA_LOAD
317----
318
319Here you can see, that these global data structures are collected into
320continuous memory areas.  This memory area can be identified by start and stop
321symbols.  This constructs a table of uniform items.
322
323The low level FreeBSD code calls at some time during the initialization the
324mi_startup() function (machine independent startup).  This function will sort
325the SYSINIT(9) set and call handler functions which perform further
326initialization.  The last step is the scheduler invocation.
327
328The SYSINIT(9) routines are run in mi_startup() which is called by
329rtems_bsd_initialize().
330
331This is also explained in "The Design and Implementation of the FreeBSD
332Operating System" section 14.3 "Kernel Initialization".
333
334In RTEMS we have a library and not a bunch of object files.  Thus we need a way
335to pull-in the desired services out of the libbsd.  Here the
336"rtems-bsd-sysinit.h" comes into play.  The SYSINIT(9) macros have been
337modified and extended for RTEMS in "sys/kernel.h":
338
339[listing]
340----
341#ifndef __rtems__
342#define    C_SYSINIT(uniquifier, subsystem, order, func, ident) \
343    static struct sysinit uniquifier ## _sys_init = { \
344        subsystem, \
345        order, \
346        func, \
347        (ident) \
348    }; \
349    DATA_SET(sysinit_set,uniquifier ## _sys_init)
350#else /* __rtems__ */
351#define    SYSINIT_ENTRY_NAME(uniquifier) \
352    _bsd_ ## uniquifier ## _sys_init
353#define    SYSINIT_REFERENCE_NAME(uniquifier) \
354    _bsd_ ## uniquifier ## _sys_init_ref
355#define    C_SYSINIT(uniquifier, subsystem, order, func, ident) \
356    struct sysinit SYSINIT_ENTRY_NAME(uniquifier) = { \
357        subsystem, \
358        order, \
359        func, \
360        (ident) \
361    }; \
362    DATA_SET(sysinit_set,SYSINIT_ENTRY_NAME(uniquifier))
363#define    SYSINIT_REFERENCE(uniquifier) \
364    extern struct sysinit SYSINIT_ENTRY_NAME(uniquifier); \
365    static struct sysinit const * const \
366    SYSINIT_REFERENCE_NAME(uniquifier) __used \
367    = &SYSINIT_ENTRY_NAME(uniquifier)
368#define    SYSINIT_MODULE_REFERENCE(mod) \
369    SYSINIT_REFERENCE(mod ## module)
370#define    SYSINIT_DRIVER_REFERENCE(driver, bus) \
371    SYSINIT_MODULE_REFERENCE(driver ## _ ## bus)
372#endif /* __rtems__ */
373----
374
375Here you see that the SYSINIT(9) entries are no longer static.  The
376*_REFERENCE() macros will create references to the corresponding modules which
377are later resolved by the linker.  The application has to provide an object
378file with references to all required FreeBSD modules.
379
380The FreeBSD device model is quite elaborated (with follow-ups):
381
382http://www.freebsd.org/cgi/man.cgi?query=driver
383
384The devices form a tree with the Nexus device at a high-level.  This Nexus
385device is architecture specific in FreeBSD.  In RTEMS we have our own Nexus
386device, see "rtems-bsd-nexus.c".  It uses a table to add child devices:
387
388[listing]
389----
390const char *const _bsd_nexus_devices [] = {
391    #ifdef NEED_USB_OHCI
392        "ohci",
393    #endif
394    #ifdef NEED_USB_EHCI
395        "ehci",
396    #endif
397    #ifdef NEED_SDHC
398        "sdhci",
399    #endif
400    NULL
401};
402----
403
404This table must be provided by the application.
405
406=== SYSCTL_NODE Example
407
408During development, we had an undefined reference to
409_bsd_sysctl__net_children that we had trouble tracking down. Thanks to
410Chris Johns, we located it. He explained how to read SYSCTL_NODE
411definitions. This line from freebsd/netinet/in_proto.c is attempting
412to add the "inet" node to the parent node "_net".
413
414[listing]
415----
416SYSCTL_NODE(_net,      PF_INET,         inet,   CTLFLAG_RW, 0,
417        "Internet Family");
418----
419
420Our problem was that we could not find where _bsd_sysctl__net_children
421was defined. Chris suggested that when in doubt compile with -save-temps
422and look at the preprocessed .i files. But he did not need that. He
423explained that this the symbol name _bsd_sysctl__net_children was
424automatically generated by a SYSCTL_NODE as follows:
425
426* _bsd_ - added by RTEMS modifications to SYSCTL_NODE macro
427* sysctl_ - boilerplace added by SYSCTL_NODE macro
428* "" - empty string for parent node
429* net - name of SYSCTL_NODE
430* children - added by SYSCTL macros
431 
432This was all generated by a support macro declaring the node as this:
433
434[listing]
435----
436struct sysctl_oid_list SYSCTL_NODE_CHILDREN(parent, name);
437----
438
439Given this information, we located this SYSCTL_NODE declaration in
440kern/kern_mib.c
441
442[listing]
443----
444SYSCTL_NODE(, CTL_KERN,   kern,   CTLFLAG_RW, 0,
445        "High kernel, proc, limits &c");
446----
447
Note: See TracBrowser for help on using the repository browser.