1. Visão geral do BIOS
BIOS é um acrônimo para Basic Input/Output System . Também conhecido como BIOS do sistema, BIOS ROM ou BIOS do PC.
O BIOS de um computador (Basic Input/Output) é o firmware da placa-mãe, o software que é executado em um nível inferior ao do sistema operacional e informa ao computador de qual unidade inicializar, quanta RAM ele possui e controla outros detalhes importantes, como a CPU frequência. Você pode entrar no menu do BIOS para alterar a ordem de inicialização, fazer overclock no seu PC, desativar periféricos integrados e até definir uma senha mestra.
Antes de carregar o Windows ou Linux, o BIOS inicializa e testa os componentes de hardware do sistema (POST), carrega o carregador de inicialização do dispositivo de armazenamento em massa e inicializa o kernel. Durante esse processo, o BIOS encontra o Master Boot Record (MBR) para concluir a inicialização.
O programa BIOS é solidificado em um pequeno chip ROM na placa-mãe do computador. Normalmente, placas-mãe diferentes usam BIOS diferentes.
Embora a maioria das pessoas use o termo BIOS para se referir a qualquer firmware de placa-mãe, isso é tecnicamente incorreto. O programa de configuração em computadores e placas-mãe modernos é chamado UEFI (Universal Extensible Firmware Interface) e suporta unidades maiores e possui menus gráficos mais ricos do que os BIOS mais antigos, que não suportavam armazenamento maior que 2,2 TB. Normalmente, no entanto, as pessoas se referem a UEFI como UEFI BIOS e firmware mais antigo como Legacy BIOS. Todos os PCs modernos têm BIOS UEFI.
2. Carregador de inicialização
O bootloader é o primeiro código executado após o sistema embarcado ser ligado, através deste pequeno programa é realizada a inicialização do hardware, são obtidas informações sobre o tamanho da memória, etc., e o celular é ajustado para o estado de adaptação. Após concluir a inicialização da CPU e do hardware relacionado, a imagem do sistema operacional ou o programa aplicativo incorporado solidificado é instalado na memória e, em seguida, salta para o espaço onde o sistema operacional está localizado para iniciar o sistema operacional.
uboot é uma manifestação concreta do BootLoader, uboot é um subconjunto do bootloader, mas BootLoader não se refere apenas ao uboot, como bios também pertence ao BootLoader. No entanto, no desenvolvimento embarcado diário, BootLoader e uboot são frequentemente misturados.Em muitos casos, tanto BootLoader quanto uboot referem-se a uboot, porque no desenvolvimento embarcado, o BootLoader usado é basicamente uboot.
3. U-Boot
O bootloader é a peça crítica de software que roda em qualquer sistema. Sempre que um sistema de computação é inicializado, a primeira parte do código a ser carregada e executada é o carregador de inicialização. Ele fornece aos usuários uma interface para carregar o sistema operacional e os aplicativos. A função principal do uboot é iniciar o kernel do sistema operacional, e a essência do uboot é um programa bare metal.
Existem muitos bootloaders no ecossistema de código aberto, como GRUB, UEFI, RedBoot, Yaboot, etc. No entanto, U-Boot ou Das U-Boot é o carregador de inicialização de plataforma cruzada de código aberto mais usado. Geralmente é usado em sistemas embarcados e o objetivo principal é configurar o sistema e carregar o sistema operacional de próximo nível. Ele suporta várias arquiteturas e é fortemente seguido pelos fabricantes de hardware.
O carregador de inicialização U-Boot geralmente é carregado pela ROM de inicialização do sistema a partir de várias fontes de inicialização, geralmente memória não volátil, como flash NOR, cartão SD e flash SPI, para controlar o hardware durante a inicialização. Uma vez que o U-Boot começa a ser executado, ele configura o hardware para carregar a imagem do próximo nível do armazenamento integrado ou da rede e, em seguida, inicia o carregamento da imagem do próximo nível. Depois que a imagem do próximo nível é carregada, o U-Boot transfere o controle de execução para a imagem executável do próximo nível. O U-Boot também fornece ao usuário uma interface do tipo "shell" para que o usuário possa usar a configuração de hardware antes que a imagem do próximo nível assuma o controle.
uboot (inicialização universal) é um código de inicialização universal que suporta CPUs de várias arquiteturas. O uboot é altamente personalizado e dividido em gerenciamento de recursos em nível de Soc e gerenciamento de recursos em nível de placa. Diferentes CPUs ou diferentes placas de desenvolvimento da mesma CPU, o uboot é diferente e precisa ser transplantado de acordo com o circuito de hardware.
4. Compile e instale no U-Boot
O conteúdo a seguir é reproduzido do U-Boot - SFPi Salted Fish Pie
1. Compile o U-Boot a partir do código-fonte
Obter U-Boot
Obtenha o código-fonte do U-Boot online. Tome o Github como exemplo, clone o repositório u-boot/u-boot :
$ git clone [email protected]:u-boot/u-boot.git
Se você quiser uma versão estável do U-Boot, você pode fazer o checkout de uma tag, veja a v2018.11-rc3 como exemplo:
$ git checkout v2018.11-rc3
Ou baixe diretamente o código-fonte U-Boot da versão especificada, tome v2018.11-rc3 como exemplo:
$ wget https://github.com/u-boot/u-boot/archive/v2018.11-rc3.tar.gz
$ tar xvf v2018.11-rc3.tar.gz
2. Obtenha a cadeia de ferramentas de compilação cruzada
Se você é um usuário do Archlinux, você pode instalar o arm-none-eabi-gcc diretamente :
$ sudo pacman -Sy arm-none-eabi-gcc
Se você é um usuário Debian, você pode instalar gcc-arm-linux-gnueabihf :
$ sudo apt install gcc-arm-linux-gnueabihf
Se você é um usuário do Ubuntu, você pode instalar o gcc-arm-linux-gnueabihf
$ sudo apt-get install gcc-arm-linux-gnueabihf
Se você é um usuário do Fedora, você pode instalar o arm-none-eabi-gcc-cs
$ sudo dnf install arm-none-eabi-gcc-cs
Para distribuições Linux não listadas, você pode pesquisar suas fontes para uma cadeia de ferramentas de compilação cruzada ou usar o Linaro GCC , se não .
Devido aos diferentes prefixos dos compiladores cruzados instalados em cada versão, se o compilador instalado for arm-none-eabi-gcc, então o CROSS_COMPILE que usaremos posteriormente é arm-none-eabi-, ou seja, remova a última parte do gcc . Outros comuns são arm-linux-gnueabihf- e arm-linux-gnueabi, ambos são bons.
3. Configure o U-Boot
O arquivo .config do U-Boot testado fornecido foi armazenado no diretório u-boot de sbc-fish/sfpi . O .config aqui pode ser copiado diretamente para o diretório raiz do U-Boot para uso.
Tome U-Boot v2018.11-rc3 como exemplo, vá para o diretório U-Boot e baixe .config:
$ wget https://raw.githubusercontent.com/sbc-fish/sfpi/master/u-boot/v2018.11-rc3/.config
Se não fornecermos a versão correspondente do .config, você pode encontrar um .config com uma versão mais próxima e baixá-lo para uso. Se houver algumas configurações que precisam ser alteradas, haverá prompts correspondentes durante a compilação subsequente. Geralmente, você pode usar os parâmetros padrão.
Se você quiser ajustar a configuração por conta própria:
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- menuconfig
onde CROSS_COMPILE é o prefixo de sua cadeia de ferramentas de compilação cruzada instalada. Se você usar o .config que fornecemos, nenhuma alteração será necessária.
4. Compile o U-Boot
Então comece a compilar:
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- -j24
que -j24
é ajustado de acordo com a CPU da sua máquina. Neste ponto, você deve obter um u-boot-sunxi-with-spl.bin
arquivo no diretório atual.
5. Flash no U-Boot
partição
Recomenda-se gravar a tabela de partições no formato MBR no cartão TF e reservar um certo espaço antes da primeira partição. Se o tamanho do arquivo compilado na etapa anterior for de algumas centenas de K, um esquema de particionamento para referência é:
Disk: /dev/disk4 geometry: 980/128/63 [7907328 sectors]
Offset: 0 Signature: 0xAA55
Starting Ending
#: id cyl hd sec - cyl hd sec [ start - size]
------------------------------------------------------------------------
1: 0B 1023 254 63 - 1023 254 63 [ 2048 - 20480] Win95 FAT-32
2: 83 1023 254 63 - 1023 254 63 [ 22528 - 7884800] Linux files*
3: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
4: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
A primeira partição (FAT-32) começa a partir do setor 2048, ou seja, em 1M (2048*512=1M), para que haja espaço suficiente reservado para o U-Boot. O tamanho deste espaço reservado pode ser ajustado de acordo com os u-boot-sunxi-with-spl.bin
arquivos compilados e a capacidade do cartão TF. Para o uso de ferramentas de particionamento, consulte Partitioning - Archlinux Wiki , fdisk - Archlinux Wiki ou fdisk Manpages .
Use DD para fazer o flash U-Boot
Escreva no u-boot-sunxi-with-spl.bin
offset 8192 do cartão TF, o comando é o seguinte:
$ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/disk4 bs=1024 seek=8
Se você é um usuário do macOS, pode usar o flash_uboot_macOS.sh que escrevemos .
6. Iniciar
conectar porta serial
Insira o cartão TF na torta de peixe salgado, conecte o microUSB ao computador e você verá um dispositivo USB para Serial. Os drivers de cada plataforma podem ser baixados no site oficial da Qinheng . No Windows, você pode usar ferramentas como o assistente de porta serial. No Linux e macOS, você pode usar os seguintes comandos:
$ screen [tty] 115200
Verifique a porta serial. Para macOS, o tty aqui deve estar no formato /dev/tty.wchusbserial*.
Pressione o botão de ligar na placa, se a configuração for bem-sucedida, você poderá ver a inicialização do U-Boot da seguinte maneira:
U-Boot SPL 2018.11-rc3 (Nov 09 2018 - 11:55:32 +0800)
DRAM: 64 MiB
Trying to boot from MMC1
U-Boot 2018.11-rc3 (Nov 09 2018 - 11:55:32 +0800) Allwinner Technology
CPU: Allwinner V3s (SUN8I 1681)
Model: Lichee Pi Zero
DRAM: 64 MiB
MMC: SUNXI SD/MMC: 0
Loading Environment from FAT... OK
In: serial@01c28000
Out: serial@01c28000
Err: serial@01c28000
Net: No ethernet found.
starting USB...
No controllers found
Hit any key to stop autoboot: 0
=>
Neste ponto, podemos prosseguir para a próxima etapa do processo de compilação do kernel do Linux.
5. Compilação do Kernel Linux
1. Baixe o código-fonte do Linux e aplique o Patch
Mantemos um patch para o kernel principal do Linux em sbc-fish/sfpi:/linux . Ele fornece DTS, padrão .config
e algumas outras pequenas alterações para dispositivos de torta de peixe salgado. Veja o link acima para ver as versões de kernel atualmente suportadas. Outras versões de kernel podem ser alteradas de acordo com o patch da versão de kernel mais próxima.
Baixe o código fonte do kernel Linux, tome 4.19.1 como exemplo:
$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.1.tar.xz
$ tar xvf linux-4.19.1.tar.xz
$ cd linux-4.19.1
Aplique os patches que fornecemos:
$ curl https://raw.githubusercontent.com/sbc-fish/sfpi/master/linux/4.19.1/sfpi-linux-4.19.1.patch | patch -p1
patching file arch/arm/boot/dts/Makefile
patching file arch/arm/boot/dts/sun8i-v3s-saltedfishpi.dts
patching file arch/arm/boot/dts/sun8i-v3s.dtsi
patching file arch/arm/configs/saltedfishpi_defconfig
patching file drivers/bluetooth/Kconfig
patching file drivers/bluetooth/hci_h5.c
2. Obtenha a cadeia de ferramentas de compilação cruzada
Se você leu a parte relevante em [Compiling and Flashing U-Boot] (https://sbc-fish.github.io/sfpi/uboot/), você pode pular esta seção.
Se você é um usuário do Archlinux, você pode instalar o arm-none-eabi-gcc diretamente :
$ sudo pacman -Sy arm-none-eabi-gcc
Se você é um usuário Debian, você pode instalar gcc-arm-linux-gnueabihf :
$ sudo apt install gcc-arm-linux-gnueabihf
Se você é um usuário do Ubuntu, você pode instalar o gcc-arm-linux-gnueabihf
$ sudo apt-get install gcc-arm-linux-gnueabihf
Se você é um usuário do Fedora, você pode instalar o arm-none-eabi-gcc-cs
$ sudo dnf install arm-none-eabi-gcc-cs
Para distribuições Linux não listadas, você pode pesquisar suas fontes para uma cadeia de ferramentas de compilação cruzada ou usar o Linaro GCC , se não .
Devido aos diferentes prefixos dos compiladores cruzados instalados em cada versão, se o compilador instalado for arm-none-eabi-gcc, então o CROSS_COMPILE que usaremos posteriormente é arm-none-eabi-, ou seja, remova a última parte do gcc . Outros comuns são arm-linux-gnueabihf- e arm-linux-gnueabi, ambos são bons.
3. Gere e altere o .config do Linux
Use o .config que fornecemos
No Patch recém aplicado, um .config testado já está incluso, digite o seguinte comando:
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- saltedfishpi_defconfig
Se você quiser ajustar a configuração por conta própria:
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- menuconfig
4. Compile o kernel do Linux
Compile o kernel do Linux com o seguinte comando:
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- -j4
O tempo de compilação do Linux depende das instalações de hardware de sua máquina, e os parâmetros são ajustados de acordo com o número de threads da CPU -j
. Pode muito bem tomar uma xícara de café enquanto espera o Linux compilar.
Após a compilação, devemos obter o arquivo de arch/arm/boot/zImage
soma arch/arm/boot/dts/sun8i-v3s-saltedfishpi.dtb
que desejamos.
5. Escreva no cartão TF
arch/arm/boot/zImage
Copie os arquivos e arquivos compilados arch/arm/boot/dts/sun8i-v3s-saltedfishpi.dtb
no sistema de arquivos do cartão TF. Recomenda-se gravar no sistema de arquivos FAT ou EXT.
6. Preparar rootfs
Um kernel sozinho não é suficiente, também precisamos de um rootfs. Os métodos comuns são buildroot e usar diretamente a imagem da versão de distribuição existente. Aqui tomamos ArchLinuxARM como exemplo, assumindo que a partição rootfs esperada foi montada lá mnt
:
$ wget http://os.archlinuxarm.org/os/ArchLinuxARM-armv7-latest.tar.gz
$ bsdtar -xpf ArchLinuxARM-armv7-latest.tar.gz -C mnt
Se você estiver usando o macOS e não puder gravar no sistema de arquivos EXT4, primeiro encontre uma máquina Linux e faça o seguinte:
$ dd if=/dev/zero of=archlinuxarm.img bs=1M count=1024
$ mkfs.ext4 archlinuxarm.img
$ sudo mount -o loop archlinuxarm.img mnt
$ wget http://os.archlinuxarm.org/os/ArchLinuxARM-armv7-latest.tar.gz
$ bsdtar -xpf ArchLinuxARM-armv7-latest.tar.gz -C mnt
$ sudo umount mnt
Copie o obtido archlinuxarm.img
para o sistema macOS e escreva:
$ sudo dd if=archlinuxarm.img of=/dev/[disk] bs=65535
As partições correspondentes [disk]
podem ser encontradas aqui . diskutil list
Para um melhor desempenho, você pode adicionar um antes do nome do dispositivo r
, por exemplo /dev/rdisk4s2
.
Se você tiver e2fsprogs ( ) instalado no macOS brew install e2fsprogs
, poderá expandir o sistema de arquivos para o tamanho total da partição:
$ sudo /usr/local/opt/e2fsprogs/sbin/resize2fs -p /dev/[disk]
O [disk]
significado aqui é o mesmo acima.
7. Configure as opções de inicialização do U-Boot
Na seção anterior, você deveria ter conseguido entrar na interface U-Boot. Primeiro precisamos encontrar o kernel e os .dtb
arquivos que acabamos de construir. Veja a tabela de partição do cartão TF:
=> part list mmc 0
Partition Map for MMC device 0 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 8192 85045 68db6199-01 0c
2 94208 30453760 68db6199-02 83
=>
Aqui você pode ver o status da partição no cartão TF. Aqui está um exemplo, uma partição FAT contém o kernel e os .dtb
arquivos, e outra partição EXT4 contém o rootfs. Digite o seguinte comando para confirmar onde o kernel está armazenado:
=> fatls mmc 0:1 # 浏览分区 1 (FAT 文件系统)上的文件
=> ext4ls mmc 0:2 # 浏览分区 2 (EXT4 文件系统)上的文件
Neste tutorial, os arquivos necessários são zImage
colocados sun8i-v3s-saltedfishpi.dtb
na primeira partição (sistema de arquivos FAT). Digite o seguinte comando para carregar o kernel e os .dtb
arquivos na memória:
=> fatload mmc 0:1 0x41000000 zImage
=> fatload mmc 0:1 0x41800000 sun8i-v3s-saltedfishpi.dtb
Se for um sistema de arquivos EXT4, o comando acima pode ser usado ext2load
ou ext4load
substituído . fatload
Agora comece a inicializar no kernel:
=> setenv bootargs console=ttyS0,115200
=> bootz 0x41000000 - 0x41800000
Neste ponto, você deve ver o kernel do Linux inicializando com sucesso, mas falhou ao concluir a inicialização porque o rootfs não foi encontrado. No exemplo acima, o rootfs está localizado na segunda partição do cartão TF, então você pode alterar os parâmetros de boot e entrar no kernel:
=> fatload mmc 0:1 0x41000000 zImage
=> fatload mmc 0:1 0x41800000 sun8i-v3s-saltedfishpi.dtb
=> setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait
=> bootz 0x41000000 - 0x41800000
Deve-se notar que este aqui rootwait
deve ser adicionado, e também /dev/mmcblk0p2
representa a segunda partição no cartão TF. Quando rootfs não foi especificado agora, o kernel exibirá as seguintes informações:
[ 2.252872] Please append a correct "root=" boot option; here are the available partitions:
[ 2.261315] b300 15273984 mmcblk0
[ 2.261320] driver: mmcblk
[ 2.268156] b301 42522 mmcblk0p1 68db6199-01
[ 2.268159]
[ 2.274971] b302 15226880 mmcblk0p2 68db6199-02
[ 2.274974]
Você pode encontrar e mmcblk0p2
alterar os rootfs correspondentes de acordo com as informações exibidas aqui.
Se você deseja salvar o comando de inicialização para que possa ser iniciado automaticamente mais tarde, digite o seguinte comando:
=> setenv bootcmd 'fatload mmc 0:1 0x41000000 zImage;fatload mmc 0:1 0x41800000 sun8i-v3s-saltedfishpi.dtb; setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait; bootz 0x41000000 - 0x41800000'
=> saveenv
Após cada ligação, o U-Boot inicializará automaticamente no Linux. Você também pode entrar manualmente boot
no Linux.