Skip to content

Commit

Permalink
milkv/pioneer: init
Browse files Browse the repository at this point in the history
  • Loading branch information
skeuchel authored and RaitoBezarius committed Apr 5, 2024
1 parent cac934b commit f4a0722
Show file tree
Hide file tree
Showing 13 changed files with 402 additions and 0 deletions.
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,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;
Expand Down
50 changes: 50 additions & 0 deletions milkv/pioneer/README.md
Original file line number Diff line number Diff line change
@@ -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 changes: 28 additions & 0 deletions milkv/pioneer/default.nix
Original file line number Diff line number Diff line change
@@ -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 changes: 7 additions & 0 deletions milkv/pioneer/fip.nix
Original file line number Diff line number Diff line change
@@ -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=";
}
46 changes: 46 additions & 0 deletions milkv/pioneer/firmware.nix
Original file line number Diff line number Diff line change
@@ -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 changes: 44 additions & 0 deletions milkv/pioneer/linux.nix
Original file line number Diff line number Diff line change
@@ -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 { }))
54 changes: 54 additions & 0 deletions milkv/pioneer/linuxboot-initrd.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{ buildGoModule
, fetchFromGitHub
, fetchpatch
, linux-firmware
, ...
}:

# Based on
# https://github.com/sophgo/bootloader-riscv/blob/e0839852d571df106db622611f4786ae17e8df0f/scripts/envsetup.sh#L809-L819

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;
}
)
];

# We only build the u-root binary in the build phase and the initrd in the
# postBuild hook.
subPackages = [ "." ];
postBuild = ''
GOROOT="$(go env GOROOT)" $GOPATH/bin/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 initramfs.cpio \
core boot
# 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 initramfs.cpio
'';

installPhase = ''
install -D initramfs.cpio.xz $out/initrd.img
'';

# Tests time out after 10min for native riscv64 builds on the pioneer.
doCheck = false;
}
15 changes: 15 additions & 0 deletions milkv/pioneer/linuxboot-kernel.nix
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions milkv/pioneer/opensbi.nix
Original file line number Diff line number Diff line change
@@ -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"
];
})
12 changes: 12 additions & 0 deletions milkv/pioneer/sd-image-installer.nix
Original file line number Diff line number Diff line change
@@ -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;
}
57 changes: 57 additions & 0 deletions milkv/pioneer/sd-image.nix
Original file line number Diff line number Diff line change
@@ -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
'';
};
}
15 changes: 15 additions & 0 deletions milkv/pioneer/zsbl-increase-timeout.patch
Original file line number Diff line number Diff line change
@@ -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;
}
}

Loading

0 comments on commit f4a0722

Please sign in to comment.