This page discusses how to run a Raspberry Pi filesystem on a PC. The examples will focus on Raspberry Pi OS, but the process should work for any similar OS.

Step 1: Create your directory tree

First, you need to make a directory containing your Raspberry Pi system. You can either untar a root tarball into an existing filesystem, download a disk image and mount its filesystem, or use an existing SD card.

Option 1.1: Use a root tarball

This option is recommended if you just need to run programs on your computer (e.g. when cross-compiling). It's the easiest option, but doesn't leave you with a disk image you can copy back to an SD card.

Go to the Raspberry Pi download index (or equivalent for your OS) and click on the directory you want (e.g. raspios_lite_armhf). Download a file called something like root.tar.xz (usually one of the largest files in the directory), then do:

mkdir rpi
sudo tar -C rpi -xf /path/to/your/root.tar.xz

Create a root tarball from a disk image

As of June 2025, downloads.raspberrypi.org only provides root tarballs for bullseye (oldstable). To create a root tarball for bookworm (stable), you will need to extract the files from a disk image.

Go to the Raspberry Pi download index (or equivalent for your OS) and click on the directory you want (e.g. raspios_lite_armhf). Then click images/, then the directory with the most recent date. Download the largest file in that directory (should end with .img.xz), then do:

# Create a variable to make the next few steps easier to type:
IMAGE_FILENAME=<image-filename>.img

# Decompress your disk image:
unxz "$IMAGE_FILENAME".xz

# Loopback-mount your disk image:
sudo losetup -f -P --show "$IMAGE_FILENAME"
# This should print "/dev/loop0".  If it says e.g. "/dev/loop1" instead,
# change the references to "/dev/loop0" in the instructions below.

# Mount the partitions:
mkdir -p rpi
sudo mount /dev/loop0p2 -o ro rpi
sudo mount /dev/loop0p1 -o rw rpi/boot

# Create the tarball:
sudo tar -C rpi -zcf /path/to/your/root.tar.gz .

# Unmount the partitions and the disk image:
sudo umount rpi/boot rpi
sudo losetup -d /dev/loop0

# Optionally delete the disk image:
rm "$IMAGE_FILENAME"

Option 1.2: Use a disk image

This option is recommended if you need to modify an actual disk image (e.g. to configure an image before you run it on a real Pi).

Download your disk image, e.g. from the Raspberry Pi Foundation or the Raspberry Pi download index. Then do:

# Make sure you have installed all necessary packages:
sudo apt install -y unzip sfdisk

# Decompress your disk image:
unzip /path/to/your/raspios.zip

# You shouldn't need the zip file again:
rm /path/to/your/raspios.zip

# Create a variable to make the next few steps easier to type:
IMAGE_FILENAME=<unzipped-filename>.img

# Optionally resize your disk image and the main partiton:
# (see `man truncate` and `man sfdisk` for details):
truncate -s +1G "$IMAGE_FILENAME"
echo "- +" | /usr/sbin/sfdisk -N 2 "$IMAGE_FILENAME"

# Loopback-mount your disk image:
sudo losetup -f -P --show "$IMAGE_FILENAME"
# This should print "/dev/loop0".  If it says e.g. "/dev/loop1" instead,
# change the references to "/dev/loop0" in the instructions below.

# If you resized your disk image before, do:
sudo resize2fs /dev/loop0p2

# Optional: Check the filesystem with e2fsck
sudo e2fsck -f /dev/loop0p2

# Mount the partitions:
mkdir -p rpi
sudo mount /dev/loop0p2 -o rw rpi
sudo mount /dev/loop0p1 -o rw rpi/boot

Option 1.3: Use an actual SD card

This option is recommended if you need to make changes to a running device (e.g. to run an overnight upgrade for a device you normally leave off), or for distributions that don't support the other options (e.g. OSMC).

Download and install your disk image on the SD card in the normal way, plug it in your Raspberry Pi and boot it up.

When you're ready to use the SD card in your PC, shut the Pi down, remove its SD card and prepare to plug it in to your PC. Then do:

# Make sure your SD card is not plugged in, then do:
ls /dev/disk/by-id/* | grep -v -- '-part[0-9]*$' | tee /tmp/disks.txt

# Plug your SD card in, then do:
ls /dev/disk/by-id/* | grep -v -- '-part[0-9]*$' | diff /tmp/disks.txt -
# You should see something like:
# 10a11
# > /dev/disk/by-id/<identifier-of-your-card>

# Make a variable with the device from the previous command:
DEVICE_TO_MOUNT=/dev/disk/by-id/<identifier-of-your-card>

# Mount the card's partitions:
mkdr rpi
sudo mount "$DEVICE_TO_MOUNT"-part2 rpi
sudo mount "$DEVICE_TO_MOUNT"-part1 rpi/boot

Step 2: Start your system

Once you have a directory with a system on it, you need to start a new process that thinks that directory it the root of the directory tree. You can do that with either a traditional chroot command, or with a more modern systemd-nspawn command.

Option 2.1: Use a traditional chroot

chroot is the traditional way to run commands in a different filesystem namespace. It's widely available, even on older Linux systems.

Follow the steps in QemuUserEmulation to get cross-architecture binaries running transparently. Then do:

# make some important filesystems available:
sudo mount --bind /dev rpi/dev
sudo mount --bind /sys rpi/sys
sudo mount --bind /proc rpi/proc
sudo mount --bind /dev/pts rpi/dev/pts

# chroot in:
sudo chroot rpi bin/bash

Option 2.2: Use a systemd container

systemd-nspawn is available on modern Linux systems, and does a better job of isolating the environment from your host system.

Follow the steps in QemuUserEmulation to get cross-architecture binaries running transparently. Then do:

# Ensure the systemd-container package is available:
sudo apt install -y systemd-container

sudo systemd-nspawn -D /mnt bin/bash

If you have an issue with Internet connectivity, exit and remove rpi/resolv.conf. Systemd will recreate the file when your run systemd-nspawn again.

Step 3: Use your system

The shell you created in the previous step should act like any normal terminal. Here are some ideas to get you started using it.

Run raspi-config

Raspberry Pi OS expects you to run raspi-config shortly after installation. Run that now and fill out any relevant options. It's especially useful to run Localisation Options > L1 Locale and Localisation Options > L2 Timezone so that aptwill download from a better mirror.

Remove the desktop environment

For example, make it a slim server:

sudo apt-get remove -y --dry-run --auto-remove --purge libx11-.*

Make sure the package list is sane, then run again without --dry-run.

Step 4: Clean up

When you've finished with your chroot, exit the shell (e.g. with the exit command), then do:

# Will complain about some directories that aren't mount points:
sudo umount -R rpi/*

# Only if you chose options 1.2 or 1.3:
sudo umount rpi

# Only if you chose option 1.2:
sudo losetup -d /dev/loop0

If you chose option 1.2, your disk image should now be ready to flash. Or if you chose option 1.3, you should be able to remove your SD card and run plug it back in to your Pi.

See also