From 11d087e9bed1820e9777f970aaf3789d66a825cb Mon Sep 17 00:00:00 2001 From: oliverpool Date: Wed, 23 Mar 2022 10:18:38 +0100 Subject: [PATCH] initial commit :strawberry: --- LICENSE | 30 ++++++++ README.md | 1 + cmd/compile/main.go | 171 ++++++++++++++++++++++++++++++++++++++++++++ go.mod | 5 ++ go.sum | 2 + gokrazy/cmdline.txt | 1 + gokrazy/config.txt | 7 ++ 7 files changed, 217 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 cmd/compile/main.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 gokrazy/cmdline.txt create mode 100644 gokrazy/config.txt diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1a4a4a7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,30 @@ +BSD 3-Clause License + +Copyright (c) 2017 the gokrazy authors +Copyright (c) 2022, oliverpool +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..623e3bf --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Kernel for Raspberry Pi 32 bits, for usage in gokrazy diff --git a/cmd/compile/main.go b/cmd/compile/main.go new file mode 100644 index 0000000..3c727d0 --- /dev/null +++ b/cmd/compile/main.go @@ -0,0 +1,171 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "io/fs" + "log" + "os" + "os/user" + "path/filepath" + "runtime" + "strconv" + "strings" + + "github.com/magefile/mage/sh" +) + +func main() { + if err := run(); err != nil { + log.Println(err) + + os.Exit(1) + } +} + +func execCmd(env map[string]string, stdout io.Writer, stderr io.Writer, cmd string, args ...string) func(args ...string) error { + return func(args2 ...string) error { + fmt.Println(cmd, args2) + _, err := sh.Exec(env, stdout, stderr, cmd, append(args, args2...)...) + return err + } +} + +var kernelFolderFlag = flag.String("kernel", "./linux-sources", "folder containing the kernel to compile") + +func run() error { + flag.Parse() + + // TODO new version check + + kernelFolder, err := filepath.Abs(*kernelFolderFlag) + if err != nil { + return err + } + + fmt.Println("[kernel]", kernelFolder) + + dockerRun := execCmd(nil, os.Stdout, os.Stderr, + "docker", + "run", + "-it", // to forward interrupt signals + "--rm", // cleanup afterwards + "-v", kernelFolder+":/root/armhf", + "ghcr.io/oliverpool/crossbuild-armhf:impish-20220316", + ) + // change the owner of the files inside docker to the current user + chown := func(folder string) error { + user, err := user.Current() + if err != nil { + return err + } + return dockerRun("chown", "-R", user.Uid+":"+user.Gid, folder) + } + + // default raspberry pi config according to https://www.raspberrypi.com/documentation/computers/linux_kernel.html#cross-compiling-the-kernel + if err := dockerRun("make", "bcmrpi_defconfig"); err != nil { + return err + } + if err := chown(".config"); err != nil { + return err + } + + // adjust config to add CONFIG_SQUASHFS + configPath := filepath.Join(kernelFolder, ".config") + err = adjustTextFile(configPath, func(line string) bool { + return strings.HasPrefix(line, "CONFIG_SQUASHFS=") + }, []string{ + "CONFIG_SQUASHFS=y", + }) + if err != nil { + return err + } + + // compile kernel and dtbs + if err := dockerRun("make", "zImage", "dtbs", "-j"+strconv.Itoa(runtime.NumCPU())); err != nil { + return err + } + if err := chown("arch/arm/boot"); err != nil { + return err + } + + bootFolder := filepath.Join(kernelFolder, "arch", "arm", "boot") + dstFolder := filepath.Join(".", "dist") + os.RemoveAll(dstFolder) // ignore any error + if err = os.MkdirAll(dstFolder, 0755); err != nil { + return err + } + + // copy and rename kernel + if err = sh.Copy(filepath.Join(dstFolder, "vmlinuz"), filepath.Join(bootFolder, "zImage")); err != nil { + return err + } + + // copy dtb files + files, err := filepath.Glob(filepath.Join(bootFolder, "dts", "bcm*-rpi-*.dtb")) + if err != nil { + return err + } + // copy config and cmdline files + files = append(files, "./gokrazy/cmdline.txt", "./gokrazy/config.txt") + for _, file := range files { + dtbName := filepath.Base(file) + if err = sh.Copy(filepath.Join(dstFolder, dtbName), file); err != nil { + return err + } + } + + return nil +} + +func adjustTextFile(path string, skipLine func(string) bool, appendLines []string) error { + b, stat, err := readFile(path) // read the whole file in memory, since we are going to overwrite it + if err != nil { + return err + } + + dst, err := os.OpenFile(path, os.O_TRUNC|os.O_WRONLY, stat.Mode()) + if err != nil { + return err + } + defer dst.Close() + w := bufio.NewWriter(dst) + + for _, line := range strings.Split(string(b), "\n") { + if skipLine(line) { + continue + } + _, err = w.WriteString(line + "\n") + if err != nil { + return err + } + } + for _, line := range appendLines { + _, err = w.WriteString(line + "\n") + if err != nil { + return err + } + } + err = w.Flush() + if err != nil { + return err + } + return dst.Close() +} + +func readFile(path string) ([]byte, fs.FileInfo, error) { + f, err := os.Open(path) + if err != nil { + return nil, nil, err + } + defer f.Close() + b, err := io.ReadAll(f) + if err != nil { + return b, nil, err + } + + stats, err := f.Stat() + return b, stats, err +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..dd04a43 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/oliverpool/kernel-rpi-os-32 + +go 1.18 + +require github.com/magefile/mage v1.13.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..9739604 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/magefile/mage v1.13.0 h1:XtLJl8bcCM7EFoO8FyH8XK3t7G5hQAeK+i4tq+veT9M= +github.com/magefile/mage v1.13.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= diff --git a/gokrazy/cmdline.txt b/gokrazy/cmdline.txt new file mode 100644 index 0000000..695997c --- /dev/null +++ b/gokrazy/cmdline.txt @@ -0,0 +1 @@ +root=/dev/mmcblk0p2 init=/gokrazy/init rootwait panic=10 oops=panic diff --git a/gokrazy/config.txt b/gokrazy/config.txt new file mode 100644 index 0000000..e4cc7f5 --- /dev/null +++ b/gokrazy/config.txt @@ -0,0 +1,7 @@ +# See https://www.raspberrypi.com/documentation/computers/config_txt.html + +enable_uart=0 + +kernel=vmlinuz + +disable_splash=1