Merge pull request #902 from skeuchel/milkv-pioneer

milkv/pioneer: init
This commit is contained in:
Jörg Thalheim 2024-04-08 10:48:28 +02:00 committed by GitHub
commit 1e3b3a35b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 421 additions and 0 deletions

View File

@ -185,6 +185,7 @@
microsoft-surface-laptop-amd = import ./microsoft/surface/surface-laptop-amd;
microsoft-surface-common = import ./microsoft/surface/common;
microsoft-surface-pro-3 = import ./microsoft/surface-pro/3;
milkv-pioneer = import ./milkv/pioneer;
morefine-m600 = import ./morefine/m600;
msi-b350-tomahawk = import ./msi/b350-tomahawk;
msi-b550-a-pro = import ./msi/b550-a-pro;

50
milkv/pioneer/README.md Normal file
View File

@ -0,0 +1,50 @@
# Creating an installation SD card image
Create and customize a `flake.nix` file:
```nix
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nixos-hardware.url = "github:nixos/nixos-hardware";
};
outputs = { nixpkgs, nixos-hardware, ... }:
let
supportedSystems = [
"x86_64-linux"
"aarch64-linux"
"riscv64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
forAllSupportedSystems = nixpkgs.lib.genAttrs supportedSystems;
in
{
packages = forAllSupportedSystems (system: rec {
default = sd-image;
sd-image = (import "${nixpkgs}/nixos" {
configuration = {
imports = [
"${nixos-hardware}/milkv/pioneer/sd-image-installer.nix"
];
nixpkgs.buildPlatform.system = system;
nixpkgs.hostPlatform.system = "riscv64-linux";
system.stateVersion = "24.05";
};
inherit system;
}).config.system.build.sdImage;
});
};
}
```
Then build the image by running `nix build .#` in the same folder.
# Known issues
LinuxBoot will not output the boot menu on the serial console, only on the graphical console.
Unfortuately, it might also pick up boot options from other devices, e.g. an nvme or sata drive.
It might end up booting by default from those instead of booting from the SD card.

28
milkv/pioneer/default.nix Normal file
View File

@ -0,0 +1,28 @@
{ config, lib, pkgs, ... }:
{
boot = {
consoleLogLevel = lib.mkDefault 7;
initrd = {
availableKernelModules = [
"amdgpu"
"radeon"
"mmc_block"
"sdhci_sophgo"
];
};
kernelPackages = pkgs.linuxPackagesFor (pkgs.callPackage ./linux.nix {
inherit (config.boot) kernelPatches;
});
kernelParams = lib.mkDefault [
"earlycon"
"console=ttyS0,115200"
"console=tty1"
];
};
hardware.deviceTree = {
enable = true;
name = lib.mkDefault "sophgo/mango-milkv-pioneer.dtb";
};
}

7
milkv/pioneer/fip.nix Normal file
View File

@ -0,0 +1,7 @@
{ fetchurl, ... }:
# Download the vendor's Firmware Image Package
fetchurl {
url = "https://github.com/sophgo/bootloader-riscv/raw/3f750677e0249ff549ad3fe20bbc800998503539/firmware/fip.bin";
hash = "sha256-rav00Ok6+FU77lI0piQPHCaz7Tw1RSbyUal4PyeSccg=";
}

View File

@ -0,0 +1,46 @@
{ stdenv
, writeText
, opensbi
, fip
, zsbl
, linuxboot-kernel
, linuxboot-initrd
, dtbs ? "${linuxboot-kernel}/dtbs"
, ...
}:
let
# Configure a conf.init for linuxboot. If this is not found on the sdcard,
# zsbl will load it from spi flash even when booting from sd. That conf.ini
# might be configured differently and thus not properly boot from sd.
conf-ini = writeText "conf.ini" ''
[sophgo-config]
[devicetree]
name = mango-milkv-pioneer.dtb
[kernel]
name = riscv64_Image
[firmware]
name = fw_dynamic.bin
[ramfs]
name = initrd.img
[eof]
'';
in
stdenv.mkDerivation {
name = "milkv-pioneer-firmware";
buildCommand = ''
install -D ${conf-ini} $out/riscv64/conf.ini
install -D ${fip} $out/fip.bin
install -D ${zsbl} $out/zsbl.bin
install -D ${opensbi}/share/opensbi/lp64/generic/firmware/fw_dynamic.bin $out/riscv64/
install -D ${linuxboot-initrd}/initrd.img $out/riscv64/
install -D ${dtbs}/sophgo/mango-milkv-pioneer.dtb $out/riscv64/
install -D ${linuxboot-kernel}/Image $out/riscv64/riscv64_Image
'';
}

44
milkv/pioneer/linux.nix Normal file
View File

@ -0,0 +1,44 @@
{ buildLinux, fetchFromGitHub, kernelPatches, lib, ... } @ args:
let
modDirVersion = "6.6.20";
in
buildLinux (args // {
inherit kernelPatches modDirVersion;
version = "${modDirVersion}-milkv-pioneer";
src = fetchFromGitHub {
owner = "sophgo";
repo = "linux-riscv";
rev = "caa949e3690fe8a4656313b2b56f52666fa880db";
hash = "sha256-qJpR3KMgvP4tfPfBfQ/MiEWg/uuuxHYuACK8taKKK3E=";
};
defconfig = "sophgo_mango_normal_defconfig";
structuredExtraConfig = let inherit (lib.kernel) freeform module yes; in {
# LinuxBoot will override the console bootparams which will result
# in the distro kernel to be booted with e.g. console=tty1 only.
# https://github.com/sophgo/bootloader-riscv/issues/71
# Force output on serial console through the config. This is also
# needed to get the forced serial-getty to be started.
# We also list tty1 again because according to
# https://docs.kernel.org/admin-guide/serial-console.html and
# https://0pointer.de/blog/projects/serial-console.html
# this will be the main console.
CMDLINE = freeform "console=ttyS0,115200 console=tty1";
CMDLINE_EXTEND = yes;
# Enable these explicitly because they are not enabled by the defconfig.
# The all-hardware profile expects these to be built.
VIRTIO_MENU = yes;
VIRTIO_PCI = module;
# There is an i2c mcu driver (drivers/soc/sophgo/umcu) which is always
# compiled into the kernel. Hence some of the i2c support also needs to
# be compiled in instead of being compiled as a module.
I2C = yes;
I2C_CHARDEV = yes;
I2C_DESIGNWARE_PLATFORM = yes;
};
extraMeta.branch = "sg2042-dev-6.6";
} // (args.argsOverride or { }))

View File

@ -0,0 +1,73 @@
{ buildPackages
, fetchFromGitHub
, fetchpatch
, linux-firmware
, buildGoModule
, ...
}:
# Based on
# https://github.com/sophgo/bootloader-riscv/blob/e0839852d571df106db622611f4786ae17e8df0f/scripts/envsetup.sh#L809-L819
let
u-root = buildPackages.buildGoModule rec {
pname = "u-root";
version = "0.14.0";
src = fetchFromGitHub {
owner = "u-root";
repo = "u-root";
rev = "v${version}";
hash = "sha256-8zA3pHf45MdUcq/MA/mf0KCTxB1viHieU/oigYwIPgo=";
};
vendorHash = null;
patches = [
(fetchpatch {
url = "https://github.com/sophgo/bootloader-riscv/commit/322c3305763872a9b88a1c85d79bca63b8fbe7a6.patch";
hash = "sha256-l5r3DbcMqRYD5FhRBqtEIEscZAdDvjmQJE4BIAtWYWE=";
stripLen = 1;
})
];
postInstall = ''
cp -r . $out/src
'';
# We only build the u-root binary in the build phase and the initrd in the
# postBuild hook.
subPackages = [ "." ];
# Tests time out after 10min for native riscv64 builds on the pioneer.
doCheck = false;
};
in
buildGoModule {
name = "linuxboot-initrd";
src = null;
vendorHash = null;
dontUnpack = true;
nativeBuildInputs = [ u-root ];
buildPhase = ''
runHook preBuild
pushd ${u-root}/src
mkdir -p $out
GOROOT="$(go env GOROOT)" u-root \
-build bb \
-uinitcmd=boot \
-files "${linux-firmware}/lib/firmware/amdgpu/:lib/firmware/amdgpu/" \
-files "${linux-firmware}/lib/firmware/radeon/:lib/firmware/radeon/" \
-o $out/initramfs.cpio \
core boot
popd
# The vendor does not compress the initrd. We do since we include more
# firmware files. CRC32 is required by the kernel's decompressor.
xz --check=crc32 $out/initramfs.cpio
runHook postBuild
'';
installPhase = ''
runHook preInstall
mv $out/initramfs.cpio.xz $out/initrd.img
runHook postInstall
'';
}

View File

@ -0,0 +1,15 @@
{ fetchFromGitHub, lib, linuxManualConfig, stdenv, ... }:
linuxManualConfig rec {
inherit lib stdenv;
modDirVersion = "6.6.20";
version = "${modDirVersion}-milkv-pioneer";
src = fetchFromGitHub {
owner = "sophgo";
repo = "linux-riscv";
rev = "caa949e3690fe8a4656313b2b56f52666fa880db";
hash = "sha256-qJpR3KMgvP4tfPfBfQ/MiEWg/uuuxHYuACK8taKKK3E=";
};
configfile = "${src}/arch/riscv/configs/sophgo_mango_normal_defconfig";
extraMeta.branch = "sg2042-dev-6.6";
}

22
milkv/pioneer/opensbi.nix Normal file
View File

@ -0,0 +1,22 @@
{ fetchFromGitHub, opensbi, ... }:
opensbi.overrideAttrs (attrs: {
# Based on the vendor's sg2042-master branch.
version = "1.4-git-a6e158f7";
src = fetchFromGitHub {
owner = "sophgo";
repo = "opensbi";
rev = "a6e158f71aab17155e2bf25a325ce4f0be51d9dd";
hash = "sha256-5ggrEx1e53pB2+m0TBjDzDJXf2wjsQ2edu01FqqGt/Y=";
};
makeFlags =
# Based on the vendor options
# https://github.com/sophgo/bootloader-riscv/blob/01dc52ce10e7cf489c93e4f24b6bfe1bf6e55919/scripts/envsetup.sh#L299
attrs.makeFlags ++ [
"PLATFORM=generic"
"FW_PIC=y"
"BUILD_INFO=y"
"DEBUG=1"
];
})

View File

@ -0,0 +1,12 @@
{ modulesPath, ... }:
{
imports = [
"${modulesPath}/profiles/installation-device.nix"
./sd-image.nix
];
# the installation media is also the installation target,
# so we don't want to provide the installation configuration.nix.
installer.cloneConfig = false;
}

View File

@ -0,0 +1,57 @@
{ config, lib, modulesPath, pkgs, ... }:
let
inherit (pkgs) callPackage;
fip = callPackage ./fip.nix { };
zsbl = callPackage ./zsbl.nix { };
opensbi = callPackage ./opensbi.nix { };
linuxboot-kernel = callPackage ./linuxboot-kernel.nix { };
linuxboot-initrd = callPackage ./linuxboot-initrd.nix { };
dtbs = config.hardware.deviceTree.package;
firmware = callPackage ./firmware.nix {
inherit fip zsbl opensbi linuxboot-kernel linuxboot-initrd dtbs;
};
in
{
imports = [
"${modulesPath}/profiles/base.nix"
"${modulesPath}/installer/sd-card/sd-image.nix"
./default.nix
];
boot.loader = {
grub.enable = lib.mkDefault false;
generic-extlinux-compatible.enable = lib.mkDefault true;
};
hardware.enableRedistributableFirmware = true;
# For some reason the serial getty is not started automatically
# even though console=ttyS0,115200 is passed to the kernel.
# https://docs.kernel.org/admin-guide/serial-console.html
# https://github.com/NixOS/nixpkgs/issues/84105
systemd.services."serial-getty@ttyS0" = {
enable = true;
wantedBy = [ "getty.target" ];
serviceConfig.Restart = "always";
};
sdImage = {
imageName = "${config.sdImage.imageBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}-milkv-pioneer.img";
populateFirmwareCommands = ''
mkdir -p firmware/
cp -a ${firmware}/* firmware/
touch firmware/BOOT
'';
firmwarePartitionOffset = 1;
firmwareSize = 128;
populateRootCommands = ''
mkdir -p ./files/boot
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
'';
};
}

View File

@ -0,0 +1,15 @@
--- a/drivers/sd/sd.c
+++ b/drivers/sd/sd.c
@@ -560,11 +560,11 @@ static int bm_sd_read(int lba, uintptr_t buf, size_t size)
} else {
udelay(1);
timeout++;
}
- if (timeout >= 10000) {
+ if (timeout >= 100000) {
printf("sdhci read data timeout\n");
goto timeout;
}
}

51
milkv/pioneer/zsbl.nix Normal file
View File

@ -0,0 +1,51 @@
{ buildPackages
, bison
, fetchFromGitHub
, flex
, lib
, stdenv
, ...
}:
stdenv.mkDerivation rec {
pname = "zsbl-sg2042";
version = "git-cc806273";
src = fetchFromGitHub {
owner = "sophgo";
repo = "zsbl";
rev = "cc806273e0f679bef2f6b017c68adede1594ad31";
hash = "sha256-zOlBM7mwz8FUM/BlzOxJmpI8LI/KcFOGXegvgiilbaM=";
};
patches = [
# Depending on the sdcard, reading larger initrds (say >= 25MB)
# can hit the timeout.
./zsbl-increase-timeout.patch
];
nativeBuildInputs = [
bison
flex
];
depsBuildBuild = [
buildPackages.stdenv.cc
];
hardeningDisable = [
"fortify"
"stackprotector"
];
makeFlags = [
"CROSS_COMPILE=${stdenv.cc.targetPrefix}"
];
configurePhase = "make sg2042_defconfig";
installPhase = "install -D zsbl.bin $out";
enableParallelBuilding = true;
dontStrip = true;
meta = {
homepage = "https://github.com/sophgo/zsbl";
description = "Sophgo RISC-V Zero Stage Boot Loader";
license = lib.licenses.gpl2;
};
}