[LINUX] [Memo] Connect Raspberry Pi Zero to the Internet with a single USB cable! (Use nfs, no SD card / keyboard / mouse / monitor required)

Overview

--Connect Raspberry Pi Zero to the Internet with a single USB cable --No SD card required --Since root (/) is mounted by NFS, set the NFS server side with Ubuntu 20.04 of VirtualBox. --Sometimes NFS mount seems to fail (timing?), So maybe you should try connecting a monitor?

--Reference: [HOW TO RUN OR BOOT RASPBIAN ON A RASPBERRY PI ZERO WITHOUT AN SD-CARD](https://dev.webonomic.nl/how-to-run-or-boot-raspbian-on-a-raspberry- pi-zero-without-an-sd-card)
Or rather, I checked it for Buster as it is

environment

procedure

Virtual environment installation

  1. Start PowerShell as an administrator (Win + x, a, ALT + y)

  2. Chocolatey installation (https://chocolatey.org/install)

    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
    
  3. Install Virtualbox + Extension and pin it (do not upgrade it without permission)

    #choco pin remove --name virtualbox
    #choco uninstall  -y virtualbox -x
    cinst -y virtualbox --params "/ExtensionPack /NoQuickLaunch /NoRegister /NoPath"
    choco pin add    --name virtualbox
    
  4. Install vagrant etc.

    cinst -y vagrant vscode
    

-(Host key setting) For keyboards that do not have a right Ctrl, start Virtualbox once, and then select Host Key Combination in Menu> File> Preferences ...> Input> [Virtual Machine] to select another key (eg: Host Key Combination). Right Alt).
Image.png

  1. Restart the host machine (Windows 10) once, and start PowerShell again as an administrator.

  2. Install vagrant plugin

    vagrant plugin install vagrant-vbguest
    vagrant plugin install vagrant-disksize 
    
  3. Exit with ʻexit`

Preparation of virtual machine (VM guest)

  1. Start PowerShell normally (Win + x, i)

  2. Working folder: Create C: \ Vagrant \ u20 (> mkdir C: \ Vagrant \ u20), move ('> cd C: \ Vagrant \ u20`)

  3. Create the following Vagrantfile with VS Code (> code C: \ Vagrant \ u20 \ Vagrantfile).
    Add the plugin
    Image.png -image-store.s3.ap-northeast-1.amazonaws.com/0/75594/3817fecb-f4e0-65ee-d19d-4dce4078da26.png)

    # -*- mode: ruby -*-
    # vi: set ft=ruby :
    
    VB_NAME="u2004"
    VM_MEMORY=1024
    VM_CORES=2
    
    Vagrant.configure("2") do |config|
      config.vm.box = "ubuntu/focal64"
      config.vm.boot_timeout = 6000
      config.vm.network "public_network"
      
      config.vm.provider "virtualbox" do |vb|
        #vb.gui = true #Virtualbox window opens
        vb.name         = VB_NAME
        vb.memory       = VM_MEMORY
        vb.cpus         = VM_CORES
        vb.customize ['modifyvm', :id, '--usb', 'on']
        vb.customize ['modifyvm', :id, '--usbehci', 'on' ] # USB 2.0 controller
        vb.customize ["modifyvm", :id, "--usbxhci", 'off' ] # USB 3.0 controller
        vb.customize ["usbfilter", "add", "0", "--target", :id, '--name', "Broadcom BCM2708 Boot","--vendorid","0a5c","--productid","2763", "--remote", "no"] #
        vb.customize ["usbfilter", "add", "1", "--target", :id, '--name', "Broadcom BCM2710 Boot","--vendorid","0a5c","--productid","2764", "--remote", "no"] #
        vb.customize ["usbfilter", "add", "2", "--target", :id, '--name', "Linux with usb RNDIS/Ethernet Gadget","--vendorid","0525","--productid","a4a2", "--remote", "no"] #
      end
    
      config.vm.provision "shell", privileged: true, inline: <<-SHELL
        sed -i -e 's/ console=ttyS0//g' /etc/default/grub.d/50-cloudimg-settings.cfg
        update-grub
        apt-get update
        apt install -y linux-modules-$(uname -r) linux-modules-extra-$(uname -r)
        apt install -y build-essential libusb-1.0-0-dev git unzip nfs-kernel-server
      SHELL
    end
    
  4. Start the virtual machine with vagrant up

  5. Wait for a while. About 20 to 30 minutes? --ʻUbuntu / focal64Image download ――It takes a long time to start this guy. If I change the grub parameter (removeconsole = ttyS0), it seems to be good (https://bugs.launchpad.net/cloud-images/+bug/1829625), so I am doing it with vagrant provision. --Download tools and other information --Install linux-modules-extra-` for USB Ethernet driver

    image.png

  6. Shut down once with vagrant halt.

  7. Change vb.customize ["usbfilter "," add "... ʻadd to modify` in Vagrantfile. (Do all three. Only two images below .. 3 I'm trying to change my eyes ...)
    ![Image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/c33e2e68-3a16 -5f13-4567-b565bd87ead8.png)

  8. Start with vagrant up, log in with vagrant ssh

Preparation for launching RPi Zero

  1. Log in to the virtual machine

  2. Build usbboot / rpiboot

    cd ${HOME} && \
    git clone --depth=1 https://github.com/raspberrypi/usbboot && \
    cd usbboot && \
    make && \
    cd ${HOME}
    
  3. Download and unzip Raspbian lite

    cd ${HOME} && \
    wget http://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2020-02-14/2020-02-13-raspbian-buster-lite.zip && \
    unzip 2020-02-13-raspbian-buster-lite.zip
    
  4. Mount the Raspbian lite image.

    sudo losetup -P /dev/loop5 ${HOME}/2020-02-13-raspbian-buster-lite.img
    sudo mkdir -p /pi/{boot,root}
    sudo mount /dev/loop5p1 /pi/boot
    sudo mount /dev/loop5p2 /pi/root
    
  5. Patch to start

    # Edit /pi/boot/config.txt
    grep -e '^dtoverlay=dwc2$' /pi/boot/config.txt || echo -e "# enable OTG\ndtoverlay=dwc2\n# set initramfs\ninitramfs initrd.img followkernel" | sudo tee -a /pi/boot/config.txt
    
    #cmdline.txt
    #console=serial0,115200 console=tty1 root=PARTUUID=738a4d67-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh
    echo 'otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/nfs nfsroot=10.42.0.1:/pi/root rw ip=10.42.0.14:10.42.0.1::255.255.255.0:pi:usb0:static elevator=deadline modules-load=dwc2,g_ether fsck.repair=yes rootwait g_ether.host_addr=5e:a1:4f:5d:cf:d2' | sudo tee /pi/boot/cmdline.txt
    
    cat <<'EOF' | sudo tee /pi/root/etc/fstab
    proc            /proc           proc    defaults          0       0
    10.42.0.1:/pi/root / nfs defaults 0 1
    #PARTUUID=738a4d67-01  /boot           vfat    defaults          0       2
    #PARTUUID=738a4d67-02  /   
    EOF
    
    # /pi/root/etc/dhcpcd.conf
    grep -e '^interface usb0 #mt08$' /pi/root/etc/dhcpcd.conf || echo -e 'interface usb0 #mt08\nstatic ip_address=10.42.0.14/24\nstatic routers=10.42.0.1\nstatic domain_name_servers=8.8.8.8' | sudo tee -a /pi/root/etc/dhcpcd.conf
    
    #Start ssh automatically
    cd /pi/root/etc/systemd/system/multi-user.target.wants
    sudo ln -s /lib/systemd/system/ssh.service ssh.service
    cd ${HOME}
    
    #Bring the initrd.
    cd ${HOME} && \
    wget "https://github.com/mt08xx/files/raw/master/2020-0512-1_RPIZero_initrd.img-4.19.97%2B" && \
    sudo cp 2020-0512-1_RPIZero_initrd.img-4.19.97+ //pi/boot/initrd.img
    
  6. Ubuntu side settings

    #NFS settings
    grep 10.42.0 /etc/exports || echo "/pi/root 10.42.0.14(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
    sudo systemctl restart nfs-server.service
    sudo exportfs -rav
    
    #Assign a fixed IP to Ethernet for USB connection.
    #The device name may be usb0 or enx5ea14f5dcfd2..
    cat << 'EOF' | sudo tee /etc/netplan/50-cloud-init.yaml
    # This file is generated from information provided by the datasource.  Changes
    # to it will not persist across an instance reboot.  To disable cloud-init's
    # network configuration capabilities, write a file
    # /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
    # network: {config: disabled}
    network:
        ethernets:
            enp0s3:
                dhcp4: true
                match:
                    macaddress: 02:c2:ed:de:cc:93
                set-name: enp0s3
            usb0:
                dhcp4: no
                dhcp6: no
                addresses: [10.42.0.1/24]
            enx5ea14f5dcfd2:
                dhcp4: no
                dhcp6: no
                addresses: [10.42.0.1/24]
        version: 2
    EOF
    
    #Adaptation
    sudo netplan generate
    sudo netplan apply
    
    #IP Forwarding enabled
    sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
    
  7. Exit with ʻexit, virtual machine with vagrant halt`, shut down once

Launch RPi Zero

  1. RPi Zero does not connect

  2. Start PowerShell normally (Win + x, i)

  3. Execute the following

    #Move to working folder
    cd C:\Vagrant\u20
    #Virtual machine startup
    vagrant up
    #Log in to the virtual machine
    vagrant ssh
    
  4. Execute the following

    #IP forwarding settings(Do not save)
    sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
    #
    #Raspbian lite image mount
    sudo losetup -P /dev/loop5 ${HOME}/2020-02-13-raspbian-buster-lite.img
    sudo mkdir -p /pi/{boot,root}
    sudo mount /dev/loop5p1 /pi/boot
    sudo mount /dev/loop5p2 /pi/root
    #
    #Run rpiboot
    cd ${HOME}
    sudo usbboot/rpiboot -d /pi/boot/
    
  5. Connect the RPi Zero's USB port (not the power supply PWR) to your PC.
    It may be better to connect RPi Zero to a TV and see how it looks.

  6. Pray

Execution example

-- 10.42.0.1: / pi / root on / type nfs ... image.png

Other

--I put ubuntu 20.04 64bit in RPi4B and it worked in the same way (or rather, it is better to check with RPi4B ..) --swap cannot be used --I mount the img file of raspbian and use it, but I think that the file is copied in actual use. --The device name is usb0 or enx5ea14f5dcfd2 .. ――What if multiple Pi Zeros are connected? Please let me know if you can make good settings at that time. --Using SD, the previous article, [Note] Connect the Raspberry Pi Zero to the Internet with a single USB cable! (No keyboard, mouse or monitor required), ha![Image.png](https://qiita-image-store.s3.ap-northeast- 1.amazonaws.com/0/75594/dfae691b-7579-af5c-f13b-80b915efd397.png).

How to make initrd.img

  1. Put Raspbian on SD and start it.

  2. Start with RPi Zero

  3. Execute the following

    ## Make initramfs on "RPi-Zero"
    sudo apt install -y initramfs-tools
    
    grep -e '^g_ether$' /etc/initramfs-tools/modules || echo -e 'g_ether\nlibcomposite\nu_ether\nudc-core\nusb_f_rndis\nusb_f_ecm' | sudo tee -a /etc/initramfs-tools/modules
    
    sudo update-initramfs -c -k `uname -r`
    
  4. A file called /boot/initrd.img-4.19.97+ will be created, so copy it to the VM's /pi/boot/initrd.img.

Recommended Posts

[Memo] Connect Raspberry Pi Zero to the Internet with a single USB cable! (Use nfs, no SD card / keyboard / mouse / monitor required)
A memo to simply use the illuminance sensor TSL2561 with Raspberry Pi 2
Raspberry Pi --1 --First time (Connect a temperature sensor to display the temperature)
Connect to the console of Raspberry PI and display local IP and SD information
Try to use up the Raspberry Pi 2's 4-core CPU with Parallel Python