Wow, I can’t believe it has been over two years since I last wrote about Android’s for of the QEMU emulator. Turns out there have been some changes since I last looked at it.
The most important is that the Android emulator no longer has a
fixed layout of devices in the physical memory address space. So,
while it may have previously been the case that the event device was
always at 0xff007000, now it might be at
0xff008000, or 0xff009000, depending on what
other devices have been configured for a particular device
configuration.
Now, if a device may exist at some random physical address, how
does the OS know how to setup the devices drivers? Well, as I’m
sure you’ve guessed, the addresses and really random, they
are located at page-offset addresses through a restricted range of
memory. OK, so how does the OS know what the range is? Well, there is
the goldfish_device_bus device.
Basically, this device provides a mechanism to enumerate the
devices on the bus. The driver writes PDEV_BUS_OP_INIT to
the PDEV_BUS_OP register, the
goldfish_device_bus then raises an interrupt. The driver
the reads the PDEV_BUS_OP register. Each time the value
is PDEV_BUS_OP_ADD_DEV, the driver can read the other
registers such as PDEV_BUS_IO_BASE,
PDEV_BUS_IO_SIZE, PDEV_BUS_IRQ, to determine
the properties of the new device. It continues doing this until it
reads a PDEV_BUS_OP_DONE, which indicates the bus scan
has finished.
The driver can determine what type of device it has found by
writing a pointer to the PDEV_BUS_GET_NAME register. When
this happens the device writes an the device’s name (as an ASCII
string) to the pointer.
Linux uses these strings to perform device to driver matching as described in the Platform Devices and Drivers document.