source: rtems-docs/user/bsps/bsps-x86_64.rst @ 3859073

Last change on this file since 3859073 was 3859073, checked in by Chris Johns <chrisj@…>, on 08/03/22 at 04:22:20

versions: Update microblaze, powerpc, riscv and x86_64

Updates #4695

  • Property mode set to 100644
File size: 6.6 KB
Line 
1.. SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. Copyright (C) 2018 Amaan Cheval <amaan.cheval@gmail.com>
4.. Copyright (C) 2018 embedded brains GmbH
5
6x86_64
7******
8
9amd64
10=====
11
12This BSP offers only one variant, ``amd64``. The BSP can run on UEFI-capable
13systems by using FreeBSD's bootloader, which then loads the RTEMS executable (an
14ELF image).
15
16Currently only the console driver and context initialization and switching are
17functional (to a bare minimum), but this is enough to run the ``hello.exe`` sample
18in the RTEMS testsuite.
19
20Build Configuration Options
21---------------------------
22
23There are no BSP configuration options available at build time.
24
25Testing with QEMU
26-----------------
27
28To test with QEMU, we need to:
29
30- Build / install QEMU (most distributions should have it available on the
31  package manager).
32- Build UEFI firmware that QEMU can use to simulate an x86-64 system capable of
33  booting a UEFI-aware kernel, through the ``--bios`` flag.
34
35Building TianoCore's UEFI firmware, OVMF
36^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37
38Complete detailed instructions are available at `TianoCore's Github's wiki
39<https://github.com/tianocore/tianocore.github.io/wiki/How-to-build-OVMF>`_.
40
41Quick instructions (which may fall out of date) are:
42
43.. code-block:: none
44
45    $ git clone git://github.com/tianocore/edk2.git
46    $ cd edk2
47    $ make -C BaseTools
48    $ . edksetup.sh
49
50Then edit ``Conf/target.txt`` to set:
51
52.. code-block:: ini
53
54    ACTIVE_PLATFORM       = OvmfPkg/OvmfPkgX64.dsc
55    TARGET                = DEBUG
56    TARGET_ARCH           = X64
57    # You can use GCC46 as well, if you'd prefer
58    TOOL_CHAIN_TAG        = GCC5
59
60Then run ``build`` in the ``edk2`` directory - the output should list the
61location of the ``OVMF.fd`` file, which can be used with QEMU to boot into a UEFI
62shell.
63
64You can find the ``OVMF.fd`` file like this as well in the edk2 directory:
65
66.. code-block:: none
67
68    $ find . -name "*.fd"
69    ./Build/OvmfX64/DEBUG_GCC5/FV/MEMFD.fd
70    ./Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd # the file we're looking for
71    ./Build/OvmfX64/DEBUG_GCC5/FV/OVMF_CODE.fd
72    ./Build/OvmfX64/DEBUG_GCC5/FV/OVMF_VARS.fd
73
74Boot RTEMS via FreeBSD's bootloader
75-----------------------------------
76
77The RTEMS executable produced (an ELF file) needs to be placed in the FreeBSD's
78``/boot/kernel/kernel``'s place.
79
80To do that, we first need a hard-disk image with FreeBSD installed on
81it. `Download FreeBSD's installer "memstick" image for amd64
82<https://www.freebsd.org/where.html>`_ and then run the following commands,
83replacing paths as appropriate.
84
85.. code-block:: none
86
87  $ qemu-img create freebsd.img 8G
88  $ OVMF_LOCATION=/path/to/ovmf/OVMF.fd
89  $ FREEBSD_MEMSTICK=/path/to/FreeBSD-11.2-amd64-memstick.img
90  $ qemu-system-x86_64 -m 1024 -serial stdio --bios $OVMF_LOCATION \
91      -drive format=raw,file=freebsd.img \
92      -drive format=raw,file=$FREEBSD_MEMSTICK
93
94The first time you do this, continue through and install FreeBSD. `FreeBSD's
95installation guide may prove useful
96<https://www.freebsd.org/doc/handbook/bsdinstall-start.html>`_ if required.
97
98Once installed, build your RTEMS executable (an ELF file), for
99eg. ``hello.exe``. We need to transfer this executable into ``freebsd.img``'s
100filesystem, at either ``/boot/kernel/kernel`` or ``/boot/kernel.old/kernel`` (or
101elsewhere, if you don't mind user FreeBSD's ``loader``'s prompt to boot your
102custom kernel).
103
104If your host system supports mounting UFS filesystems as read-write
105(eg. FreeBSD), go ahead and:
106
1071. Mount ``freebsd.img`` as read-write
1082. Within the filesystem, back the existing FreeBSD kernel up (i.e. effectively
109   ``cp -r /boot/kernel /boot/kernel.old``).
1103. Place your RTEMS executable at ``/boot/kernel/kernel``
111
112If your host doesn't support mounting UFS filesystems (eg. most Linux kernels),
113do something to the effect of the following.
114
115On the host
116
117.. code-block:: none
118
119   # Upload hello.exe anywhere accessible within the host
120   $ curl --upload-file hello.exe https://transfer.sh/rtems
121
122Then on the guest (FreeBSD), login with ``root`` and
123
124.. code-block:: none
125
126   # Back the FreeBSD kernel up
127   $ cp -r /boot/kernel/ /boot/kernel.old
128   # Bring networking online if it isn't already
129   $ dhclient em0
130   # You may need to add the --no-verify-peer depending on your server
131   $ fetch https://host.com/path/to/rtems/hello.exe
132   # Replace default kernel
133   $ cp hello.exe /boot/kernel/kernel
134   $ reboot
135
136After rebooting, the RTEMS kernel should run after the UEFI firmware and
137FreeBSD's bootloader. The ``-serial stdio`` QEMU flag will let the RTEMS console
138send its output to the host's ``stdio`` stream.
139
140Paging
141------
142
143During the BSP's initialization, the paging tables are setup to identity-map the
144first 512GiB, i.e. virtual addresses are the same as physical addresses for the
145first 512GiB.
146
147The page structures are set up statically with 1GiB super-pages.
148
149.. note::
150  Page-faults are not handled.
151
152.. warning::
153  RAM size is not detected dynamically and defaults to 1GiB, if the
154  configuration-time ``RamSize`` parameter is not used.
155
156Interrupt Setup
157---------------
158
159Interrupt vectors ``0`` through ``32`` (i.e. 33 interrupt vectors in total) are
160setup as "RTEMS interrupts", which can be hooked through
161``rtems_interrupt_handler_install``.
162
163The Interrupt Descriptor Table supports a total of 256 possible vectors (0
164through 255), which leaves a lot of room for "raw interrupts", which can be
165hooked through ``_CPU_ISR_install_raw_handler``.
166
167Since the APIC needs to be used for the clock driver, the PIC is remapped (IRQ0
168of the PIC is redirected to vector 32, and so on), and then all interrupts are
169masked to disable the PIC. In this state, the PIC may _still_ produce spurious
170interrupts (IRQ7 and IRQ15, redirected to vector 39 and vector 47 respectively).
171
172The clock driver triggers the initialization of the APIC and then the APIC
173timer.
174
175The I/O APIC is not supported at the moment.
176
177.. note::
178  IRQ32 is reserved by default for the APIC timer (see following section).
179
180  IRQ255 is reserved by default for the APIC's spurious vector.
181
182.. warning::
183  Besides the first 33 vectors (0 through 32), and vector 255 (the APIC spurious
184  vector), no other handlers are attached by default.
185
186Clock Driver
187------------
188
189The clock driver currently uses the APIC timer. Since the APIC timer runs at the
190CPU bus frequency, which can't be detected easily, the PIT is used to calibrate
191the APIC timer, and then the APIC timer is enabled in periodic mode, with the
192initial counter setup such that interrupts fire at the same frequency as the
193clock tick frequency, as requested by ``CONFIGURE_MICROSECONDS_PER_TICK``.
194
195Console Driver
196--------------
197
198The console driver defaults to using the ``COM1`` UART port (at I/O port
199``0x3F8``), using the ``NS16550`` polled driver.
Note: See TracBrowser for help on using the repository browser.