Internal Speaker Of OneXPlayer 2 Pro (8840) In Linux
Background
Internal speaker of OneXPlayer 2 Pro doesn't work. There is a long thread discussing this issue. From this thread, it seems that the AMP isn't initialized correctly. Someone found that the speaker works after rebooting from Windows. So I came out an idea: What if initializing the AMP with Windows in a virtual machine.
PCI passthrough
To let Windows initialize the AMP, I must let the virtual machine access the hardware directly. This will need VFIO
driver in the Linux
kernel. I unbind the hardware from snd_hda_intel
driver, then bind the hardware to vfio-pci
driver. After that, the virtual machine can use the hardware.
PCI slot name
Firstly, I should find out the name of the pci slot connected by the audio device.
# lspci -D: always print domain numbers
# grep -i audio: show only audio related hardware
# grep -v Radeon: remove the hdmi audio device
lspci -D|grep -i audio|grep -v Radeon
The output is like:
0000:64:00.6 Audio device: Advanced Micro Devices, Inc. [AMD] Family 17h/19h HD Audio Controller
0000:64:00.6
is the pci slot name.
Bind/unbind vfio-pci
driver
- bind
echo '0000:64:00.6' | sudo tee /sys/bus/pci/drivers/vfio-pci/unbind
echo '0000:64:00.6' | sudo tee /sys/bus/pci/drivers/snd_hda_intel/bind
- unbind
echo '0000:64:00.6' | sudo tee /sys/bus/pci/drivers/snd_hda_intel/unbind
echo '0000:64:00.6' | sudo tee /sys/bus/pci/drivers/vfio-pci/bind
Create a virtual device with the Windows
partition
In the previous research, I found that the internal speaker won't work in a new Windows
too. But I have the original Windows
partition. Each time I installed Linux
on a new machine, I would keep the Windows
partition not touching. After some researches, I finally start a vm with the Windows
partition. Avoiding to mass the original Windows
partition, I used dd
to clone the partition.
# I have shrinked the size of the partition to 89GB.
dd if=/dev/nvme0n1p3 of=/var/cache/oxp2p-win11.img
Keep the partition layout
I kept the partition layout of the Windows
partition and partitions before it to avoid any implicit issue.
- Use the following command to print the layout.
fdisk -l /dev/nvme0n1
The output is like:
/dev/nvme0n1p1 2048 206847 204800 100M EFI System
/dev/nvme0n1p2 206848 468991 262144 128M Microsoft reserved
/dev/nvme0n1p3 468992 187191295 186722304 89G Microsoft basic data
A sector equals to 512 bytes.
- Create an image to simulate those two partitions before the
Windows
partition.
dd if=/dev/zero of=part1.img bs=512 count=468992
- Create an image for margin after the
Windows
partition.
dd if=/dev/zero of=part3.img bs=1M count=100
I don't know why. But it seems there should be some addtitional spaces after the Windows
partition.
- Create a device mapper.
Use losetup
to set the image file as a block device, and then use dmsetup
to create a mapper.
loop1_file=part1.img
loop2_file=/var/cache/oxp2p-win11.img
loop3_file=part3.img
disk_name=oxp2p-win11
loop1=$(sudo losetup -f)
sudo losetup $loop1 $loop1_file
loop1_size=$(sudo blockdev --getsz $loop1)
loop2=$(sudo losetup -f)
sudo losetup $loop2 $loop2_file
loop2_size=$(sudo blockdev --getsz $loop2)
loop3=$(sudo losetup -f)
sudo losetup $loop3 $loop3_file
loop3_size=$(sudo blockdev --getsz $loop3)
sudo dmsetup create $disk_name <<EOF
0 $loop1_size linear $loop1 0
$loop1_size $loop2_size linear $loop2 0
$(expr $loop1_size + $loop2_size) $loop3_size linear $loop3 0
EOF
Run with qemu
- Create an empty file for persisting UEFI variables
dd if=/dev/zero conv=sync bs=1M count=4 of=ovmf_vars.fd
- Run with qemu
# The path of /usr/share/edk2/x64/OVMF_CODE.4m.fd will be different in different distro.
# This should be run after binding the `vfio-pci` driver.
qemu-system-x86_64 -m 4096M -smp 4 -accel kvm -cpu host -drive file=/usr/share/edk2/x64/OVMF_CODE.4m.fd,if=pflash,format=raw,readonly=on -drive file=./ovmf_vars.fd,if=pflash,format=raw -drive file=/dev/mapper/oxp2p-win11,media=disk,format=
raw -device usb-ehci -device usb-kbd -device usb-mouse -device usb-tablet -usb -monitor stdio -device vfio-pci,host=64:00.6
- Force closing the vm after the sound came out in the login screen.
- Unbind the
vfio-pci
driver.
Advance(hda-verb)
TO BE CONTINUED