summaryrefslogblamecommitdiff
path: root/nuttx/Documentation/NuttXNxFlat.html
blob: 289c8a35c16e5afdc96a39bc457f6b49f326cddc (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549




































































































































































































































































































































































































































































































































































                                                                                                                                 
<html>
<head>
<title>NXFLAT</title>
</head>
<body background="backgd.gif">

<hr><hr>
<table width ="100%">
  <tr align="center" bgcolor="#e4e4e4">
    <td>
      <h1><big><font color="#3c34ec"><i>NXFLAT</i></font></big></h1>
      <h2><font color="#dc143c">&gt;&gt;&gt; Under Construction &lt;&lt;&lt;</font></h2>
      <p>Last Updated: June 26, 2009</p>
    </td>
  </tr>
</table>
<hr><hr>
<table width ="100%">
  <tr bgcolor="#e4e4e4">
    <td>
  <h1>Table of Contents</h1>
    </td>
  </tr>
</table>

<center><table width ="80%">
<tr>
<td>
<table>
<tr>
  <td valign="top" width="22"><img height="20" width="20" src="favicon.ico"></td>
  <td>
    <a href="#overview">1.0 Overview</a>
  </td>
</tr>
<tr>
  <td><br></td>
  <td>
    <a href="#functionality">1.1 Functionality</a>
  </td>
</tr>
<tr>
  <td><br></td>
  <td>
    <a href="#background">1.2 Background</a>
  </td>
</tr>
<tr>
  <td><br></td>
  <td>
    <a href="#limitations">1.3 Limitations</a>
  </td>
</tr>
<tr>
  <td><br></td>
  <td>
    <a href="#supported">1.4 Supported Processors</a>
  </td>
</tr>
<tr>
  <td><br></td>
  <td>
    <a href="#status">1.5 Development Status</a>
  </td>
</tr>
<tr>
  <td valign="top" width="22"><img height="20" width="20" src="favicon.ico"></td>
  <td>
    <a href="#toolchain">2.0 NXFLAT Toolchain</a>
  </td>
</tr>
<tr>
  <td><br></td>
  <td>
    <a href="#building">1.2 Building the NXFLAT Toolchain</a>
  </td>
</tr>
<tr>
  <td><br></td>
  <td>
    <a href="#mknxflat">1.2 mknxflat</a>
  </td>
</tr>
<tr>
  <td><br></td>
  <td>
    <a href="#ldnxflat">1.3 ldnxflat</a>
  </td>
</tr>
<tr>
  <td><br></td>
  <td>
    <a href="#making">1.4 Making an NXFLAT module</a>
  </td>
</tr>
<tr>
  <td valign="top" width="22"><img height="20" width="20" src="favicon.ico"></td>
  <td>
    <a href="#nogot">Appendix A.  No GOT Operation</a>
  </td>
</tr>
<tr>
  <td valign="top" width="22"><img height="20" width="20" src="favicon.ico"></td>
  <td>
    <a href="#pictext">Appendix B.  PIC Text Workaround</a>
  </td>
</tr>
</table>
</td>
</tr>
</table></center>

<table width ="100%">
  <tr bgcolor="#e4e4e4">
  <td>
    <a name="overview"><h1>1.0 Overview</h1></a>
  </td>
  </tr>
</table>f

<a name="functionality"><h2>1.1 Functionality</h2></a>

<p>
  NXFLAT is a customized and simplified version of binary format implemented a few years ago called
  <a HREF="http://xflat.sourceforge.net/">XFLAT</A>
  With the NXFLAT binary format you will be able to do the following:
</p>
<ul>
  <li>Place separately linked programs in a file system, and</li>
  <li>Execute those programs by dynamically linking them to the base NuttX code.</li>
</ul>
<p>
  This allows you to extend the NuttX base code after it has been written into FLASH.
  One motivation for implementing NXFLAT is support clean CGI under an HTTPD server.
</p>
<p>
  This feature is especially attractive when combined with the NuttX ROMFS support:
  ROMFS allows you to execute programs in place (XIP) in flash without copying anything
  other than the .data section to RAM.
  In fact, the initial NXFLAT release will work only on ROMFS.
</p>
<p>
  This NuttX feature includes:
</p>
<ul>
  <li>
    A dynamic loader that is built into the NuttX core
   (See <a href="http://nuttx.cvs.sourceforge.net/viewvc/nuttx/nuttx/binfmt/">CVS</a>).
  </li>
  <li>
    Minor changes to RTOS to support position independent code, and
  </li>
  <li>
    A linker to bind ELF binaries to produce the NXFLAT binary format
    (See <a href="http://nuttx.cvs.sourceforge.net/viewvc/nuttx/misc/buildroot/toolchain/nxflat">CVS).
  </li>
</ul>

<a name="background"><h2>1.2 Background</h2></a>

<p>
  NXFLAT is derived from <a href="http://xflat.sourceforge.net/">XFLAT</a>.
  XFLAT is a toolchain add that provides full shared library and XIP executable
  support for processors that have no Memory Management Unit (MMU).
  NXFLAT is greatly simplified for the deeply embedded environment targeted by Nuttx:
</p>
<ul>
  <li>NXFLAT does not support shared libraries, because</li>
  <li>NXFLAT does not support <i>exportation</i> of symbol values from a module</li>
</ul>
<p>
  Rather, the NXFLAT module only <i>imports</i> symbol values.
  In the NXFLAT model, the (PIC<sup>1</sup>) NXFLAT module resides in a FLASH file system and
  when it is loaded at run time, it is dynamically linked only to the (non-PIC) base NuttX
  code:
  The base NuttX <i>exports</i> a symbol table; the NXFLAT module <i>imports</i> those symbol value
  to dynamically bind the module to the base code.
</p>
<p><sup>1</sup><small>&quot;Position Independent Code&quot;</small></p>

<a name="limitations"><h2>1.3 Limitations</h2></a>

<ul>
  <li><b>ROMFS Only</b>.
    The initial NXFLAT release will work only with executable modules residing on a ROMFS
    file system.
    That is because the loader depends on the capability to <code>mmap()</code> the code segment.
    NUTTX does not provide any general kind of file mapping capability.
    In fact, <i>true </i>file mapping is only possible with RTOSs and MCUs that provide an MMU<sup>1</sup>
    and only ROMFS supports that kind of XIP execution from FLASH.
    It is possible to simulate file mapping by allocating memory and copy the file into memory.
    NXFLAT would work that kind of file mapping to and that feature could easily be added to NuttX.
  </li>
  <li><b>GCC/ARM/Cortex-M3 Only</b>
    At present, the NXFLAT toolchain is only available for ARM and Cortex-M3 (thumb2) targets.
  </li>
  <li><b>Read-Only Data in RAM</b>
    Read-only data must reside in RAM.  
    In code generated by GCC, all data references are indexed by the PIC<sup>2</sup> base register
    (that is usually R10 or <i>sl</i> for the ARM processors).
    The includes read-only data (<code>.rodata</code>).
    Embedded firmware developers normally like to keep <code>.rodata</code> in FLASH with the code sections.
    But because all data is referenced with the PIC base register, all of that data must lie in RAM.
    A NXFLAT change to work around this is under investigation<sup>3</sup>.
  </li>
  <li><b>Globally Scoped Function Function Pointers</b>
    If a function pointer is taken to a statically defined function, then (at least for ARM) GCC will
    generate a relocation that NXFLAT cannot handle.
    The workaround is make all such functions global in scope.
    A fix would involve a change to the GCC compiler as described in <a href="#pictext">Appendix B</a>.
  </li>
  <li><b>No Callbacks</b>
    Callbacks through function pointers must be avoided or, when then cannot be avoided, handled very specially.
    The reason for this is that the PIC module requires setting of a special value in a PIC register.
    If the callback does not set the PIC register, then the called back function will fail because
    it will be unable to correct access data memory.
    Special logic is in place to handle: Signal callbacks, watchdog timer callbacks.
    But other callbacks (like those used with <code>qsort()</code> must be avoided in an NXFLAT module.
  </li>
</ul>

<ul><p>
  <sup>1</sup><small>&quot;Memory Management Unit&quot;</small><br>
  <sup>2</sup><small>&quot;Position Independent Code&quot;</small><br>
  <sup>3</sup><small>A work around is under consideration:
    At run time, the <code>.rodata</code> offsets will be indexed by a RAM address.
    If the dynamic loader were to offset those <code>.rodata</code> offsets properly, it
    still might be possible to reference <code>.rodata</code> in ROM.
    That work around is still a top of investigation at this time.</small>
</p></ul>

<a name="supported"><h2>1.4 Supported Processors</h2></a>

<p>
  As mentioned <a href="#limitations">above</a>, the NXFLAT toolchain is only available for ARM and
  Cortex-M3 (thumb2) targets.
  Furthermore, NXFLAT has only been tested on the Eagle-100 LMS6918 Cortex-M3 board.
</p>

<a name="status"><h2>1.5 Development Status</h2></a>

<p>
  The initial release of NXFLAT was made in NuttX version 0.4.9.
  Testing is limited to the tests found under <code>examples/nxflat</code> in the source tree.
  Some known problems exist
  (see the <a href="http://nuttx.cvs.sourceforge.net/*checkout*/nuttx/nuttx/TODO">TODO</a> list).
  As such, NXFLAT is currently in an early alpha phase.
</p>

<table width ="100%">
  <tr bgcolor="#e4e4e4">
  <td>
    <a name="toolchain"><h1>2.0 NXFLAT Toolchain</h1></a>
  </td>
  </tr>
</table>

<a name="building"><h2>1.2 Building the NXFLAT Toolchain</h2></a>

<p>
  In order to use NXFLAT, you must use special NXFLAT tools to create the binary module in FLASH.
  To do this, you will need to download the buildroot package and build it on your Linux or Cygwin machine.
  The buildroot can be downloaded from 
  <a https://sourceforge.net/project/showfiles.php?group_id=189573&package_id=224585">Sourceforge</a>.
  You will need version 0.1.7 or later.
</p>
<p>
  Here are some general build instructions:
</p>
<ul>

  <li>
    You must have already configured Nuttx in <code>&lt;some-dir&gt;/nuttx</code>
  <li>
  <li>
    Download the buildroot package <code>buildroot-0.x.y</code> into <code>&lt;some-dir&gt;</code>
  <li>
  <li>
    Unpack <code>&lt;some-dir&gt;/buildroot-0.x.y.tar.gz</code> using a command like <code>tar zxf buildroot-0.x.y</code>.
    This will result in a new directory like <code>&lt;some-dir&gt;/misc/buildroot-0.x.y</code>
  </li>
  <li>
    Move this into position: <code>mv &lt;some-dir&gt;/misc/buildroot-0.x.y <code>&lt;some-dir&gt;/buildroot</code>
  </li>
  <li>
    <code>cd <code>&lt;some-dir&gt;/buildroot</code>
  </li>
  <li>
    Copy a configuration file into the top buildroot directory: <code>cp configs/abc-defconfig-x.y.z .config</code>.
  </li>
  <li>
    Enable building of the NXFLAT tools by <code>make menuconfig</code>.
    Select to build the NXFLAT toolchain with GCC (you can also select omit building GCC with and only build the
    NXFLAT toolchain for use with your own GCC toolchain).
  </li>
  <li>
    Make the toolchain: <code>make</code>.
    When the make completes, the tool binaries will be available under
    <code>&lt;some-dir&gt;/buildroot/build_abc/staging_dir/bin</code>
  </li>
</ul>

<a name="mknxflat"><h2>1.2 mknxflat</h2></a>

<p>
  <code>mknxflat</code> is used to build a <i>thunk</i> file.
  See <a href="#making">below</a> for usage.

<ul><pre>
Usage: mknxflat [options] &lt;bfd-filename&gt;

Where options are one or more of the following.  Note
that a space is always required between the option and
any following arguments.

  -d Use dynamic symbol table. [symtab]
  -f &lt;cmd-filename&gt;
      Take next commands from &lt;cmd-filename&gt; [cmd-line]
  -o &lt;out-filename&gt;
     Output to <out-filename> [stdout]
  -v Verbose output [no output]
  -w Import weakly declared functions, i.e., weakly
     declared functions are expected to be provided at
     load-time [not imported]
</pre></ul>

<a name="ldnxflat"><h2>1.3 ldnxflat</h2></a>

<p>
  <code>ldnxflat</code> is use to link your object files along with the <i>thunk</i> file
  generated by <a href="#mknxflat"><code>mknxflat<code></a> to produce the NXFLAT binary module.
  See <a href="#making">below</a> for usage.
</p>

<ul><pre>
Usage: ldnxflat [options] &lt;bfd-filename&gt;

Where options are one or more of the following.  Note
that a space is always required between the option and
any following arguments.

  -d Use dynamic symbol table [Default: symtab]
  -e &lt;entry-point&gt;
     Entry point to module [Default: _start]
  -o &lt;out-filename&gt;
     Output to &lt;out-filename&gt; [Default: &lt;bfd-filename&gt;.nxf]
  -s &lt;stack-size&gt;
     Set stack size to &lt;stack-size&gt; [Default: 4096]
  -v Verbose output. If -v is applied twice, additional
     debug output is enabled [Default: no verbose output].
</pre></ul>

<a name="making"><h2>1.4 Making an NXFLAT module</h2></a>

<p>
  Below is a snippet from an NXFLAT make file (simplified from NuttX
  <a href="http://nuttx.cvs.sourceforge.net/viewvc/*checkout*/nuttx/nuttx/examples/nxflat/tests/hello/Makefile?revision=1.6">
  Hello, World!</a> example.
<p>
<ul><table width="50%">

<ul><table>
  <tr>
    <th>Target 1</th>
    <td><code>hello.r1:</code></td>
    <td><code>hello.o</code></td>
  </tr>
  <tr>
    <td><br></td>
    <td><br></td>
    <td><code>abc-elf-ld -r -d -warn-common -o $@ $^</code></td>
  </tr>
  <tr>
    <th>Target 2</th>
    <td><code>hello-thunk.S:</code></td>
    <td><code>hello.r1</code></td>
  </tr>
  <tr>
    <td><br></td>
    <td><br></td>
    <td><code>mknxflat -o $@ $^</code></td>
  </tr>
  <tr>
    <th>Target 3</th>
    <td><code>hello.r2:</code></td>
    <td><code>hello-thunk.S</code></td>
  </tr>
  <tr>
    <td><br></td>
    <td><br></td>
    <td>
      <code>abc-elf-ld -r -d -warn-common -T binfmt/libnxflat/gnu-nxflat.ld -no-check-sections -o $@ hello.o hello-thunk.o</code>
    </td>
  </tr>
  <tr>
    <th>Target 4</th>
    <td><code>hello:</code></td>
    <td><code>hello.r2</code></td>
  </tr>
  <tr>
    <td><br></td>
    <td><br></td>
    <td><code>ldnxflat -e main -s 2048 -o $@ $^</code></td>
  </tr>
  <tr>
</table></ul>

<p><b>Target 1</b>.
  This target links all of the object files together into one relocation object.
  In this case, there is only a single object file, <code>hello.o</code>, and it is linked to produce <code>hello.r1</code>.
</p>

<p><b>Target 2</b>.
  Given <code>hello.r1</code>, this target will invoke <a href="#mknxflat"><code>mknxflat</code></a>
  to make the <i>thunk</i> file, <code>hello-thunk.S</code>.
  This <i>thunk</i> contains all of the information needed to create the imported function list.
</p>

<p><b>Target 3</b>
  This this target is similar to <b>Target 1</b>.
  In this case, it will link together the object file, <code>hello.o</code> along with the assembled <i>thunk</i> file,
  <code>hello-thunk.o</code> to create another, single relocatable object, <code>hello.r2</code>.
  The linker script, <code>gnu-nxflat.ld</code> is required at this point to correctly position the sections.
</p>

<p><b>Target 4</b>.
  Finally, this target will use the <code>hello.r2</code> relocatable object to create the final, NXFLAT module
  <code>hello</code> by calling <a href="#ldnxflat"><code>ldnxflat</code></a>.
</p>

<table width ="100%">
  <tr bgcolor="#e4e4e4">
  <td>
    <a name="nogot"><h1>Appendix A.  No GOT Operation</h1></a>
  </td>
  </tr>
</table>

<p>
  When GCC generate position independent code, new code sections will appear in your programs.
  One of these the the GOT (Global Offset Table) and, in ELF environments, the PLT (Procedure
  Lookup Table.
  For example, if your C code generated (ARM) assembly language like this without PIC:
<p>
<ul><pre>
        ldr     r1, .L0         <-- Fetch the offset to 'x'
        ldr     r0, [r10, r1]   <-- Load the value of 'x' with PIC
                                offset
        ...
.L0:    .word   x               <-- Offset to 'x'
</pre></ul>

<p>
  Then when PIC is enabled (say with the -fpic compiler option), it will generate code like
  this:
</p>

<ul><pre>
        ldr     r1, .L0         <-- Fetch the offset to the GOT entry
        ldr     r1, [r10,r1]    <-- Fetch the (relocated) address
                                of 'x' from the GOT
        ldr     r0, [r1, #0]    <-- Fetch the value of 'x'
        ...
.L1     .word   x(GOT)          <-- Offset to entry in the GOT
</pre></ul>

<p>See <a href="http://xflat.sourceforge.net/NoMMUSharedLibs.html#shlibsgot">reference</a></p>

<p>
  Notice that the generates an extra level of indirection through the GOT.
  This indirection is not needed by NXFLAT and only adds more RAM usage and
  execution time.
</p>
<p>
  NXFLAT (like <a href="http://xflat.sourceforge.net/">XFLAT</a>) can work even better with
  the GOT.
  Patches again older version of GCC exist to eliminate the GOT indirections.
  Several are available <a href="http://xflat.cvs.sourceforge.net/viewvc/xflat/xflat/gcc/">here</a>
  if you are inspired to port them to a new GCC version.
</p>


<table width ="100%">
  <tr bgcolor="#e4e4e4">
  <td>
    <a name="pictext"><h1>Appendix B.  PIC Text Workaround</h1></a>
  </td>
  </tr>
</table>

<p>
  There is a problem with the memory model in GCC that prevents it from
  being used as you need to use it in the NXFLAT context.
  The problem is that GCC PIC model assumes that the executable lies in a flat, contiguous (virtual) address space like:
<p>
<ul><table width="15%">
  <tr><th>Virtual</th></td>
  <tr>
    <td align="center" bgcolor="#e4e4e4"><code>.text</code></td>
  </tr>
  <tr>
    <td align="center" bgcolor="#e4e4e4"><code>.got</code></td>
  </tr>
  <tr>
    <td align="center" bgcolor="#e4e4e4"><code>.data</code></td>
  </tr>
  <tr>
    <td align="center" bgcolor="#e4e4e4"><code>.bss</code></td>
  </tr>
</table></ul>
<p>
  It assumes that the PIC base register (usually r10 for ARM) points to the base of <code>.text</code>
  so that any address in <code>.text</code>, <code>.got</code>, <code>.data</code>, <code>.bss</code>
  can be found with an offset from the same base address.
  But that is not the memory arrangement that we need in the XIP embedded environment.
  We need two memory regions, one in FLASH containing shared code and on per task in RAM containing task-specific data:
</p>

<ul><table width="30%">
  <tr><th>Flash</th><th>RAM</th></td>
  <tr>
    <td align="center" bgcolor="#e4e4e4"><code>.text</code></td>
    <td align="center" bgcolor="#e4e4e4"><code>.got</code></td>
  </tr>
  <tr>
    <td bgcolor="#e4e4e4"><br></td>
    <td align="center" bgcolor="#e4e4e4"><code>.data</code></td>
  </tr>
  <tr>
    <td bgcolor="#e4e4e4"><br></td>
    <td align="center" bgcolor="#e4e4e4"><code>.bss</code></td>
  </tr>
</table></ul>

<p>
  The PIC base register needs to point to the base of the <code>.got</code> and only
  addresses in the <code>.got</code>, <code>.data</code>, and <code>.bss</code>
  sections can be accessed as an offset from the PIC base register.
  See also this 
  <a href="http://xflat.cvs.sourceforge.net/viewvc/*checkout*/xflat/xflat/gcc/README?revision=1.1.1.1">XFLAT discussion</a>.
</p>
<p>
  Patches again older version of GCC exist to correct this GCC behavior.
  Several are available <a href="http://xflat.cvs.sourceforge.net/viewvc/xflat/xflat/gcc/">here</a>
  if you are inspired to port them to a new GCC version.
</p>

</body>
</html>