Running Linux on QEMU¶
Info
Refer to the main QEMU article for information on installing QEMU.
Preface¶
It's possible to run on QEMU the same Linux images as for nSIM/HAPS. A process of building of Linux images is completely same.
Running for ARC HS 3x/4x¶
Running for ARC HS 5x¶
Info
Linux kernels for ARCv3 are loaded differently in comparison to kernels for ARCv1 and ARCv2.
Kernels for ARCv3 are always loaded from a physical address 0x0
instead of 0x80000000
.
A custom loader
image is generated to distinguish it from a default vmlinux
(vmlinux
uses 0x80000000
as a starting address in physical and virtual spaces). Thus, it's necessary to run QEMU with
-M virt,ram_start=0
parameter.
qemu-system-arc -M virt,ram_start=0 -cpu hs5x -m 2G -display none -nographic -monitor none -kernel loader
Running for ARC HS 6x¶
qemu-system-arc64 -M virt,ram_start=0 -cpu hs6x -m 2G -display none -nographic -monitor none -kernel loader
Networking in QEMU Using a User Level Network Interface¶
Configuring Network¶
Firstly, it's necessary to enable BR2_SYSTEM_DHCP
option in Buildroot configuration.
Just use BR2_SYSTEM_DHCP=eth0
in your configuration file or use this option in a
configuration menu:
You can connect a QEMU machine to a network using a user level network interface by passing these additional options:
You can enable port forwarding for a set of ports. Here is an example for forwarding ports for FTP and SSH:
-netdev user,id=net0,hostfwd=tcp::2021-:21,hostfwd=tcp::2022-:22 -device virtio-net-device,netdev=net0 -device virtio-rng-pci
Here is a full command line for running QEMU with support of networking and forwarding of ports for FTP and SSH:
qemu-system-arc -M virt -cpu archs -m 2G -display none -nographic -monitor none -kernel vmlinux -device virtio-rng-pci \
-netdev user,id=net0,hostfwd=tcp::2021-:21,hostfwd=tcp::2022-:22 -device virtio-net-device,netdev=net0
In boot log output you will see these lines:
Starting network: udhcpc: started, v1.35.0
udhcpc: broadcasting discover
udhcpc: broadcasting select for 10.0.2.15, server 10.0.2.2
udhcpc: lease of 10.0.2.15 obtained from 10.0.2.2, lease time 86400
deleting routers
adding dns 10.0.2.3
Use ifconfig
or ping
utility to ensure that an Ethernet interface is initialized successfully:
# ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1180 (1.1 KiB) TX bytes:689 (689.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=255 time=15.418 ms
64 bytes from 8.8.8.8: seq=1 ttl=255 time=0.701 ms
64 bytes from 8.8.8.8: seq=2 ttl=255 time=0.558 ms
64 bytes from 8.8.8.8: seq=3 ttl=255 time=1.122 ms
If you don't configure Buildroot with BR2_SYSTEM_DHCP=eth0
option, then
you will to initialize an network device manually after Linux is booted:
# ifconfig eth0 up
# udhcpc
udhcpc: started, v1.35.0
udhcpc: broadcasting discover
udhcpc: broadcasting select for 10.0.2.15, server 10.0.2.2
udhcpc: lease of 10.0.2.15 obtained from 10.0.2.2, lease time 86400
deleting routers
adding dns 10.0.2.3
Using SSH¶
You can connect to the Linux kernel through SSH using a custom port 2022
(it is forwarded to 22 port inside of QEMU machine). To add SSH server to the
Linux image use BR2_PACKAGE_OPENSSH=y
and BR2_PACKAGE_HAVEGED=y
options for Buildroot:
Run Linux and create a user user
and crate a home directory for the user:
Here is an example for connecting to the Linux using SSH:
Networking in QEMU Using TUN/TAP Network Interface¶
TUN/TAP network interface allows interacting of the target with your host in both directions. For example, you can mount host’s NFS directories inside of the target.
Configure TUN/TAP interface on host’s side (choose your own IP address instead of 10.42.0.1
):
Run QEMU
qemu-system-arc -M virt -cpu archs -m 2G -display none -nographic -monitor none -kernel vmlinux \
-netdev tap,id=net0,ifname=tap1,script=no,downscript=no -device virtio-net-device,netdev=net0
Configure a network interface on target's side:
After that you can connect to any Linux service without port forwarding. Here is an example of connecting to the Linux using SSH with TUN/TAP interface configured:
Mounting an External Filesystem Image¶
It's possible to run Linux with an external filesystem image. Firstly,
turn off linking an initial RAM filesystem into Linux kernel (BR2_TARGET_ROOTFS_INITRAMFS=n
)
and add an option for building Ext2 filesystem image (BR2_TARGET_ROOTFS_EXT2=y
) in Buildroot:
Filesystem images -> [*] ext2/3/4 root filesystem
-> [ ] initial RAM filesystem linked into linux kernel
Run the Linux kernel and initialize and external storage:
qemu-system-arc -M virt -cpu archs -m 2G -display none -nographic -monitor none -kernel vmlinux \
-append "root=/dev/vda ro" -drive file=images/rootfs.ext2,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0
Mounting a Shared Folder¶
If you need shared folder access, add the following arguments to QEMU's command line:
And the on target's side:
Target will see contents on your directory as if it's a FAT partition on some drive without symbolic links, special attributes, etc. Target may do changes to the contents of this folder (with read/write permissions above). Host must not do any changes to the folder while target is using this shared folder, otherwise things will go seriously wrong (QEMU creates FAT table on start and then it's target which manipulates it but not host).
Mounting NFS Folder¶
Install and configure NFS on CentOS or Fedora:
# For CentOS 7
sudo yum install nfs-utils
# For Fedora
sudo dnf install nfs-utils
# Enable services and add rules for firewall:
sudo systemctl enable --now rpcbind nfs-server
sudo firewall-cmd --add-service=nfs --permanent
sudo firewall-cmd --reload
Install and configure NFS on Ubuntu:
Then you need to configure NFS directory for sharing. For example,
it's /nfs
directory and the current user owns it. Add this line to
/etc/exports
(you can find anonuid
and anongid
for your user using id -u
and id -g
respectively):
Update the table of exported NFS file systems:
Then enable NFS in you Buildroot configuration using configuration
menu (it corresponds to BR2_PACKAGE_NFS_UTILS=y
):
Run the Linux image with network interface enabled (use your own path
for vmlinux
images for HS3x/4x targets or loader
image for HS5x/6x targets):
qemu-system-arc -M virt -cpu archs -m 2G -display none -nographic -monitor none \
-kernel images/vmlinux -device virtio-rng-pci -netdev user,id=net0 \
-device virtio-net-device,netdev=net0
Create a directory for mounting the shared folder in guest system:
Configure the network interface in guest system:
# udhcpc
udhcpc: started, v1.36.1
udhcpc: broadcasting discover
udhcpc: broadcasting select for 10.0.2.15, server 10.0.2.2
udhcpc: lease of 10.0.2.15 obtained from 10.0.2.2, lease time 86400
deleting routers
adding dns 10.0.2.3
Mount the shared folder: