| <!-- |
| Documentation/_templates/layout.html |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. The |
| ASF licenses this file to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance with the |
| License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| License for the specific language governing permissions and limitations |
| under the License. |
| --> |
| |
| |
| |
| <!DOCTYPE html> |
| <html class="writer-html5" lang="en"> |
| <head> |
| <meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" /> |
| |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>NuttX Protected Build — NuttX latest documentation</title> |
| <link rel="stylesheet" type="text/css" href="../_static/pygments.css" /> |
| <link rel="stylesheet" type="text/css" href="../_static/css/theme.css" /> |
| <link rel="stylesheet" type="text/css" href="../_static/copybutton.css" /> |
| <link rel="stylesheet" type="text/css" href="../_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css" /> |
| <link rel="stylesheet" type="text/css" href="../_static/custom.css" /> |
| |
| |
| <link rel="shortcut icon" href="../_static/favicon.ico"/> |
| <script src="../_static/jquery.js"></script> |
| <script src="../_static/_sphinx_javascript_frameworks_compat.js"></script> |
| <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script> |
| <script src="../_static/doctools.js"></script> |
| <script src="../_static/sphinx_highlight.js"></script> |
| <script src="../_static/clipboard.min.js"></script> |
| <script src="../_static/copybutton.js"></script> |
| <script src="../_static/design-tabs.js"></script> |
| <script src="../_static/js/theme.js"></script> |
| <link rel="index" title="Index" href="../genindex.html" /> |
| <link rel="search" title="Search" href="../search.html" /> |
| <link rel="next" title="Platform Directories" href="platform_directories.html" /> |
| <link rel="prev" title="Integrating with Newlib" href="integrate_newlib.html" /> |
| </head> |
| |
| <body class="wy-body-for-nav"> |
| <div class="wy-grid-for-nav"> |
| <nav data-toggle="wy-nav-shift" class="wy-nav-side"> |
| <div class="wy-side-scroll"> |
| <div class="wy-side-nav-search" > |
| |
| <a href="../index.html" class="icon icon-home"> NuttX |
| |
| |
| |
| </a> |
| |
| <!-- this version selector is quite ugly, should be probably replaced by something |
| more modern --> |
| |
| <div class="version-selector"> |
| <select onchange="javascript:location.href = this.value;"> |
| |
| <option value="../../latest" selected="selected">latest</option> |
| |
| <option value="../../10.0.0" >10.0.0</option> |
| |
| <option value="../../10.0.1" >10.0.1</option> |
| |
| <option value="../../10.1.0" >10.1.0</option> |
| |
| <option value="../../10.2.0" >10.2.0</option> |
| |
| <option value="../../10.3.0" >10.3.0</option> |
| |
| <option value="../../11.0.0" >11.0.0</option> |
| |
| <option value="../../12.0.0" >12.0.0</option> |
| |
| <option value="../../12.1.0" >12.1.0</option> |
| |
| <option value="../../12.2.0" >12.2.0</option> |
| |
| <option value="../../12.2.1" >12.2.1</option> |
| |
| <option value="../../12.3.0" >12.3.0</option> |
| |
| <option value="../../12.4.0" >12.4.0</option> |
| |
| <option value="../../12.5.0" >12.5.0</option> |
| |
| <option value="../../12.5.1" >12.5.1</option> |
| |
| <option value="../../12.6.0" >12.6.0</option> |
| |
| <option value="../../12.7.0" >12.7.0</option> |
| |
| <option value="../../12.8.0" >12.8.0</option> |
| |
| <option value="../../12.9.0" >12.9.0</option> |
| |
| <option value="../../12.10.0" >12.10.0</option> |
| |
| <option value="../../12.11.0" >12.11.0</option> |
| |
| </select> |
| </div> |
| |
| |
| <div role="search"> |
| <form id="rtd-search-form" class="wy-form" action="../search.html" method="get"> |
| <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> |
| <input type="hidden" name="check_keywords" value="yes" /> |
| <input type="hidden" name="area" value="default" /> |
| </form> |
| </div> |
| |
| </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> |
| <p class="caption" role="heading"><span class="caption-text">Table of Contents</span></p> |
| <ul class="current"> |
| <li class="toctree-l1"><a class="reference internal" href="../index.html">Home</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../introduction/index.html">Introduction</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../quickstart/index.html">Getting Started</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../contributing/index.html">Contributing</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../introduction/inviolables.html">The Inviolable Principles of NuttX</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../platforms/index.html">Supported Platforms</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../components/index.html">OS Components</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../applications/index.html">Applications</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../implementation/index.html">Implementation Details</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../reference/index.html">API Reference</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../debugging/index.html">Debugging</a></li> |
| <li class="toctree-l1 current"><a class="reference internal" href="index.html">Guides</a><ul class="current"> |
| <li class="toctree-l2"><a class="reference internal" href="nfs.html">NFS Client How-To</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="usbtrace.html">USB Device Trace</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="simulator.html">Simulator</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="rndis.html">How to use RNDIS</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="drivers.html">Drivers</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="cpp_cmake.html">C++ Example using CMake</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="pysimcoder.html">pysimCoder integration with NuttX</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="customboards.html">Custom Boards How-To</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="customapps.html">Custom Apps How-to</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="citests.html">Running CI Test Locally</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="zerolatencyinterrupts.html">High Performance: Zero Latency Interrupts, Maskable Nested Interrupts</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="fortify.html">Fortify</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="nestedinterrupts.html">Nested Interrupts</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="ofloader.html">Open Flash Loader</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="testingtcpip.html">Testing TCP/IP Network Stacks</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="automounter.html">Auto-Mounter</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="stm32nullpointer.html">STM32 Null Pointer Detection</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="stm32ccm.html">STM32 CCM Allocator</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="etcromfs.html">etc romfs</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="thread_local_storage.html">Thread Local Storage</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="devicetree.html">Device Tree</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="changing_systemclockconfig.html">Changing the System Clock Configuration</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="usingkernelthreads.html">Using Kernel Threads</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="armv7m_runtimestackcheck.html">ARMv7-M Run Time Stack Checking</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="include_files_board_h.html">Including Files in board.h</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="specialstuff_in_nuttxheaderfiles.html">Why can’t I put my special stuff in NuttX header files?</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="kernel_threads_with_custom_stacks.html">Kernel Threads with Custom Stacks</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="versioning_and_task_names.html">Versioning and Task Names</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="logging_rambuffer.html">Logging to a RAM Buffer</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="ipv6.html">IPv6</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="integrate_newlib.html">Integrating with Newlib</a></li> |
| <li class="toctree-l2 current"><a class="current reference internal" href="#">NuttX Protected Build</a><ul> |
| <li class="toctree-l3"><a class="reference internal" href="#the-traditional-flat-build">The Traditional “Flat” Build</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#the-two-pass-protected-build">The “Two Pass” Protected Build</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#the-memory-protection-unit">The Memory Protection Unit</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#advantages-of-the-protected-build">Advantages of the Protected Build</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#user-space-proxies-kernel-space-stubs">User-Space Proxies/Kernel-Space Stubs</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#combining-intel-hex-files">Combining Intel HEX Files</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#files-and-directories">Files and Directories</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#alignment-regions-and-subregions">Alignment, Regions, and Subregions</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#memory-management">Memory Management</a><ul> |
| <li class="toctree-l4"><a class="reference internal" href="#single-user-heap">Single User Heap</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="#dual-partitioned-heaps">Dual, Partitioned Heaps</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="#the-traditional-approach">The Traditional Approach</a></li> |
| </ul> |
| </li> |
| <li class="toctree-l3"><a class="reference internal" href="#comparing-the-flat-build-configuration-with-the-protected-build-configuration">Comparing the “Flat” Build Configuration with the Protected Build Configuration</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#size-expansion">Size Expansion</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#performance-issues">Performance Issues</a></li> |
| </ul> |
| </li> |
| <li class="toctree-l2"><a class="reference internal" href="platform_directories.html">Platform Directories</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="port_drivers_to_stm32f7.html">Porting Drivers to the STM32 F7</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="semihosting.html">Semihosting</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="renode.html">Run NuttX on Renode</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="signal_events_interrupt_handlers.html">Signaling Events from Interrupt Handlers</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="signaling_sem_priority_inheritance.html">Signaling Semaphores and Priority Inheritance</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="smaller_vector_tables.html">Smaller Vector Tables</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="port.html">How to port</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="updating_release_system_elf.html">Updating a Release System with ELF Programs</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="partially_linked_elf.html">ELF Programs – With Symbol Tables</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="fully_linked_elf.html">ELF Programs – No Symbol Tables</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="building_nuttx_with_app_out_of_src_tree.html">Building NuttX with Applications Outside the Source Tree</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="building_uclibcpp.html">Building uClibc++</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="custom_app_directories.html">Custom Application Directories</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="multiple_nsh_sessions.html">Multiple NSH Sessions</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="nsh_network_link_management.html">NSH Network Link Management</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="ram_rom_disks.html">RAM Disks and ROM Disks</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="reading_can_msgs.html">Reading CAN Messages</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="remove_device_drivers_nsh.html">Removing Device Drivers with NSH</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="rust.html">Rust in NuttX</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="optee.html">Interfacing with OP-TEE</a></li> |
| </ul> |
| </li> |
| <li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../logos/index.html">NuttX Logos</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../_tags/tagsindex.html">Tags</a></li> |
| </ul> |
| |
| </div> |
| </div> |
| </nav> |
| |
| <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > |
| <i data-toggle="wy-nav-top" class="fa fa-bars"></i> |
| <a href="../index.html">NuttX</a> |
| </nav> |
| |
| <div class="wy-nav-content"> |
| <div class="rst-content"> |
| <div role="navigation" aria-label="Page navigation"> |
| <ul class="wy-breadcrumbs"> |
| <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li> |
| <li class="breadcrumb-item"><a href="index.html">Guides</a></li> |
| <li class="breadcrumb-item active">NuttX Protected Build</li> |
| <li class="wy-breadcrumbs-aside"> |
| <a href="https://github.com/apache/nuttx/blob/master/Documentation/guides/protected_build.rst" class="fa fa-github"> Edit on GitHub</a> |
| </li> |
| </ul> |
| <hr/> |
| </div> |
| <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> |
| <div itemprop="articleBody"> |
| |
| <section id="nuttx-protected-build"> |
| <h1>NuttX Protected Build<a class="headerlink" href="#nuttx-protected-build" title="Permalink to this heading"></a></h1> |
| <div class="admonition warning"> |
| <p class="admonition-title">Warning</p> |
| <p>Migrated from : |
| <a class="reference external" href="https://cwiki.apache.org/confluence/display/NUTTX/NuttX+Protected+Build">https://cwiki.apache.org/confluence/display/NUTTX/NuttX+Protected+Build</a></p> |
| </div> |
| <section id="the-traditional-flat-build"> |
| <h2>The Traditional “Flat” Build<a class="headerlink" href="#the-traditional-flat-build" title="Permalink to this heading"></a></h2> |
| <p>The traditional NuttX build is a “flat” build. By flat, I mean that when |
| you build NuttX, you end up with a single “blob” called <code class="docutils literal notranslate"><span class="pre">nuttx</span></code>. All of the |
| components of the build reside in the same address space. All components |
| of the build can access all other components of the build.</p> |
| </section> |
| <section id="the-two-pass-protected-build"> |
| <h2>The “Two Pass” Protected Build<a class="headerlink" href="#the-two-pass-protected-build" title="Permalink to this heading"></a></h2> |
| <p>The NuttX protected build, on the other hand, is a “two-pass” build and |
| generates two “blobs”: (1) a separately compiled and linked <cite>kernel</cite> blob |
| called, again, <cite>nuttx</cite> and separately compiled and linked <cite>user</cite> blob called |
| in <code class="docutils literal notranslate"><span class="pre">nuttx_user.elf</span></code> (in the existing build configurations). The user blob |
| is created on pass 1 and the kernel blob is created on pass2.</p> |
| <p>These two make commands are identical:</p> |
| <div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>make |
| make<span class="w"> </span>pass1<span class="w"> </span>pass2 |
| </pre></div> |
| </div> |
| <p>But the second is clearer and I prefer to use it for the protected build. |
| In the second case, the user and kernel blobs are built separately; in the |
| first, the kernel and user blob builds may be intermixed and somewhat |
| confusing. You can also build the kernel and user blobs separately with |
| one of the following commands:</p> |
| <div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>make<span class="w"> </span>pass1 |
| make<span class="w"> </span>pass2 |
| </pre></div> |
| </div> |
| <p>At the end of the build, there will be several files in the top-level NuttX build directory. From Pass 1:</p> |
| <ul class="simple"> |
| <li><p><code class="docutils literal notranslate"><span class="pre">nuttx_user.elf</span></code>. The pass1 user-space ELF file</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">nuttx_user.hex</span></code>. The pass1 Intel HEX format file (selected in <code class="docutils literal notranslate"><span class="pre">defconfig</span></code>)</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">User.map</span></code>. Symbols in the user-space ELF file</p></li> |
| </ul> |
| <p>From Pass 2:</p> |
| <ul class="simple"> |
| <li><p><code class="docutils literal notranslate"><span class="pre">nuttx</span></code>. The pass2 kernel-space ELF file</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">nuttx.hex</span></code>. The pass2 Intel HEX file (selected in <code class="docutils literal notranslate"><span class="pre">defconfig</span></code>)</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">System.map</span></code>. Symbols in the kernel-space ELF file</p></li> |
| </ul> |
| </section> |
| <section id="the-memory-protection-unit"> |
| <h2>The Memory Protection Unit<a class="headerlink" href="#the-memory-protection-unit" title="Permalink to this heading"></a></h2> |
| <p>If the MCU supports a Memory Protection Unit (MPU), then the logic within |
| the kernel blob all execute in kernel-mode, i.e., with all privileges. |
| These privileged threads can access all memory, all CPU instructions, |
| and all MCU registers. The logic executing within the user-mode blob, |
| on the other hand, all execute in user-mode with certain restrictions |
| as enforced by the MCU and by the MPU. The MCU may restrict access to |
| certain registers and machine instructions; with the MPU, access to all |
| kernel memory resources are prohibited from the user logic. This includes |
| the kernel blob’s FLASH, .bss/.data storage, and the kernel heap memory.</p> |
| </section> |
| <section id="advantages-of-the-protected-build"> |
| <h2>Advantages of the Protected Build<a class="headerlink" href="#advantages-of-the-protected-build" title="Permalink to this heading"></a></h2> |
| <p>The advantages of such a protected build are (1) security and (2) |
| modularity. Since the kernel resources are protected, it will be much |
| less likely that a misbehaving task will crash the system or that a |
| wild pointer access will corrupt critical memory. This security also |
| provides a safer environment in which to execute 3rd party software |
| and prevents “snooping” into the kernel memory from the hosted applications.</p> |
| <p>Modularity is assured because there is a strict control of the exposed |
| kernel interfaces. In the flat build, all symbols are exposed and there |
| is no enforcement of a kernel API. With the protected build, on the |
| other hand, all interactions with the kernel from the user application |
| logic must use <cite>system calls</cite> (or <cite>syscalls</cite>) to interface with the OS. A |
| system call is necessary to transition from user-mode to kernel-mode; |
| all user-space operating system interfaces are via syscall <cite>proxies</cite>. |
| Then, while in kernel mode, the kernel system call handler will |
| perform the OS service requested by the application. At the |
| conclusion of system processing, user-privileges are restored |
| and control is return to the user application. Since the only |
| interactions with the kernel can be through support system calls, |
| modularity of the OS is guaranteed.</p> |
| </section> |
| <section id="user-space-proxies-kernel-space-stubs"> |
| <h2>User-Space Proxies/Kernel-Space Stubs<a class="headerlink" href="#user-space-proxies-kernel-space-stubs" title="Permalink to this heading"></a></h2> |
| <p>The same OS interfaces are exposed to the application in both the “flat” |
| build and the protected build. The difference is that in the protected |
| build, the user-code interfaces with a <cite>proxy</cite> for the OS function. For |
| example, here is what a proxy for the OS <code class="docutils literal notranslate"><span class="pre">getpid()</span></code> interface:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><unistd.h></span> |
| <span class="cp">#include</span><span class="w"> </span><span class="cpf"><syscall.h></span> |
| <span class="kt">pid_t</span><span class="w"> </span><span class="nf">getpid</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> |
| <span class="p">{</span> |
| <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="kt">pid_t</span><span class="p">)</span><span class="n">sys_call0</span><span class="p">(</span><span class="n">SYS_getpid</span><span class="p">);</span> |
| <span class="p">}</span> |
| </pre></div> |
| </div> |
| <p>Thus the <code class="docutils literal notranslate"><span class="pre">getpid()</span></code> proxy is a stand-in for the real OS <code class="docutils literal notranslate"><span class="pre">getpid()</span></code> interface |
| that executes a system call so the kernel code can perform the real |
| <code class="docutils literal notranslate"><span class="pre">getpid()</span></code> operation on behalf of the user application. Proxies are |
| auto-generated for all exported OS interfaces using the CSV file |
| <code class="docutils literal notranslate"><span class="pre">syscall/syscall.csv</span></code> and the program <code class="docutils literal notranslate"><span class="pre">tools/mksyscalls</span></code>. Similarly, |
| on the kernel-side, there are auto-generated <cite>stubs</cite> that map the |
| system calls back into real OS calls. These, however, are internal |
| to the OS and the implementation may be architecture-specific. |
| See the <code class="docutils literal notranslate"><span class="pre">README.txt</span></code> files in those directories for further information.</p> |
| </section> |
| <section id="combining-intel-hex-files"> |
| <h2>Combining Intel HEX Files<a class="headerlink" href="#combining-intel-hex-files" title="Permalink to this heading"></a></h2> |
| <p>One issue that you may face is that the two pass builds creates two |
| FLASH images. Some debuggers that I use will allow me to write each |
| image to FLASH separately. Others will expect to have a single Intel |
| HEX image. In this latter case, you may need to combine the two Intel |
| HEX files into one. Here is how you can do that:</p> |
| <ol class="arabic simple"> |
| <li><p>The <cite>tail</cite> of the <code class="docutils literal notranslate"><span class="pre">nuttx.hex</span></code> file should look something like this |
| (with my comments and spaces added):</p></li> |
| </ol> |
| <div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$<span class="w"> </span>tail<span class="w"> </span>nuttx.hex |
| <span class="c1"># 00, data records</span> |
| ... |
| :10<span class="w"> </span>9DC0<span class="w"> </span><span class="m">00</span><span class="w"> </span>01000000000800006400020100001F0004 |
| :10<span class="w"> </span>9DD0<span class="w"> </span><span class="m">00</span><span class="w"> </span>3B005A0078009700B500D400F300110151 |
| :08<span class="w"> </span>9DE0<span class="w"> </span><span class="m">00</span><span class="w"> </span>30014E016D0100008D |
| <span class="c1"># 05, Start Linear Address Record</span> |
| :04<span class="w"> </span><span class="m">0000</span><span class="w"> </span><span class="m">05</span><span class="w"> </span><span class="m">0800</span><span class="w"> </span><span class="m">0419</span><span class="w"> </span>D2 |
| <span class="c1"># 01, End Of File record</span> |
| :00<span class="w"> </span><span class="m">0000</span><span class="w"> </span><span class="m">01</span><span class="w"> </span>FF |
| </pre></div> |
| </div> |
| <p>Use an editor such as vi to remove the 05 and 01 records.</p> |
| <ol class="arabic simple" start="2"> |
| <li><p>The <cite>head</cite> of the <code class="docutils literal notranslate"><span class="pre">nuttx_user.hex</span></code> file should look something like this |
| (again with my comments and spaces added):</p></li> |
| </ol> |
| <div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$<span class="w"> </span>head<span class="w"> </span>nuttx_user.hex |
| <span class="c1"># 04, Extended Linear Address Record</span> |
| :02<span class="w"> </span><span class="m">0000</span><span class="w"> </span><span class="m">04</span><span class="w"> </span><span class="m">0801</span><span class="w"> </span>F1 |
| <span class="c1"># 00, data records</span> |
| :10<span class="w"> </span><span class="m">8000</span><span class="w"> </span><span class="m">00</span><span class="w"> </span>BD89<span class="w"> </span>01084C800108C8110208D01102087E |
| :10<span class="w"> </span><span class="m">8010</span><span class="w"> </span><span class="m">00</span><span class="w"> </span><span class="m">0010</span><span class="w"> </span>00201C1000201C1000203C16002026 |
| :10<span class="w"> </span><span class="m">8020</span><span class="w"> </span><span class="m">00</span><span class="w"> </span>4D80<span class="w"> </span>01085D80010869800108ED83010829 |
| ... |
| </pre></div> |
| </div> |
| <p>Nothing needs to be done here. The <code class="docutils literal notranslate"><span class="pre">nuttx_user.hex</span></code> file should be fine.</p> |
| <ol class="arabic simple" start="3"> |
| <li><p>Combine the edited nuttx.hex and un-edited <code class="docutils literal notranslate"><span class="pre">nuttx_user.hex</span></code> file to produce |
| a single combined hex file:</p></li> |
| </ol> |
| <div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$<span class="w"> </span>cat<span class="w"> </span>nuttx.hex<span class="w"> </span>nuttx_user.hex<span class="w"> </span>>combined.hex |
| </pre></div> |
| </div> |
| <p>Then use the <code class="docutils literal notranslate"><span class="pre">combined.hex</span></code> file with for FLASH/JTAG tool. If you do this |
| a lot, you will probably want to invest a little time to develop a tool |
| to automate these steps.</p> |
| </section> |
| <section id="files-and-directories"> |
| <h2>Files and Directories<a class="headerlink" href="#files-and-directories" title="Permalink to this heading"></a></h2> |
| <p>Here is a summary of directories and files used by the STM32F4Discovery |
| protected build:</p> |
| <ul class="simple"> |
| <li><p><code class="docutils literal notranslate"><span class="pre">boards/arm/stm32/stm32f4discovery/configs/kostest</span></code>. This is the kernel |
| mode OS test configuration. The two standard configuration files |
| can be found in this directory: (1) <code class="docutils literal notranslate"><span class="pre">defconfig</span></code> and (2) <code class="docutils literal notranslate"><span class="pre">Make.defs</span></code>.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">boards/arm/stm32/stm32f4discovery/kernel</span></code>. This is the first past |
| build directory. The Makefile in this directory is invoked to |
| produce the pass1 object (<code class="docutils literal notranslate"><span class="pre">nuttx_user.elf</span></code> in this case). The |
| second pass object is created by <code class="docutils literal notranslate"><span class="pre">arch/arm/src/Makefile</span></code>. Also |
| in this directory is the file <code class="docutils literal notranslate"><span class="pre">userspace.c</span></code>. The user-mode blob |
| contains a header that includes information need by the kernel |
| blob in order to interface with the user-code. That header is |
| defined in by this file.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">boards/arm/stm32/stm32f4discovery/scripts</span></code>. Linker scripts for |
| the kernel mode build are found in this directory. This includes |
| (1) <code class="docutils literal notranslate"><span class="pre">memory.ld</span></code> which hold the common memory map, (2) <code class="docutils literal notranslate"><span class="pre">user-space.ld</span></code> |
| that is used for linking the pass1 user-mode blob, and (3) |
| <code class="docutils literal notranslate"><span class="pre">kernel-space.ld</span></code> that is used for linking the pass1 kernel-mode blob.</p></li> |
| </ul> |
| </section> |
| <section id="alignment-regions-and-subregions"> |
| <h2>Alignment, Regions, and Subregions<a class="headerlink" href="#alignment-regions-and-subregions" title="Permalink to this heading"></a></h2> |
| <p>There are some important comments in the <code class="docutils literal notranslate"><span class="pre">memory.ld</span></code> |
| file that are worth duplicating here:</p> |
| <p>“The STM32F407VG has 1024Kb of FLASH beginning at address |
| 0x0800:0000 and 192Kb of SRAM. SRAM is split up into three blocks:</p> |
| <ul class="simple"> |
| <li><p>“112KB of SRAM beginning at address 0x2000:0000</p></li> |
| <li><p>“16KB of SRAM beginning at address 0x2001:c000</p></li> |
| <li><p>“64KB of CCM SRAM beginning at address 0x1000:0000</p></li> |
| </ul> |
| <p>“When booting from FLASH, FLASH memory is aliased to address |
| 0x0000:0000 where the code expects to begin execution by jumping |
| to the entry point in the 0x0800:0000 address range.</p> |
| <p>“For MPU support, the kernel-mode NuttX section is assumed to |
| be 128Kb of FLASH and 4Kb of SRAM. That is an excessive amount |
| for the kernel which should fit into 64KB and, of course, can |
| be optimized as needed… Allowing the additional memory does |
| permit addition debug instrumentation to be added to the kernel |
| space without overflowing the partition.</p> |
| <p>“Alignment of the user space FLASH partition is also a critical |
| factor: The user space FLASH partition will be spanned with a |
| single region of size 2||n bytes. The alignment of the user-space |
| region must be the same. As a consequence, as the user-space |
| increases in size, the alignment requirement also increases.</p> |
| <p>“This alignment requirement means that the largest user space |
| FLASH region you can have will be 512KB at it would have to be |
| positioned at 0x08800000. If you change this address, don’t |
| forget to change the <code class="docutils literal notranslate"><span class="pre">CONFIG_NUTTX_USERSPACE</span></code> configuration |
| setting to match and to modify the check in <code class="docutils literal notranslate"><span class="pre">kernel/userspace.c</span></code>.</p> |
| <p>“For the same reasons, the maximum size of the SRAM mapping is |
| limited to 4KB. Both of these alignment limitations could be |
| reduced by using multiple MPU regions to map the FLASH/SDRAM |
| range or perhaps with some clever use of subregions.”</p> |
| </section> |
| <section id="memory-management"> |
| <h2>Memory Management<a class="headerlink" href="#memory-management" title="Permalink to this heading"></a></h2> |
| <p>At present, there are two options for memory management in the |
| NuttX protected build:</p> |
| <section id="single-user-heap"> |
| <h3>Single User Heap<a class="headerlink" href="#single-user-heap" title="Permalink to this heading"></a></h3> |
| <p>By default, there is only a single user-space heap and heap |
| allocator that is shared by both kernel- and user-modes. |
| PROs: Simple and makes good use of the heap memory space, |
| CONs: Awkward architecture and no security for kernel-mode |
| allocations.</p> |
| </section> |
| <section id="dual-partitioned-heaps"> |
| <h3>Dual, Partitioned Heaps<a class="headerlink" href="#dual-partitioned-heaps" title="Permalink to this heading"></a></h3> |
| <p>Two configuration options can change this behavior:</p> |
| <ul class="simple"> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_MM_MULTIHEAP=y</span></code>. This changes internal memory manager interfaces |
| so that multiple heaps can be supported.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_MM_KERNEL_HEAP=y</span></code>. Uses the multi-heap capability to enable |
| a kernel heap</p></li> |
| </ul> |
| <p>If this both options are defined defined, the two heap partitions and |
| two copies of the memory allocators are built:</p> |
| <p>One un-protected heap partition that will allocate user accessible memory |
| that is shared by both the kernel- and user-space code. That allocator |
| physically resides in the user address space so that it can be called |
| directly by both the user- and kernel-space code. There is a header at |
| the beginning of the user-space blob; the kernel-space code gets |
| address of the user-space allocator from this header.</p> |
| <p>And another protected heap partition that will allocate protected |
| memory that is only accessible from the kernel code. This allocator |
| is built into the kernel block. This separate protected heap is |
| required if you want to support security features.</p> |
| <p>NOTE: There are security issues with calling into the user space |
| allocators in kernel mode. That is a security hole that could be |
| exploit to gain control of the system! Instead, the kernel code |
| should switch to user mode before entering the memory allocator |
| stubs (perhaps via a trap). The memory allocator stubs should |
| then trap to return to kernel mode (as does the signal handler now).</p> |
| </section> |
| <section id="the-traditional-approach"> |
| <h3>The Traditional Approach<a class="headerlink" href="#the-traditional-approach" title="Permalink to this heading"></a></h3> |
| <p>A more traditional approach would use something like the interface |
| <code class="docutils literal notranslate"><span class="pre">sbrk()</span></code>. The <code class="docutils literal notranslate"><span class="pre">sbrk()</span></code> function adds memory to the heap space |
| allocation of the calling process. In this case, there would |
| still be kernel- and user-mode instances of the memory allocators. |
| Each would <code class="docutils literal notranslate"><span class="pre">sbrk()</span></code> as necessary to extend their heap; the pages |
| allocated for the kernel-mode allocator would be protected but |
| the pages allocated for the user-mode allocator would not. |
| PROs: Meets all of the needs. CONs: Complex. Memory losses |
| due to quantization.</p> |
| <p>This approach works well with CPUs that have very capable |
| Memory Management Units (MMUs) that can coalesce the |
| srbk-ed chunks to a contiguous, <cite>virtual</cite> heap region. |
| Without an MMU, the sbrk-ed memory would not be |
| contiguous; this would limit the sizes of allocations |
| due to the physical pages.</p> |
| <p>Many MCUs will have Memory Protection Units (MPUs) that can |
| support the security features (only). However these lower |
| end MPUs may not support sufficient mapping capability to |
| support this traditional approach. The ARMv7-M MPU, for |
| example, only supports eight protection regions to manage |
| all FLASH and SRAM and so this approach would not be |
| technically feasible for th ARMv7-M family (Cortex-M3/4).</p> |
| </section> |
| </section> |
| <section id="comparing-the-flat-build-configuration-with-the-protected-build-configuration"> |
| <h2>Comparing the “Flat” Build Configuration with the Protected Build Configuration<a class="headerlink" href="#comparing-the-flat-build-configuration-with-the-protected-build-configuration" title="Permalink to this heading"></a></h2> |
| <p>Compare, for example the configuration |
| <code class="docutils literal notranslate"><span class="pre">boards/arm/stm32/stm32f4discovery/configs/ostest</span></code> and the |
| configuration <code class="docutils literal notranslate"><span class="pre">boards/arm/stm32/stm32f4discovery/configs/kostest</span></code>. |
| These two configurations are identical except that one builds a |
| “flat” version of OS test and the other builds a kernel version |
| of the OS test. See the file <code class="docutils literal notranslate"><span class="pre">boards/arm/stm32/stm32f4discovery/README.txt</span></code> |
| for more details about those configurations.</p> |
| <p>The configurations can be compared using the <code class="docutils literal notranslate"><span class="pre">cmpconfig</span></code> tool:</p> |
| <div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="nb">cd</span><span class="w"> </span>tools |
| make<span class="w"> </span>-f<span class="w"> </span>Makefile.host<span class="w"> </span>cmpconfig |
| <span class="nb">cd</span><span class="w"> </span>.. |
| tools/cmpconfig<span class="w"> </span>boards/arm/stm32/stm32f4discovery/configs/ostest/defconfig<span class="w"> </span>boards/arm/stm32/stm32f4discovery/configs/kostest/defconfig |
| </pre></div> |
| </div> |
| <p>Here is a summary of the meaning of all of the important differences in the |
| configurations. This should be enough information for you to convert any |
| configuration from a “flat” to a protected build:</p> |
| <ul class="simple"> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_BUILD_2PASS=y</span></code>. This enables the two pass build.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_BUILD_PROTECTED=y</span></code>. This option enables the “two pass” |
| protected build.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_PASS1_BUILDIR="boards/arm/stm32/stm32f4discovery/kernel"</span></code>. |
| This tells the build system the (relative) location of the pass1 build directory.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_PASS1_OBJECT=""</span></code>. In some “two pass” build configurations, |
| the build system need to know the name of the first pass object. |
| This setting is not used for the protected build.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_NUTTX_USERSPACE=0x08020000</span></code>. This is the expected location |
| where the user-mode blob will be located. The user-mode blob |
| contains a header that includes information need by the kernel |
| blob in order to interface with the user-code. That header will |
| be expected to reside at this location.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_PASS1_TARGET="all"</span></code>. This is the build target to use for |
| invoking the pass1 make.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_MM_MULTIHEAP=y</span></code>. This changes internal memory manager |
| interfaces so that multiple heaps can be supported.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_MM_KERNEL_HEAP=y</span></code>. NuttX supports the option of using a |
| single user-accessible heap or, if this options is defined, |
| two heaps: (1) one that will allocate user accessible memory |
| that is shared by both the kernel- and user-space code, and |
| (2) one that will allocate protected memory that is only |
| accessible from the kernel code. Separate heap memory is required |
| if you want to support security features.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_MM_KERNEL_HEAPSIZE=8192</span></code>. This determines an approximate |
| size for the kernel heap. The standard heap space is partitioned |
| into a kernel- and user-heap space. This size of the kernel heap |
| is only approximate because the user heap is subject to stringent |
| alignment requirements. Because of the alignment requirements, the |
| actual size of the kernel heap could be considerable larger than this.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_BOARD_EARLY_INITIALIZE=y</span></code>. This setting enables a special, |
| <cite>early</cite> initialization call to initialize board-specific resources.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_BOARD_LATE_INITIALIZE=y</span></code>. This setting enables a special |
| initialization call to initialize <cite>late</cite> board-specific resources. |
| The difference between <code class="docutils literal notranslate"><span class="pre">CONFIG_BOARD_EARLY_INITIALIZE</span></code> and |
| <code class="docutils literal notranslate"><span class="pre">CONFIG_BOARD_LATE_INITIALIZE</span></code> is that the <code class="docutils literal notranslate"><span class="pre">CONFIG_BOARD_EARLY_INITIALIZE</span></code> |
| logic runs earlier in initialization before the full operating |
| system is up and running. <code class="docutils literal notranslate"><span class="pre">CONFIG_BOARD_LATE_INITIALIZE</span></code>, on the |
| other hand, runs at the completion of initialization, just before |
| the user applications are started. Neither <code class="docutils literal notranslate"><span class="pre">CONFIG_BOARD_EARLY_INITIALIZE</span></code> |
| nor <code class="docutils literal notranslate"><span class="pre">CONFIG_BOARD_LATE_INITIALIZE</span></code> are used in the OS test |
| configuration but other configurations (such as NSH) |
| require some application-specific initialization before |
| the application can run. In the “flat” build, such initialization |
| is performed as part of the application start-up sequence. |
| These includes such things as initializing device drivers. |
| These same initialization steps must be performed in kernel |
| mode for the protected build and <code class="docutils literal notranslate"><span class="pre">CONFIG_BOARD_LATE_INITIALIZE</span></code>. |
| See <code class="docutils literal notranslate"><span class="pre">boards/arm/stm32/stm32f4discovery/src/up_boot.c</span></code> for an |
| example of such board initialization code.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_NSH_ARCHINITIALIZE</span></code> is not defined. The setting |
| <code class="docutils literal notranslate"><span class="pre">CONFIG_NSH_ARCHINITIALIZE</span></code> does not apply to the OS test |
| configuration, however, this is noted here as an example |
| of initialization that cannot be performed in the protected build.</p></li> |
| </ul> |
| <p>Architecture-Specific Options:</p> |
| <ul class="simple"> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_SYS_RESERVED=8</span></code>. The user application logic |
| interfaces with the kernel blob using system calls. |
| The architecture-specific logic may need to reserved a |
| few system calls for its own internal use. The ARMv7-M |
| architectures all require 8 reserved system calls.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_SYS_NNEST=2</span></code>. System calls may be nested. The |
| system must retain information about each nested system |
| call and this setting is used to set aside resources for |
| nested system calls. In the current architecture, a maximum |
| nesting level of two is all that is needed.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARMV7M_MPU=y</span></code>. This settings enables support for |
| the ARMv7-M Memory Protection Unit (MPU). The MPU is used |
| to prohibit user-mode access to kernel resources.</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARMV7M_MPU_NREGIONS=8</span></code>. The ARMv7-M MPU supports 8 |
| protection regions.</p></li> |
| </ul> |
| </section> |
| <section id="size-expansion"> |
| <h2>Size Expansion<a class="headerlink" href="#size-expansion" title="Permalink to this heading"></a></h2> |
| <p>The protected build will, or course, result in a FLASH image that is |
| larger than that of the corresponding “flat” build. How much larger? |
| I don’t have the numbers in hand, but you can build |
| <code class="docutils literal notranslate"><span class="pre">boards/arm/stm32/stm32f4discovery/configs/nsh</span></code> and |
| <code class="docutils literal notranslate"><span class="pre">boards/arm/stm32/stm32f4discovery/configs/kostest</span></code> and compare |
| the resulting binaries for yourself using the <code class="docutils literal notranslate"><span class="pre">size</span></code> command.</p> |
| <p>Increases in size are expected because:</p> |
| <ul class="simple"> |
| <li><p>The syscall layer is included in the protected build but not the flat |
| build.</p></li> |
| <li><p>The kernel-size _syscal_l stubs will cause all enabled OS code to be |
| drawn into the build. In the flat build, only those OS interfaces |
| actually called by the application will be included in the final objects.</p></li> |
| <li><p>The dual memory allocators will increase size.</p></li> |
| <li><p>Code duplication. Some code, such as the C library, will be |
| duplicated in both the kernel- and user-blobs, and</p></li> |
| <li><p>Alignment. The alignments required by the MPU logic will leave |
| relatively large regions of FLASH (and perhaps RAM) is not usable.</p></li> |
| </ul> |
| </section> |
| <section id="performance-issues"> |
| <h2>Performance Issues<a class="headerlink" href="#performance-issues" title="Permalink to this heading"></a></h2> |
| <p>The only performance differences using the protected build should |
| result as a consequence of the <cite>sycalls</cite> used to interact with the |
| OS vs. the direct C calls as used in the flat build. If your |
| performance is highly dependent upon high rate OS calls, then |
| this could be an issue for you. But, in the typical application, |
| OS calls do not often figure into the critical performance paths.</p> |
| <p>The <cite>syscalls</cite> are, ultimately, software interrupts. If the platform |
| does not support prioritized, nested interrupts then the <cite>syscall</cite> |
| execution could also delay other hardware interrupt processing. |
| However, <cite>sycall</cite> processing is negligible: they really just |
| configure to return to in supervisor mode and vector to the |
| <cite>syscall</cite> stub. They should be lightning fast and, for the typical |
| real-time applications, should cause no issues.</p> |
| </section> |
| </section> |
| |
| |
| </div> |
| </div> |
| <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> |
| <a href="integrate_newlib.html" class="btn btn-neutral float-left" title="Integrating with Newlib" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> |
| <a href="platform_directories.html" class="btn btn-neutral float-right" title="Platform Directories" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> |
| </div> |
| |
| <hr/> |
| |
| <div role="contentinfo"> |
| <p>© Copyright 2023, The Apache Software Foundation.</p> |
| </div> |
| |
| |
| |
| </footer> |
| </div> |
| </div> |
| </section> |
| </div> |
| <script> |
| jQuery(function () { |
| SphinxRtdTheme.Navigation.enable(true); |
| }); |
| </script> |
| |
| </body> |
| </html> |