README.md 8.78 KB
Newer Older
Maximilian Luz's avatar
Maximilian Luz committed
1
2
3
4
5
6
7
8
9
# QEMU for ISIS-OBC

QEMU with support for the ISIS On-Board Computer used in SOURCE.

See `README.orig.rst` for the original QEMU readme.


## Building QEMU

Maximilian Luz's avatar
Maximilian Luz committed
10
11
12
For a general overview of how to build QEMU on Linux and which dependencies are required, see https://wiki.qemu.org/Hosts/Linux#Building_QEMU_for_Linux.
In the following is a short overview.
Note that you do not need to fully build QEMU, as we only need ARM system emulation (i.e. all other machines can be skipped).
Robin Mueller's avatar
Robin Mueller committed
13
14
Install basic build tools if not already done so
```sh
Robin Mueller's avatar
Robin Mueller committed
15
sudo apt-get install build-essential cmake
Robin Mueller's avatar
Robin Mueller committed
16
17
18
19
20
21
``` 

Install required libraries
```sh
sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev
```
Maximilian Luz's avatar
Maximilian Luz committed
22

Robin Mueller's avatar
Robin Mueller committed
23
24
25
26
27
28
Update the submodules
```sh
git submodule init
git submodule update
```

Maximilian Luz's avatar
Maximilian Luz committed
29
30
31
It is recommended to build QEMU in a separate build directory.
In the following, we assume that this directory is `./build/` in the source directory.
If you are building QEMU for the first time, you can create this directory via
Robin Mueller's avatar
Robin Mueller committed
32
```sh
Maximilian Luz's avatar
Maximilian Luz committed
33
34
mkdir build && cd build
```
Robin Mueller's avatar
Robin Mueller committed
35

Maximilian Luz's avatar
Maximilian Luz committed
36
37
From that, you then need to configure the QEMU build system.
For this, it is sufficient to only specify `arm-softmmu` as emulation target.
Robin Mueller's avatar
Robin Mueller committed
38
```sh
Maximilian Luz's avatar
Maximilian Luz committed
39
40
../configure --target-list=arm-softmmu
```
Robin Mueller's avatar
Robin Mueller committed
41

Maximilian Luz's avatar
Maximilian Luz committed
42
Finally build QEMU via
Robin Mueller's avatar
Robin Mueller committed
43
44
```sh
make -j`nproc`
Maximilian Luz's avatar
Maximilian Luz committed
45
46
47
```
Note that you only need to re-run the latest step (i.e. `make` from inside the build directory) when you make changes to the source-code and want to rebuild.

Robin Mueller's avatar
Robin Mueller committed
48
49
50
51
52
## Setting up QEMU for eclipse

To set up QEMU for eclipse, follow the steps above and make sure this repostiory was cloned in the same directory the OBSW was cloned.
After that, the shell script inside the OBSW folder should work to start the QEMU emulation for the iOBC.
To test whether QEMU will run with the script, run the second command from the next section.
Maximilian Luz's avatar
Maximilian Luz committed
53
54
55

## Running QEMU for ISIS-OBC

Maximilian Luz's avatar
Maximilian Luz committed
56
From the root directory, run
Maximilian Luz's avatar
Maximilian Luz committed
57
```sh
Maximilian Luz's avatar
Maximilian Luz committed
58
59
60
./iobc-loader                                    \
    -f <file-addr> ./path/to/bin -s <start-addr> \
    -- -monitor stdio
Maximilian Luz's avatar
Maximilian Luz committed
61
```
Maximilian Luz's avatar
Maximilian Luz committed
62
63
Make sure the path to the binary is set up correctly and use the appropriate address to load the file to (`<file-addr>`) and start address, i.e. initial program counter (`<start-addr>`).
Debug-loading the `sdram` binary works, for example with
Robin Mueller's avatar
Robin Mueller committed
64
```sh
Maximilian Luz's avatar
Maximilian Luz committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
./iobc-loader                       \
    -f sdram ./path/to/sdram-bin -s sdram -o pmc-mclk \
    -- -monitor stdio
```
while loading the full `nofrlash` binary works with 
```sh
./iobc-loader                       \
    -f norflash ./path/to/norflash-bin -s norflash \
    -- -monitor stdio
```
See `./iobc-loader -h` for more information.
The `iobc-loader` script will load and initialize the IOBC and load the specified files accordingly (more than one file can be specified at the same time).
Options after the `--` are directly forwarded to the underlying `qemu-system-arm`.

The QEMU options to pipe the serial output to the console directly are:
```sh
-serial stdio -monitor none
Robin Mueller's avatar
Robin Mueller committed
82
83
```
To have access to the QMP protocoll, have a look at the sections below.
Maximilian Luz's avatar
Maximilian Luz committed
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
### Support for SD-Cards

The iOBC supports up to two SD-Cards.
In QEMU, SD-Cards can be added by telling it to use a specified image file containing the contents of the SD-Card, meaning that all data will be read from and written to the file.
This can be done by adding the
```
-drive if=sd,index=0,format=raw,file=sd0.img
```
options to the `qemu-system-arm` call.
- The `-drive` option adds a new drive (i.e. block device).
- The `if=sd` parameter specifies the type as being an SD-Card.
- The `index=0` parameter specifies the slot of the SD-Card.
  This can be changed to `index=1` to populate the second SD-Card slot.
  For multiple slots, the `-drive` option can be repeated with parameters changed accordingly.
- The `format=raw` parameter specifies that the image file is in `raw` format.
  Multiple other formats are supported (for details consult the official QEMU documentation), however, `raw` images can be easily mounted in Linux (more details below) or copied directly from/to a physical SD-Card (e.g. via the `dd` tool).
  More on the creation of image files below.
- The `file=sd0.img` specifies that the file to be loaded is called `sd0.img` in the current working directory.
  Change `sd0.img` to whatever is appropriate for you.

As an example, a full command to run the iOBC on QEMU with two SD-Cards, provided as `sd0.img` and `sd1.img`, is
```
Maximilian Luz's avatar
Maximilian Luz committed
107
108
109
110
111
./iobc-lodaer                                              \
    -f sdram ./path/to/sourceobsw-at91sam9g20_ek-sdram.bin \
    -s sdram -o pmc-mclk                                   \
    -- -monitor stdio                                      \
    -drive if=sd,index=0,format=raw,file=sd0.img           \
112
113
114
115
116
117
118
119
    -drive if=sd,index=1,format=raw,file=sd1.img
```

#### Creating Image Files

To manipulate and create image files, QEMU provides the `qemu-img` tool.
A `raw`-type image can be created via the command
```
Maximilian Luz's avatar
Maximilian Luz committed
120
./build/qemu-img create -f raw sd0.img 4G
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
```
The `-f raw` option specifies the type as being `raw`, `sd0.img` is the path to the image file, and `4G` specifies that the image should have a size of four gigabytes.
Change the parameters according to your needs.
For more information and other format types refer to the actual QEMU documentation for this command.

#### Mounting a raw Image on Linux

On Linux systems, a `raw`-type image can be easily mounted via the command
```
mount -o loop sd0.img /mnt
```
Again, `sd0.img` is the path to the image file.
The `/mnt` path is the path to the directory where the image should be mounted.
This will not work as easily with other image formats, however, the `qemu-img` tool provides a sub-command to convert between different types of images, which can be used to convert other types to `raw` before mounting them with the above command.

Maximilian Luz's avatar
Maximilian Luz committed
136
137
138
139
140
141
142
143
### Controlling QEMU via QMP

QEMU can be controlled via the QEMU Machine Protocol (QMP).
This is can be useful for fully automated testing, as it, for example, allows the QEMU machine and simulation framework to be initialized and all device emulators to connect before sending a start command via QMP to actually start the simulated processor.
This way it can be ensured that no initial communication between machine and devices is lost.

For this, you will need to add the `-qmp` and `-S` flags, e.g. like this:
```sh
Maximilian Luz's avatar
Maximilian Luz committed
144
145
146
147
./iobc-loader                                              \
    -f sdram ./path/to/sourceobsw-at91sam9g20_ek-sdram.bin \
    -s sdram -o pmc-mclk                                   \
    -- -monitor stdio                                      \
Maximilian Luz's avatar
Maximilian Luz committed
148
149
150
151
152
153
    -qmp unix:/tmp/qemu,server -S
```
This opens a Unix domain socket at `/tmp/qemu`.
Commands can be automatically sent to this socket, e.g. from the simulation and testing framework.
Specifying the `-S` option causes QEMU to initially pause the emulation, otherwise it would start immediately.
Once the simulation framework is fully connected, it can then send a QMP `cont` command to continue emulation.
154
155
156
157
158
159
160
161
162
163
164
165
166
167

### Running without Graphics

By default, QEMU tries to launch a window which requires some graphics system (X11/Wayland) to be present.
If this is not available, e.g. in a virtual machine or container, one can add the
```
-serial stdio -monitor none
```
options.
The first option redirects the output of the emulated OBSW/the At91 to the standard I/O stream.
The second option disables the monitor interface, which can be used to pause or exit the emulator or control it in any other way.
For automated testing, this level of control is usually not required, and if so it is available via QMP.
If the monitor interface is needed nontheless (e.g. in an interactive session), one could open a telnet server, e.g. via `-monitor telnet:127.0.0.1:55555,server` and then connect to it via `telnet 127.0.0.1 55555`.
Please refer to the [QEMU documentation](https://qemu.weilnetz.de/doc/qemu-doc.html) for more details.
Maximilian Luz's avatar
Maximilian Luz committed
168
169
170
171
172
173
174
175
176
177
178

### Debugging AT91 with QEMU

Debugging a program running in QEMU is fairly easy:
Run QEMU with your preferred options (as detailed above) and add `-s -S`.
Option `-s` enables debugging (by default at port `1234`), option `-S` pauses initial execution until it is explicitly continued via a command in the debugger.
To then debug the running QEMU instance, simply start GDB and connect to `localhost:1234` (`target remote localhost:1234`).
To obtain debug information, load the symbols from the `.elf` file generated when compiling the binary (same directory, `symbol-file _bin/sam9g20/devel/sourceobsw-at91sam9g20_ek-sdram.elf`).

For example, the following commands can be used to
- run QEMU:
Maximilian Luz's avatar
Maximilian Luz committed
179
180
181
182
  ```sh
  ./iobc-loader                                              \
      -f sdram ./path/to/sourceobsw-at91sam9g20_ek-sdram.bin \
      -s sdram -o pmc-mclk -- -monitor stdio -s -S
Maximilian Luz's avatar
Maximilian Luz committed
183
184
185
186
187
188
  ```

- run GDB:
  ```
  arm-none-eabi-gdb \
      -ex 'target remote localhost:1234' \
Maximilian Luz's avatar
Maximilian Luz committed
189
      -ex 'symbol-file ./path/to/sourceobsw-at91sam9g20_ek-sdram.elf'
Maximilian Luz's avatar
Maximilian Luz committed
190
191
192
  ```
in your terminal.
IDEs with GDB support (Eclipse, VS-Code) can be configured accordingly.