diff --git a/vmbase/example/src/main.rs b/vmbase/example/src/main.rs
index bb64651..df81b2b 100644
--- a/vmbase/example/src/main.rs
+++ b/vmbase/example/src/main.rs
@@ -20,6 +20,7 @@
 
 mod exceptions;
 mod layout;
+mod pci;
 
 extern crate alloc;
 
@@ -27,17 +28,18 @@
     bionic_tls, dtb_range, print_addresses, rodata_range, stack_chk_guard, text_range,
     writable_region, DEVICE_REGION,
 };
-use aarch64_paging::{
-    idmap::IdMap,
-    paging::{Attributes, MemoryRegion},
-};
+use crate::pci::{check_pci, pci_node, PciMemory32Allocator};
+use aarch64_paging::{idmap::IdMap, paging::Attributes};
 use alloc::{vec, vec::Vec};
 use buddy_system_allocator::LockedHeap;
 use core::ffi::CStr;
 use libfdt::Fdt;
-use log::{info, LevelFilter};
+use log::{debug, info, LevelFilter};
 use vmbase::{logger, main, println};
 
+/// PCI MMIO configuration region size.
+const AARCH64_PCI_CFG_SIZE: u64 = 0x1000000;
+
 static INITIALISED_DATA: [u32; 4] = [1, 2, 3, 4];
 static mut ZEROED_DATA: [u32; 10] = [0; 10];
 static mut MUTABLE_DATA: [u32; 4] = [1, 2, 3, 4];
@@ -62,7 +64,27 @@
     assert_eq!(arg0, dtb_range().start.0 as u64);
     check_data();
     check_stack_guard();
-    check_fdt();
+
+    info!("Checking FDT...");
+    let fdt = dtb_range();
+    let fdt =
+        unsafe { core::slice::from_raw_parts_mut(fdt.start.0 as *mut u8, fdt.end.0 - fdt.start.0) };
+    let fdt = Fdt::from_mut_slice(fdt).unwrap();
+    info!("FDT passed verification.");
+    check_fdt(fdt);
+
+    let pci_node = pci_node(fdt);
+    // Parse reg property to find CAM.
+    let pci_reg = pci_node.reg().unwrap().unwrap().next().unwrap();
+    debug!("Found PCI CAM at {:#x}-{:#x}", pci_reg.addr, pci_reg.addr + pci_reg.size.unwrap());
+    // Check that the CAM is the size we expect, so we don't later try accessing it beyond its
+    // bounds. If it is a different size then something is very wrong and we shouldn't continue to
+    // access it; maybe there is some new version of PCI we don't know about.
+    assert_eq!(pci_reg.size.unwrap(), AARCH64_PCI_CFG_SIZE);
+    // Parse ranges property to find memory ranges from which to allocate PCI BARs.
+    let mut pci_allocator = PciMemory32Allocator::for_pci_ranges(&pci_node);
+
+    modify_fdt(fdt);
 
     unsafe {
         HEAP_ALLOCATOR.lock().init(HEAP.as_mut_ptr() as usize, HEAP.len());
@@ -93,6 +115,21 @@
             Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::EXECUTE_NEVER,
         )
         .unwrap();
+    idmap
+        .map_range(
+            &dtb_range().into(),
+            Attributes::NORMAL
+                | Attributes::NON_GLOBAL
+                | Attributes::READ_ONLY
+                | Attributes::EXECUTE_NEVER,
+        )
+        .unwrap();
+    idmap
+        .map_range(
+            &pci_allocator.get_region(),
+            Attributes::DEVICE_NGNRE | Attributes::EXECUTE_NEVER,
+        )
+        .unwrap();
 
     info!("Activating IdMap...");
     info!("{:?}", idmap);
@@ -101,6 +138,8 @@
 
     check_data();
     check_dice();
+
+    check_pci(pci_reg, &mut pci_allocator);
 }
 
 fn check_stack_guard() {
@@ -144,13 +183,7 @@
     info!("Data looks good");
 }
 
-fn check_fdt() {
-    info!("Checking FDT...");
-    let fdt = MemoryRegion::from(layout::dtb_range());
-    let fdt = unsafe { core::slice::from_raw_parts_mut(fdt.start().0 as *mut u8, fdt.len()) };
-
-    let reader = Fdt::from_slice(fdt).unwrap();
-    info!("FDT passed verification.");
+fn check_fdt(reader: &Fdt) {
     for reg in reader.memory().unwrap().unwrap() {
         info!("memory @ {reg:#x?}");
     }
@@ -161,8 +194,9 @@
         let reg = c.reg().unwrap().unwrap().next().unwrap();
         info!("node compatible with '{}' at {reg:?}", compatible.to_str().unwrap());
     }
+}
 
-    let writer = Fdt::from_mut_slice(fdt).unwrap();
+fn modify_fdt(writer: &mut Fdt) {
     writer.unpack().unwrap();
     info!("FDT successfully unpacked.");
 
diff --git a/vmbase/example/src/pci.rs b/vmbase/example/src/pci.rs
new file mode 100644
index 0000000..e4a4b04
--- /dev/null
+++ b/vmbase/example/src/pci.rs
@@ -0,0 +1,247 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Functions to scan the PCI bus for VirtIO device and allocate BARs.
+
+use aarch64_paging::paging::MemoryRegion;
+use alloc::alloc::{alloc, dealloc, Layout};
+use core::ffi::CStr;
+use libfdt::{Fdt, FdtNode, Reg};
+use log::{debug, info};
+use virtio_drivers::{
+    pci::{
+        bus::{BarInfo, Cam, Command, DeviceFunction, MemoryBarType, PciRoot},
+        virtio_device_type, PciTransport,
+    },
+    DeviceType, Hal, PhysAddr, Transport, VirtAddr, VirtIOBlk, PAGE_SIZE,
+};
+
+/// The standard sector size of a VirtIO block device, in bytes.
+const SECTOR_SIZE_BYTES: u64 = 512;
+
+/// Finds an FDT node with compatible=pci-host-cam-generic.
+pub fn pci_node(fdt: &Fdt) -> FdtNode {
+    fdt.compatible_nodes(CStr::from_bytes_with_nul(b"pci-host-cam-generic\0").unwrap())
+        .unwrap()
+        .next()
+        .unwrap()
+}
+
+pub fn check_pci(reg: Reg<u64>, allocator: &mut PciMemory32Allocator) {
+    let mut pci_root = unsafe { PciRoot::new(reg.addr as *mut u8, Cam::MmioCam) };
+    for (device_function, info) in pci_root.enumerate_bus(0) {
+        let (status, command) = pci_root.get_status_command(device_function);
+        info!("Found {} at {}, status {:?} command {:?}", info, device_function, status, command);
+        if let Some(virtio_type) = virtio_device_type(&info) {
+            info!("  VirtIO {:?}", virtio_type);
+            allocate_bars(&mut pci_root, device_function, allocator);
+            let mut transport =
+                PciTransport::new::<HalImpl>(&mut pci_root, device_function).unwrap();
+            info!(
+                "Detected virtio PCI device with device type {:?}, features {:#018x}",
+                transport.device_type(),
+                transport.read_device_features(),
+            );
+            instantiate_virtio_driver(transport, virtio_type);
+        }
+    }
+}
+
+fn instantiate_virtio_driver(transport: impl Transport, device_type: DeviceType) {
+    if device_type == DeviceType::Block {
+        let blk = VirtIOBlk::<HalImpl, _>::new(transport).expect("failed to create blk driver");
+        info!("Found {} KiB block device.", blk.capacity() * SECTOR_SIZE_BYTES / 1024);
+    }
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+struct PciMemoryFlags(u32);
+
+impl PciMemoryFlags {
+    pub fn prefetchable(self) -> bool {
+        self.0 & 0x80000000 != 0
+    }
+
+    pub fn range_type(self) -> PciRangeType {
+        PciRangeType::from((self.0 & 0x3000000) >> 24)
+    }
+}
+
+/// Allocates 32-bit memory addresses for PCI BARs.
+pub struct PciMemory32Allocator {
+    start: u32,
+    end: u32,
+}
+
+impl PciMemory32Allocator {
+    /// Creates a new allocator based on the ranges property of the given PCI node.
+    pub fn for_pci_ranges(pci_node: &FdtNode) -> Self {
+        let mut memory_32_address = 0;
+        let mut memory_32_size = 0;
+        for range in pci_node
+            .ranges::<u128, u64, u64>()
+            .expect("Error getting ranges property from PCI node")
+            .expect("PCI node missing ranges property.")
+        {
+            let flags = PciMemoryFlags((range.addr >> 64) as u32);
+            let prefetchable = flags.prefetchable();
+            let range_type = flags.range_type();
+            let bus_address = range.addr as u64;
+            let cpu_physical = range.parent_addr;
+            let size = range.size;
+            info!(
+                "range: {:?} {}prefetchable bus address: {:#018x} host physical address: {:#018x} size: {:#018x}",
+                range_type,
+                if prefetchable { "" } else { "non-" },
+                bus_address,
+                cpu_physical,
+                size,
+            );
+            if !prefetchable
+                && ((range_type == PciRangeType::Memory32 && size > memory_32_size.into())
+                    || (range_type == PciRangeType::Memory64
+                        && size > memory_32_size.into()
+                        && bus_address + size < u32::MAX.into()))
+            {
+                // Use the 64-bit range for 32-bit memory, if it is low enough.
+                assert_eq!(bus_address, cpu_physical);
+                memory_32_address = u32::try_from(cpu_physical).unwrap();
+                memory_32_size = u32::try_from(size).unwrap();
+            }
+        }
+        if memory_32_size == 0 {
+            panic!("No PCI memory regions found.");
+        }
+
+        Self { start: memory_32_address, end: memory_32_address + memory_32_size }
+    }
+
+    /// Gets a memory region covering the address space from which this allocator will allocate.
+    pub fn get_region(&self) -> MemoryRegion {
+        MemoryRegion::new(self.start as usize, self.end as usize)
+    }
+
+    /// Allocates a 32-bit memory address region for a PCI BAR of the given power-of-2 size.
+    ///
+    /// It will have alignment matching the size. The size must be a power of 2.
+    pub fn allocate_memory_32(&mut self, size: u32) -> Option<u32> {
+        assert!(size.is_power_of_two());
+        let allocated_address = align_up(self.start, size);
+        if allocated_address + size <= self.end {
+            self.start = allocated_address + size;
+            Some(allocated_address)
+        } else {
+            None
+        }
+    }
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+enum PciRangeType {
+    ConfigurationSpace,
+    IoSpace,
+    Memory32,
+    Memory64,
+}
+
+impl From<u32> for PciRangeType {
+    fn from(value: u32) -> Self {
+        match value {
+            0 => Self::ConfigurationSpace,
+            1 => Self::IoSpace,
+            2 => Self::Memory32,
+            3 => Self::Memory64,
+            _ => panic!("Tried to convert invalid range type {}", value),
+        }
+    }
+}
+
+/// Allocates appropriately-sized memory regions and assigns them to the device's BARs.
+fn allocate_bars(
+    root: &mut PciRoot,
+    device_function: DeviceFunction,
+    allocator: &mut PciMemory32Allocator,
+) {
+    let mut bar_index = 0;
+    while bar_index < 6 {
+        let info = root.bar_info(device_function, bar_index).unwrap();
+        debug!("BAR {}: {}", bar_index, info);
+        // Ignore I/O bars, as they aren't required for the VirtIO driver.
+        if let BarInfo::Memory { address_type, size, .. } = info {
+            match address_type {
+                _ if size == 0 => {}
+                MemoryBarType::Width32 => {
+                    let address = allocator.allocate_memory_32(size).unwrap();
+                    debug!("Allocated address {:#010x}", address);
+                    root.set_bar_32(device_function, bar_index, address);
+                }
+                MemoryBarType::Width64 => {
+                    let address = allocator.allocate_memory_32(size).unwrap();
+                    debug!("Allocated address {:#010x}", address);
+                    root.set_bar_64(device_function, bar_index, address.into());
+                }
+                _ => panic!("Memory BAR address type {:?} not supported.", address_type),
+            }
+        }
+
+        bar_index += 1;
+        if info.takes_two_entries() {
+            bar_index += 1;
+        }
+    }
+
+    // Enable the device to use its BARs.
+    root.set_command(
+        device_function,
+        Command::IO_SPACE | Command::MEMORY_SPACE | Command::BUS_MASTER,
+    );
+    let (status, command) = root.get_status_command(device_function);
+    debug!("Allocated BARs and enabled device, status {:?} command {:?}", status, command);
+}
+
+const fn align_up(value: u32, alignment: u32) -> u32 {
+    ((value - 1) | (alignment - 1)) + 1
+}
+
+struct HalImpl;
+
+impl Hal for HalImpl {
+    fn dma_alloc(pages: usize) -> PhysAddr {
+        debug!("dma_alloc: pages={}", pages);
+        let layout = Layout::from_size_align(pages * PAGE_SIZE, PAGE_SIZE).unwrap();
+        // Safe because the layout has a non-zero size.
+        let vaddr = unsafe { alloc(layout) } as VirtAddr;
+        Self::virt_to_phys(vaddr)
+    }
+
+    fn dma_dealloc(paddr: PhysAddr, pages: usize) -> i32 {
+        debug!("dma_dealloc: paddr={:#x}, pages={}", paddr, pages);
+        let vaddr = Self::phys_to_virt(paddr);
+        let layout = Layout::from_size_align(pages * PAGE_SIZE, PAGE_SIZE).unwrap();
+        // Safe because the memory was allocated by `dma_alloc` above using the same allocator, and
+        // the layout is the same as was used then.
+        unsafe {
+            dealloc(vaddr as *mut u8, layout);
+        }
+        0
+    }
+
+    fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
+        paddr
+    }
+
+    fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr {
+        vaddr
+    }
+}
