andreiw / RaspberryPiPkg

DEPRECATED - DO NOT USE | Go here instead ->
https://github.com/tianocore/edk2-platforms/tree/master/Platform/RaspberryPi/RPi3
746 stars 143 forks source link

iPXE not working on Raspberry Pi 3 #121

Closed pojntfx closed 4 years ago

pojntfx commented 5 years ago

First of all: Thanks for this, it is incredibly awesome to use UEFI on ARM. I am now trying to use this to boot iPXE and I've been able to boot it with the following workflow:

# On Host

function edk2.get_sources() {
    git clone https://github.com/tianocore/edk2.git
    git clone https://github.com/tianocore/edk2-platforms.git
    git clone https://github.com/tianocore/edk2-non-osi.git
}

function edk2.start_container() {
    docker run --rm -it -w /home/edk2 -v $PWD/edk2:/home/edk2/edk2:z \
        -v $PWD/edk2-platforms:/home/edk2/edk2-platforms:z \
        -v $PWD/edk2-non-osi:/home/edk2/edk2-non-osi:z \
        -v $PWD/ccache:/home/edk2/.ccache:z \
        -v $PWD/Build:/home/edk2/Build:z \
        3mdeb/edk2 /bin/bash
}

# In Container

function edk2.install_dependencies() {
    echo "Password: edk2"
    sudo apt update
    sudo apt install gcc-aarch64-linux-gnu -y
}

function edk2.build_release() {
    export PACKAGES_PATH=$PWD/edk2:$PWD/edk2-platforms:$PWD/edk2-non-osi
    export WORKSPACE=$PWD
    . edk2/edksetup.sh
    make -C edk2/BaseTools
    getconf _NPROCESSORS_ONLN
    NUM_CPUS=$(($(getconf _NPROCESSORS_ONLN) + 2))
    GCC5_AARCH64_PREFIX=aarch64-linux-gnu- build -b RELEASE \
        -n $NUM_CPUS \
        -a AARCH64 \
        -t GCC5 \
        -p Platform/RaspberryPi/RPi3/RPi3.dsc
}

# On host
# Copy .fd to FAT32-formatted SD card
# Do https://github.com/tianocore/edk2-platforms/tree/master/Platform/RaspberryPi/RPi3#booting-the-firmware

# In container

function ipxe.get_sources() {
    git clone https://github.com/secumod/ipxe.git # to fix cross-compilation
    cd ipxe
    git checkout 71a1a807c0da8e49c9f2a7d9797a746a0dab7588
    cd ..
}

function ipxe.make() {
    cd ipxe/src
    make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 bin-arm64-efi/snp.efi
    cd ../..
}

function ipxe.package() {
    sudo cp ipxe/src/bin-arm64-efi/snp.efi Build/
}

I then copy the files as described to the SD card:

[pojntfx@pojntfx-x230-fedora efi]$ tree
.
├── bootcode.bin
├── config.txt
├── fixup.dat
├── RPI_EFI.fd
├── snp.efi
└── start.elf

0 directories, 6 files
[pojntfx@pojntfx-x230-fedora efi]$

I boot, select the EFI file from Boot Maintenance, and iPXE boots! It does however not find the interface; it show's No more network interfaces. Is this intentional, a problem with this implementation or a problem on iPXE's side? I found a hackernews comment, which led to a SMSC95xx driver that has been implemented into iPXE, so as far as I understand it (I'm a frontend dev, so this is definitely not my speciality) iPXE should be able to use the NIC. Does anyone have an idea how this could be fixed? Thanks!

pojntfx commented 5 years ago

Including the driver should be possible like this:

make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 bin-arm64-efi/ncm--ecm--snp--smsc95xx.efi

This does however fail:

edk2@9255f14e62f5:/home/ipxe$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 bin-arm64-efi/ncm--ecm--snp--smsc95xx.efi
  [PARSEROM]
  [DEPS] drivers/usb/uhci.c
  [BUILD] bin-arm64-efi/uhci.o
  [BUILD] bin-arm64-efi/uhci.ids.o
  [AR] bin-arm64-efi/blib.a
aarch64-linux-gnu-ar: creating bin-arm64-efi/blib.a
  [VERSION] bin-arm64-efi/version.ncm--ecm--snp--smsc95xx.efi.o
  [LD] bin-arm64-efi/ncm--ecm--snp--smsc95xx.efi.tmp
bin-arm64-efi/blib.a(uhci.o): In function `uhci_root_disable':
/home/ipxe/drivers/usb/uhci.c:1203: undefined reference to `inw'
/home/ipxe/drivers/usb/uhci.c:1205: undefined reference to `outw'
bin-arm64-efi/blib.a(uhci.o): In function `uhci_root_enable':
/home/ipxe/drivers/usb/uhci.c:1161: undefined reference to `inw'
/home/ipxe/drivers/usb/uhci.c:1163: undefined reference to `outw'
/home/ipxe/drivers/usb/uhci.c:1166: undefined reference to `outw'
/home/ipxe/drivers/usb/uhci.c:1171: undefined reference to `outw'
/home/ipxe/drivers/usb/uhci.c:1178: undefined reference to `inw'
bin-arm64-efi/blib.a(uhci.o): In function `uhci_root_speed':
/home/ipxe/drivers/usb/uhci.c:1224: undefined reference to `inw'
/home/ipxe/drivers/usb/uhci.c:1249: undefined reference to `outw'
bin-arm64-efi/blib.a(uhci.o): In function `uhci_stop':
/home/ipxe/drivers/usb/uhci.c:104: undefined reference to `inw'
/home/ipxe/drivers/usb/uhci.c:106: undefined reference to `outw'
/home/ipxe/drivers/usb/uhci.c:112: undefined reference to `inw'
bin-arm64-efi/blib.a(uhci.o): In function `uhci_reset':
/home/ipxe/drivers/usb/uhci.c:144: undefined reference to `outw'
/home/ipxe/drivers/usb/uhci.c:150: undefined reference to `inw'
bin-arm64-efi/blib.a(uhci.o): In function `uhci_root_poll':
/home/ipxe/drivers/usb/uhci.c:1285: undefined reference to `inw'
/home/ipxe/drivers/usb/uhci.c:1292: undefined reference to `outw'
bin-arm64-efi/blib.a(uhci.o): In function `uhci_bus_open':
/home/ipxe/drivers/usb/uhci.c:1342: undefined reference to `outl'
bin-arm64-efi/blib.a(uhci.o): In function `uhci_run':
/home/ipxe/drivers/usb/uhci.c:87: undefined reference to `inw'
/home/ipxe/drivers/usb/uhci.c:89: undefined reference to `outw'
aarch64-linux-gnu-ld: bin-arm64-efi/ncm--ecm--snp--smsc95xx.efi.tmp: hidden symbol `inw' isn't defined
aarch64-linux-gnu-ld: final link failed: Bad value
Makefile.housekeeping:1190: recipe for target 'bin-arm64-efi/ncm--ecm--snp--smsc95xx.efi.tmp' failed
make: *** [bin-arm64-efi/ncm--ecm--snp--smsc95xx.efi.tmp] Error 1
rm bin-arm64-efi/version.ncm--ecm--snp--smsc95xx.efi.o

Looks like it tries to call outw, inw and outl from sys/io.h, which is X86 only (direct assembler calls). If someone could port this to aarch64 it might actually work. Or, what would even be even better would be a working SNP implementation for the NIC so that iPXE wouldn't have to be edited.

gratuxri commented 4 years ago

I have compiled it native on arm64 hardware without errors, but I have the same error, that "no such network device"

andreiw commented 4 years ago

Fixed with the upstream edk2 for Pi by Michael Brown