NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.14k stars 14.17k forks source link

Rock64 SD image support #35166

Closed cstrahan closed 3 years ago

cstrahan commented 6 years ago

I'm opening this issue to track my effort to add support for building an SD image for the Rock64 computer.

Rockchip has a fork of the Linux kernel and u-boot:

But it looks like most people use ayufan's forks:

He also has some Docker based build scripts:

For now, I'm attempting to work with ayufan's forks.

I used the scripts in linux-build to generate a .config to compare with what Nixpkgs currently generates for me:

The build currently fails under nix due to inclusion of non existent headers and such. I'm hoping that that boils down to a difference in Kconfig.

cstrahan commented 6 years ago

Sure enough, using .config generated via ayufan's linux-build results in a non-failing build. Otherwise I get errors like:

In file included from ../sound/soc/codecs/cx20810.c:14:0:
../sound/soc/codecs/cx20810.c:161:26: error: 'cx20810_id' undeclared here (not in a function); did you mean 'cx2081x_id'?
 MODULE_DEVICE_TABLE(i2c, cx20810_id);
                          ^
../include/linux/module.h:223:21: note: in definition of macro 'MODULE_DEVICE_TABLE'
 extern const typeof(name) __mod_##type##__##name##_device_table  \
                     ^~~~
  CC      net/core/rtnetlink.o
../include/linux/module.h:223:27: error: '__mod_i2c__cx20810_id_device_table' aliased to undefined symbol 'cx20810_id'
 extern const typeof(name) __mod_##type##__##name##_device_table  \
                           ^
../sound/soc/codecs/cx20810.c:161:1: note: in expansion of macro 'MODULE_DEVICE_TABLE'
 MODULE_DEVICE_TABLE(i2c, cx20810_id);
 ^~~~~~~~~~~~~~~~~~~
In file included from ../drivers/devfreq/rockchip_dmc.c:26:0:
../include/linux/devfreq_cooling.h:60:14: warning: 'struct devfreq_cooling_power' declared inside parameter list will not be visible outside of this definition or declaration
       struct devfreq_cooling_power *dfc_power)
              ^~~~~~~~~~~~~~~~~~~~~
  LD      drivers/fmc/built-in.o
  CC [M]  sound/soc/rockchip/rockchip_pdm.o
  CC [M]  drivers/char/tpm/st33zp24/i2c.o
  CC      mm/frontswap.o
  LD      fs/btrfs/built-in.o
  CC [M]  drivers/fmc/fmc-core.o
  CC [M]  fs/btrfs/super.o
  CC [M]  sound/soc/rockchip/rockchip_spdif.o
  CC [M]  crypto/rmd256.o
  CC [M]  crypto/rmd320.o
  LD      drivers/fpga/built-in.o
  CC [M]  drivers/fpga/fpga-mgr.o
  CC [M]  drivers/dma/fsl-edma.o
../drivers/devfreq/rockchip_dmc.c:2280:15: error: variable 'ddr_cooling_power_data' has initializer but incomplete type
 static struct devfreq_cooling_power ddr_cooling_power_data = {
               ^~~~~~~~~~~~~~~~~~~~~
../drivers/devfreq/rockchip_dmc.c:2281:3: error: 'struct devfreq_cooling_power' has no member named 'get_static_power'
  .get_static_power = model_static_power,
   ^~~~~~~~~~~~~~~~
../drivers/devfreq/rockchip_dmc.c:2281:22: warning: excess elements in struct initializer
  .get_static_power = model_static_power,
                      ^~~~~~~~~~~~~~~~~~
../drivers/devfreq/rockchip_dmc.c:2281:22: note: (near initialization for 'ddr_cooling_power_data')
../drivers/devfreq/rockchip_dmc.c:2282:3: error: 'struct devfreq_cooling_power' has no member named 'dyn_power_coeff'
  .dyn_power_coeff = 120,
   ^~~~~~~~~~~~~~~
../drivers/devfreq/rockchip_dmc.c:2282:21: warning: excess elements in struct initializer
  .dyn_power_coeff = 120,
                     ^~~
../drivers/devfreq/rockchip_dmc.c:2282:21: note: (near initialization for 'ddr_cooling_power_data')
../drivers/devfreq/rockchip_dmc.c: In function 'ddr_power_model_simple_init':
../drivers/devfreq/rockchip_dmc.c:2325:24: error: invalid use of undefined type 'struct devfreq_cooling_power'
  ddr_cooling_power_data.dyn_power_coeff = (unsigned long)temp;
                        ^
../drivers/devfreq/rockchip_dmc.c: In function 'rockchip_dmcfreq_probe':
../drivers/devfreq/rockchip_dmc.c:2492:13: warning: passing argument 3 of 'of_devfreq_cooling_register_power' from incompatible pointer type [-Wincompatible-pointer-types]
             &ddr_cooling_power_data);
             ^
In file included from ../drivers/devfreq/rockchip_dmc.c:26:0:
../include/linux/devfreq_cooling.h:59:1: note: expected 'struct devfreq_cooling_power *' but argument is of type 'struct devfreq_cooling_power *'
 of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../drivers/devfreq/rockchip_dmc.c: At top level:
../drivers/devfreq/rockchip_dmc.c:2280:37: error: storage size of 'ddr_cooling_power_data' isn't known
 static struct devfreq_cooling_power ddr_cooling_power_data = {
                                     ^~~~~~~~~~~~~~~~~~~~~~
  CC      kernel/kallsyms.o
  CC [M]  sound/soc/rockchip/rockchip_da7219.o
  CC [M]  net/bridge/br_nf_core.o
make[4]: *** [../scripts/Makefile.build:272: drivers/devfreq/rockchip_dmc.o] Error 1
make[3]: *** [../scripts/Makefile.build:411: drivers/devfreq] Error 2
cstrahan commented 6 years ago

Ah, part of the problem is that I wasn't specifying rockchip_linux_defconfig, though I'm not sure if that's sufficient to get past the compilation errors. I'll run another build and see if I, perhaps, need to black list some of the modules that pkgs/os-specific/linux/kernel/generate-config.pl automatically attempts to build.

cstrahan commented 6 years ago

That wasn't sufficient.

However, I realize I can ensure hostPlatform.platform.kernelAutoModules = false; to prevent automatically compiling a bunch of optional modules, which brings the diff down quite a bit between the Nix generated config vs the one from ayufan's linux-build.

Trying to build that now, and crossing my fingers.

cstrahan commented 6 years ago

Success! I can build ayufan's fork without hardcoding a pre-generated config:

{ stdenv, buildPackages, hostPlatform, fetchFromGitHub, perl, buildLinux, ... } @ args:

buildLinux (args // {
  version = "4.4.103";
  extraMeta.branch = "4.4";

  # override aarch64-multiplatform settings.
  # not the right way to do this; need advice.
  hostPlatform = hostPlatform // {
    platform = hostPlatform.platform // {
      kernelBaseConfig = "rockchip_linux_defconfig";
      kernelAutoModules = false; # compilation failures otherwise
    };
  };

  src =  fetchFromGitHub {
    owner = "ayufan-rock64";
    repo = "linux-kernel";
    rev = "cd53e86c7fc2b56d6b14150e5dbabeb18f7219ff";
    sha256 = "1nnwglgw177npm18i8wjqfdl6w5rbdj8rq9303lglsz70ma060ai";
  };
} // (args.argsOverride or {}))

Now I need to package the u-boot fork and work on a port of nixos/modules/installer/cd-dvd/sd-image-aarch64.nix.

cstrahan commented 6 years ago

Here's some more info:

dezgeg commented 6 years ago

The mainline kernel (at least in linux-next) claims support for Ethernet, SD/MMC, USB; does that not boot?

thefloweringash commented 6 years ago

This might be useful: https://github.com/thefloweringash/rock64-nix

The kernel build broke after the definition of buildLinux changed, see https://github.com/NixOS/nixpkgs/pull/35094.

cstrahan commented 6 years ago

@thefloweringash Wow, google really failed me — thanks for saving me a lot of effort!

@dezgeg I think that’s mostly what I’d need, but it lacks full HDMI support. Without HDMI, I wouldn’t have been able to debug the UART/serial issue on the RPi (systemd wasn’t automatically starting getty on ttyS1), so I’d like to ensure I/we have the option of supporting HDMI for those kinds of scenarios.

cstrahan commented 6 years ago

@thefloweringash After a few patches to account for changes in nixpkgs, I got your repo working.

Now, if only I could convince the Rock64 to display on my TV and/or capture card (its HDMI only seems to work with my two computer monitors)...

timokau commented 6 years ago

What is the status of this? I see that there is at least some rock64 specific stuff in nixpkgs. The device isn't listed in the wiki.

Mic92 commented 6 years ago

I currently run a board using @thefloweringash's repository. It is working fine for me. I have also a monitor attached as it is powering our office dashboard.

samueldr commented 6 years ago

That board isn't the only one known to work with NixOS, but not documented on the Wiki. I personally will only document boards I had personal experience with, or for some pages, where I had enough information already available on-hand to fixup the pages.

As for other ARM devices, contributors are welcome to add as much information they want (hopefully, all that is necessary.) If you need a hand for integrating that information on the Wiki, get in touch with me.

timokau commented 6 years ago

Any reason not to include support in upstream nixpkgs?

Mic92 commented 6 years ago

The kernel was still using import-from-derivation which needs to be removed.

thefloweringash commented 5 years ago

I have a couple of projects on GitHub defining bootable images for the Rock64 and Samsung Chromebook Plus. I would like to get these integrated upstream if I can. I haven't found a lot of time to work on these projects lately.

Some context: To make an image bootable, it requires a boot loader. The current images assume the board can bring its own boot loader, or in the case of the RPi, provides one in a fat partition. The rock64 can bring its own boot loader, but it can also read one from the card if it's located at lba 64. The chromebook plus uses the depthcharge boot loader, which uses gpt metadata to locate the kernel.

(I believe there's a possible simplification here. Presently the image splits /boot (fat) and / (ext4), but uboot can read ext4. We could put only the RPi specific boot support files in a fat partition, and have /boot and / be the same ext4. This would require extending the ext4 image builder to allow including files outside of the nix store, but it's not hard, only fiddly. Then we can remove the section on the wiki about resizing it).

In the SBC space it's also idiomatic to have an sd image that's not only bootable, but also usable as the current system. This seems a bit odd, like distributing linux distributions as hard drive images, instead of bootable live environments that contain installers, but it's the way things are. If not for this requirement, we could save a lot of download and card writing time by using the same squashfs style as the main installer. I've switched my repos to compressing the images with xz which reduces them from ~2gb to ~300mb, but this means you can't just grab any flashing tool and write the image, but also have to find an xz decompressor.

From the above, what's the preferred approach for making images for new devices? The options, in order of my most preferred to least preferred, seem to be:

samueldr commented 5 years ago

(I believe there's a possible simplification here. Presently the image splits /boot (fat) and / (ext4), but uboot can read ext4. We could put only the RPi specific boot support files in a fat partition, and have /boot and / be the same ext4. This would require extending the ext4 image builder to allow including files outside of the nix store, but it's not hard, only fiddly. Then we can remove the section on the wiki about resizing it).

We can. See NixOS on ARM#Disable use of /boot partition.

So yeah, the image builder could be changed to do this instead. Quoting @dezgeg

In retrospect, actually mounting the FAT partition at /boot was a bad idea... U-Boot can load the kernel+initrd+etc. just fine from the ext4 partition.


Re-reading your comment, the only thing I can see that's problematic with how images are built right now is how there is no depthcharge support for anything in NixOS. The bring-your-u-boot approach is working great I think, and hopefully will become less of an issue with ebbr.

stale[bot] commented 4 years ago

Thank you for your contributions.

This has been automatically marked as stale because it has had no activity for 180 days.

If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.

Here are suggestions that might help resolve this more quickly:

  1. Search for maintainers and people that previously touched the related code and @ mention them in a comment.
  2. Ask on the NixOS Discourse.
  3. Ask on the #nixos channel on irc.freenode.net.
AleXoundOS commented 4 years ago

Important to me.

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

Mic92 commented 3 years ago

Btw I maintain their kernel fork here:

https://nixos.wiki/wiki/NixOS_on_ARM/PINE64_ROCK64#Downstream_kernel

The mainline kernel still does not support usb3 and hdmi sound, which this kernel does. One can also remaster existing aarch64 installers with this repo: https://github.com/Mic92/nixos-aarch64-images

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

samueldr commented 3 years ago

There is nothing left actionable for us here.

We have community-based documentation, and also some support in Mic92's tooling for the board.

I see no value in those vague "$BOARD support" issues. They will never get closed if we don't close them the moment the generic image is found to be bootable, as it will serve as a hoard of misc. issues, and becomes hard to understand.

If the generic SD image is bootable (assuming a proper IBF [Initial Boot Firmware, e.g. U-Boot] is booting the board), then this issue should be closed.

As I understand it, booting the Rock64, even if HDMI and USB3 does not work out of the box with the generic SD image, is working fine. Those last issues are upstream issues.

Users may want to open a tracking issue for those mainline problems, but if someone does, please keep it updated with frequent tests and relevant information from upstream sources (e.g. the mailing lists).

If you have a specific issue about the Rock64, please open a new issue about that specific problem.

Feel free to reference this issue when opening a new issue about the Rock64.