OpenWrt on x86 hardware (PC / VM / server)

See also: OpenWrt on UEFI based x86 systems

OpenWrt can run in normal PC, VM, or server hardware, and take advantage of the much more powerful hardware the x86 (Intel/AMD) architecture can offer.

Go here, select a release, then click on x86.

You will see multiple targets:

TargetDescription
64Select this one unless you have good reasons not to.
For PC hardware released after ~2007.
genericFor 32-bit-only (“i686”) hardware (either old hardware or some Atom processors). Will work on Pentium 4 and later.
Use this only if your hardware can't run the 64-bit version.
legacyFor very old PC hardware, Pentium MMX, (“i586”).
Lacks many features available on modern hardware, like multi-core support and support for more than 4GB of RAM, but will actually run on ancient hardware, while other versions will not.
geodeA custom legacy target for Geode SoCs, which are still in use in many aging networking devices, like the older Alix boards from PCEngines.

Once a target is selected, select a disk image:

ext4-combined-efi.img.gzSelect this one unless you have a reason to use a different one.
This disk image uses a read-write ext4 root partition, which can be expanded to fill a large drive.
Features like Failsafe Mode or Factory Reset will not be available, as those features require a read-only squashfs root partition to function.
It has a UEFI boot partition, a root partition, and a Master Boot Record (MBR).
ext4-combined.img.gzThis disk image is the same as above, but it is intended to be BIOS booted instead of UEFI.
ext4-rootfs.img.gzThis is a partition image of only the root partition.
It can be used to install OpenWRT without overwriting the boot partition and Master Boot Record (MBR).
squashfs-combined-efi.img.gzThis disk image uses the traditional OpenWrt layout--a squashfs read-only root filesystem, and a read-write partition where settings and packages are stored.
Due to how this image is assembled, there will be less than 100MB of free space to store additional packages and configuration, and extroot does not work. It supports booting from UEFI.
squashfs-combined.img.gzSame as squashfs-combined-efi.img.gz, but is intended to be BIOS booted.
rootfs.tar.gzThis contains all the files from the root partition. It can be extracted onto a root filesystem without overwriting the partition. To avoid conflicts, it is highly recommended to backup any older files and extract this file onto an empty filesystem.

All images support basic video output (screen text terminal), so a screen can be connected to a video port on the device to watch it boot up.

Some images support keyboard input, which can be used to configure OpenWrt directly.

To communicate over serial, a “null-modem” or “crossed” serial cable is required to connect the device's serial port to another PC's serial port.

To be able to connect to the device over the network, the image must support the device's Ethernet hardware.

  • The 64-bit image supports Intel and Realtek Ethernet chipsets.
  • The Generic and Legacy images support Intel, Realtek, Via and some other ethernet chipsets.
  • The Geode images support Geode hardware for Geode-based boards.

NVMe SSD support is available since OpenWrt 21.02.

WARNING! Users with more than a single block device are likely affected by a critical data loss bug. Read the details in Issue#20426 before flashing a new image to avoid potential data loss!

OpenWrt has a minimalist philosophy regarding packaging strategy due to limited space on embedded devices. For many x86 machines, disk space is likely not a limiting factor. Users coming from desktop distros where thousand of modules are provided in the default image might be surprised to see that on OpenWrt, the default number of drivers is also minimal. Therefore, it may be necessary to identify and obtain the needed modules for things like: storage controllers (SATA/USB etc.), sound module, crypto modules, video modules, etc.

One strategy to identify needed modules is to boot into a live Linux distro (for example Arch Linux) and inspect the output of lsmod or lspci -vvv | grep driver and then search for corresponding OpenWrt kmod packages.

Another option if building your own image is to build all modules with ALL_KMODS=y and see what works. Newer hardware may not be supported out-of-the-box.

Beyond the kernel modules, some common packages to consider installing on x86 are listed below:

Installation consists of writing the raw disk image to the drive.
It may be a USB flash drive, a USB SD card reader with an SD card in it, a SATA hard drive, or an SSD (recommended).
It can be done from a secondary PC, or by booting the router machine using a Live CD/USB.

The installation procedure differs depending on the OS used to write the raw disk image, due to different tools being available.

Be sure to select the correct drive -- Writing the raw image file will DELETE content on the drive.

In general, two programs are required:

  • one to extract the raw disk image from the compressed archive
  • another to write the raw disk image to the OpenWrt drive.

File Archiver:

Disk Flash Utility:

File Archiver:

A straight forward method involves imaging the target device from a Live Linux environment such as Arch Linux.

# obtain the desired image
wget https://downloads.openwrt.org/snapshots/targets/x86/64/openwrt-x86-64-generic-squashfs-combined-efi.img.gz
 
# Unpack image
gzip -d openwrt-x86-64-generic-squashfs-combined-efi.img.gz
 
# Identify the target disk intended to be used for the installation
lsblk -f
 
# Write image
# Note1 that you are targeting the BLOCK DEVICE not an individual partition e.g. /dev/sdx not /dev/sdx1
# Note2 your device might not be a SATA disk (sdx), it could be many others such as nvme0n1 or mmcblk0 etc.
dd if=openwrt-x86-64-generic-squashfs-combined-efi.img of=/dev/xxx
 
# Reboot into OpenWrt
reboot

If you want to write OpenWrt in SATA or IDE drives or CF Cards or SD cards, you can just remove them from the device and flash the image raw from your PC. Also sometimes eMMC is removable or can be put in “usb write mode” in some devices.

But if you cannot remove the storage from the device (or do not have an adapter to connect them to the PC), you can write OpenWrt on a USB drive (or another removable storage device), then you can then insert it in a USB port or slot. When booting select the drive where you installed OpenWrt.

Then you need to identify how is the internal storage device called with lsblk or dmesg:

opkg update
opkg install lsblk
lsblk
dmesg | grep -e sd

Be aware that you will also see the USB drive or the storage device you have temporarily installed OpenWrt on.

This for example is the output of a 4GB USB drive with 2 partitions on it that was assigned the name /dev/sda:

[    2.807590] sd 4:0:0:0: [sda] 7839744 512-byte logical blocks: (4.01 GB/3.74 GiB)
[    2.808703] sd 4:0:0:0: [sda] Write Protect is off
[    2.808754] sd 4:0:0:0: [sda] Mode Sense: 23 00 00 00
[    2.809827] sd 4:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[    2.814991]  sda: sda1 sda2
[    2.818338] sd 4:0:0:0: [sda] Attached SCSI removable disk

After you have identified the onboard storage you want to install OpenWrt in, you can follow the Linux install instructions above. Then power off the system, unplug the removable storage device you used to install OpenWrt, and power on again. Now it should boot from the internal storage.

The x86 image is using the following partition layout (as seen from inside of the device):

  1. /dev/sda1 is a 16MB ext4 /boot partition where GRUB and the kernel are stored.
  2. /dev/sda2 is a 104MB partition containing the squashfs root filesystem and a read-write f2fs filesystem OR the ext4 root filesystem (depending on what image you have chosen).

Any additional space in the device is unallocated.

See also automated script on: Expanding root partition and filesystem.

When installing OpenWrt on a VM, be sure to expand the underlying disk image before expanding the partition.

Use parted to fix the partition table, identify and expand the root partition.

# Install packages
opkg update
opkg install parted
 
# Identify disk name and partition number
parted -l -s
 
# Expand root partition
parted -f -s /dev/sda resizepart 2 100%
 
# Apply changes
reboot

Be sure to expand the underlying partition before expanding the filesystem.

It is possible to expand the root filesystem online while OpenWrt is booted. You can also perform this operation offline to reduce the chance of filesystem corruption.

Use losetup to map the root partition and resize2fs to expand the root filesystem.

# Install packages
opkg update
opkg install losetup resize2fs
 
# Map loop device to root partition
losetup /dev/loop0 /dev/sda2 2> /dev/null
 
# Expand root filesystem
resize2fs -f /dev/loop0
 
# Apply changes
reboot

You can also use fdisk to expand the root partition if parted does not work for you. The easiest way to do this is from the machine booted with a “live CD” distro like Finnix.

Here's an overview of the steps:

  1. Use fdisk to display the partition table. Notice the ~100MB root partition.
  2. Write down the starting sector address of the root partition (Usually /dev/sda2 or /dev/nvme0n1p2).
  3. Use fdisk to delete partition 2 but don't write the changes to disk yet.
  4. Use fdisk to create a new partition 2.
    1. choose/type the starting sector address you wrote down earlier (as by default it will try to place it somewhere else).
    2. leave the default end sector address (this will mean the partition will now use all available space).
  5. Write the partition table changes to disk.
    1. When it warns about partition signatures being present, type n to NOT remove the partition signature to proceed.
  6. Proceed with updating /boot/grub/grub.cfg with the new partition UUID

Example output:

Welcome to fdisk (util-linux 2.32).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): p
Disk /dev/sda: 7.2 GiB, 7751073792 bytes, 15138816 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xcbad8a62

Device     Boot Start    End Sectors  Size Id Type
/dev/sda1  *      512  33279   32768   16M 83 Linux
/dev/sda2       33792 246783  212992  104M 83 Linux

Command (m for help): d
Partition number (1,2, default 2): 

Partition 2 has been deleted.

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): 
Partition number (2-4, default 2): 
First sector (33280-15138815, default 34816): 33792
Last sector, +sectors or +size{K,M,G,T,P} (33792-15138815, default 15138815): 

Created a new partition 2 of type 'Linux' and of size 7.2 GiB.
Partition #2 contains a ext4 signature.

Do you want to remove the signature? [Y]es/[N]o: n

Command (m for help): w

The partition table has been altered.
Syncing disks.

Be aware that deleting and recreating the root partition can change its UUID. Make sure to update the root partition UUID in your GRUB configuration /boot/grub/grub.cfg in order for the system to be bootable.

# Update GRUB configuration
ROOT_BLK="$(readlink -f /sys/dev/block/"$(awk -e \
'$9=="/dev/root"{print $3}' /proc/self/mountinfo)")"
ROOT_DISK="/dev/$(basename "${ROOT_BLK%/*}")"
ROOT_DEV="/dev/${ROOT_BLK##*/}"
ROOT_UUID="$(partx -g -o UUID "${ROOT_DEV}" "${ROOT_DISK}")"
sed -i -r -e "s|(PARTUUID=)\S+|\1${ROOT_UUID}|g" /boot/grub/grub.cfg

When OpenWrt is installed on a x86 machine using generic-ext4-combined.img.gz, the drive's partition table is overwritten, which means that any existing partition is deleted. Any remaining space will be unallocated and the drive will have a normal MBR partition table.

Any partition management tool that supports MBR and ext4 can be used to create extra partitions on the drive, e.g. parted, fdisk.

But attention must be taken for future upgrades. If extra partitions are added, you cannot use -combined.img.gz images anymore, because writing this type of image will override the drive's partition table and delete any existing extra partition, and also revert boot and rootfs partitions back to default size.

On most embedded devices that run OpenWrt, upgrading is much simpler than the first installation and consists of simply executing the sysupgrade command. This holds true for the x86 platforms as well.

Use any of the usual sysupgrade, LuCI Attended Sysupgrade, owut or Firmware Selector tools for upgrading your x86 device. But:

Your first step is always...

Make a backup!

  • From LuCI, go to System → Backup/Flash firmware. Click Generate archive.
  • From CLI use sysupgrade --create-backup /tmp/backup.tar.gz and use scp or some other tool to copy the file to a safe location (usually another host).

Just do it. Every time...

The boot partition contains part of GRUB2 software, Linux kernel and grub.cfg with boot options. rootfs partition contains OpenWrt files, packages and configs.

At the moment, it's not built a separated image file with boot partition, as it's available for rootfs. To be able to upgrade boot partition without overriding the whole drive, we must extract it from ext4-combined.img.gz, this requires a spare empty drive or a virtual machine.

  1. Uncompress combined partitions image: gzip -d openwrt-19.07.8-x86-64-generic-ext4-combined.img.gz
  2. Write the image to the empty drive: dd if=openwrt-19.07.8-x86-64-generic-ext4-combined.img of=/dev/sdd (drive may be on sda, sdb, nvme0n1, etc)
  3. Extract boot partition image: dd if=/dev/sdd1 of=openwrt-19.07.8-x86-64-generic-ext4-boot.img

We will end up with the partition image openwrt-19.07.8-x86-64-generic-ext4-boot.img. Back to OpenWRT machine/drive, if the drive is on sdd and GRUB2 boot partition is on sdd1, we can write the updated image with dd if=openwrt-19.07.8-x86-64-generic-ext4-boot.img of=/dev/sdd1. Note we're here writing on the partition sdd1, not on the drive sdd.

As said above, there are 2 options for upgrading rootfs partition, when we are using the ext4 filesystem and not squashfs: writing ext4-rootfs.img.gz image or uncompressing rootfs.tar.gz into existing partition.

Writing ext4-rootfs.img.gz will delete any file on the partition. When using dd, it will preserve partition's actual size, it won't revert its size to image's.

  1. Uncompress rootfs image: gzip -d openwrt-19.07.8-x86-64-generic-ext4-rootfs.img.gz
  2. Write the image to the partition: dd if=openwrt-19.07.8-x86-64-generic-ext4-rootfs.img of=/dev/sdd2

For uncompressing rootfs.tar.gz, we must mount rootfs partition, delete all files from it, then uncompress updated files.

It may be tempting to not delete config files, but the risk isn't worth it, because some file may conflict and not be properly upgraded. It's safer to backup config files (as we should also backup whole drive before upgrading) and copy them back after upgrading. I suggest going further and having a Subversion repository on another computer where all config files are saved and their changes are tracked, and use rsync to sync between the repository working copy and production files on the router.

# mount rootfs partition, in this example it's on sdd2
mkdir /mnt/rootfs
mount -v /dev/sdd2 /mnt/rootfs
cd /mnt/rootfs
 
# delete all files on the partition
rm -Rf *
 
# copy rootfs.tar.gz here then uncompress it
tar -xvzf openwrt-19.07.8-x86-64-generic-rootfs.tar.gz
 
# wait for uncompress then delete the file
rm openwrt-19.07.8-x86-64-generic-rootfs.tar.gz

Anyone can compile OpenWrt from source, but it's a complex procedure with many options which require some experience, specially for using it on a production router.

Different from compiling, we can build our own custom image using the Image Builder. This doesn't compile the whole software, instead it downloads required packages from the same repository used by OpenWrt to install them. Image Builder builds the same image files used for installing and upgrading OpenWrt.

Due to that it's much simpler than compiling and offers great advantages, like adding directly to the image all packages we need, removing those we don't need, and also adding to it our config files. Having packages on the image, we don't need to reinstall all of them after an upgrade. And having our config files directly on the image, we don't need to reconfigure everything or copy all files from backup, which is specially difficult when default network configs don't work with our router's interfaces or it doesn't start with correct IP address. In many cases, OpenWrt will be back fully working on first boot after upgrading.

Another advantage for building a custom image is when the default rootfs partition size is too small to store all packages and we need to expand it. Note that, when following above procedures of installing then expanding partition and upgrading by writing partition image or extracting rootfs.tar.gz, we don't need to build the image with the final size of the partition. Doing so would result in the too large image file and would require enough RAM to store the whole file during building. It's recommended to use on the image just enough size to store all packages plus a small amount of free space.

Follow the Image Builder tutorial to setup the building environment using the x86/64 target. Once the building environment is setup, we use the make image command to build an image, which results on a set of files with the types of images described on this page. They are saved on bin/targets/x86/64 inside the building folder.

Because x86 hardware doesn't have profiles, we don't need to use the PROFILE parameter. With PACKAGES parameter we set all packages we want to add to or remove from default list. The command make info lists default packages list. FILES parameter is used to add custom config and script files to be added to the image, it points to a folder which represents root folder when OpenWrt is running.

For changing default partition sizes use parameters CONFIG_TARGET_KERNEL_PARTSIZE and CONFIG_TARGET_ROOTFS_PARTSIZE. We can either edit .config file on building folder or pass them directly to make image. Example CONFIG_TARGET_KERNEL_PARTSIZE=128 CONFIG_TARGET_ROOTFS_PARTSIZE=512.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2025/11/21 02:30
  • by dimmadont