Update the source code of the sample driver and reload it to the emulator instance.
The tasks include:
qemu_edu driver.qemu_edu driver.eductl_tool to verify the change.Do the following:
Stop the emulator instance:
tools/ffx emu stop
This command stops the currently running emulator instance.
Start a new instance of the Fuchsia emulator:
tools/ffx emu start workstation_eng.qemu-x64 --headless \ --kernel-args "driver_manager.use_driver_framework_v2=true" \ --kernel-args "driver_manager.root-driver=fuchsia-boot:///#meta/platform-bus.cm" \ --kernel-args "devmgr.enable-ephemeral=true"
This command starts a headless emulator instance running the Workstation prebuilt image.
Use a text editor to open the edu_device.cc file of the sample driver, for example:
nano src/qemu_edu/drivers/edu_device.cc
In the QemuEduDevice::HandleIrq function, between the line uint32_t factorial = mmio_->Read32(kFactorialComputationOffset); (Line 123) and the line FDF_SLOG(INFO, "Replying with", KV("factorial", factorial)); (Line 124), add the following line:
factorial=12345;
The function should look like below:
void QemuEduDevice::HandleIrq(async_dispatcher_t* dispatcher, async::IrqBase* irq, zx_status_t status, const zx_packet_interrupt_t* interrupt) { irq_.ack(); if (!pending_callback_.has_value()) { FDF_LOG(ERROR, "Received unexpected interrupt!"); return; } auto callback = std::move(*pending_callback_); pending_callback_ = std::nullopt; if (status != ZX_OK) { FDF_SLOG(ERROR, "Failed to wait for interrupt", KV("status", zx_status_get_string(status))); callback(zx::error(status)); return; } // Acknowledge the interrupt with the edu device. auto int_status = mmio_->Read32(kInterruptStatusRegisterOffset); mmio_->Write32(int_status, kInterruptAcknowledgeRegisterOffset); // Deassert the legacy INTx interrupt on the PCI bus. auto irq_result = pci_->AckInterrupt(); if (!irq_result.ok() || irq_result->is_error()) { FDF_SLOG(ERROR, "Failed to ack PCI interrupt", KV("status", irq_result.ok() ? irq_result->error_value() : irq_result.status())); callback(zx::error(ZX_ERR_IO)); return; } // Reply with the result. uint32_t factorial = mmio_->Read32(kFactorialComputationOffset); {{ '<strong>' }}factorial=12345;{{ '</strong>' }} FDF_SLOG(INFO, "Replying with", KV("factorial", factorial)); callback(zx::ok(factorial)); }
The function is now updated to always return the value of 12345.
Save the file and close the text editor.
Rebuild and run the modified sample driver:
tools/bazel run //src/qemu_edu/drivers:pkg.component
Run eductl_tool using fact and 12 as input:
tools/bazel run //src/qemu_edu/tools:pkg.eductl_tool -- fact 12
This command now prints output similar to the following:
$ tools/bazel run //src/qemu_edu/tools:pkg.eductl_tool -- fact 12 ... INFO: Build completed successfully, 1 total action Running workflow: pkg.eductl_tool_base Running task: pkg.debug_symbols_base (step 1/2) Running task: pkg.eductl_tool.run_base (step 2/2) added repository bazel.pkg.eductl.tool.runnable {{ '<strong>' }}Factorial(12) = 12345{{ '</strong>' }}
The last line shows that the qemu_edu driver replied with the hardcoded value of 12345 to eductl_tool.