There is little(?) reason to compress the -extra archive, but some there are some good reasons why it should be left uncompressed: 1) decompression increases boot time 2) selecting exotic formats (e.g. lzma or zstd) can actually increase the initramfs size since you now have to include support for those archive formats In the future this could be made configurable...
171 lines
5.2 KiB
Go
171 lines
5.2 KiB
Go
// Copyright 2022 Clayton Craft <clayton@craftyguy.net>
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/archive"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/bootdeploy"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist/hookdirs"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist/hookfiles"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist/hookscripts"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist/initramfs"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist/modules"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist/osksdl"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/misc"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/osutil"
|
|
"gitlab.com/postmarketOS/postmarketos-mkinitfs/pkgs/deviceinfo"
|
|
)
|
|
|
|
// set at build time
|
|
var Version string
|
|
|
|
func main() {
|
|
retCode := 0
|
|
defer func() { os.Exit(retCode) }()
|
|
|
|
outDir := flag.String("d", "/boot", "Directory to output initfs(-extra) and other boot files")
|
|
|
|
var showVersion bool
|
|
flag.BoolVar(&showVersion, "version", false, "Print version and quit.")
|
|
|
|
var disableBootDeploy bool
|
|
flag.BoolVar(&disableBootDeploy, "no-bootdeploy", false, "Disable running 'boot-deploy' after generating archives.")
|
|
flag.Parse()
|
|
|
|
if showVersion {
|
|
fmt.Printf("%s - %s\n", filepath.Base(os.Args[0]), Version)
|
|
return
|
|
}
|
|
|
|
deviceinfoFile := "/etc/deviceinfo"
|
|
if exists, err := misc.Exists(deviceinfoFile); !exists {
|
|
log.Printf("NOTE: %q not found, this file is required by mkinitfs.\n", deviceinfoFile)
|
|
return
|
|
} else if err != nil {
|
|
retCode = 1
|
|
log.Printf("received unexpected error when getting status for %q: %s", deviceinfoFile, err)
|
|
}
|
|
|
|
devinfo, err := deviceinfo.ReadDeviceinfo(deviceinfoFile)
|
|
if err != nil {
|
|
log.Println(err)
|
|
retCode = 1
|
|
return
|
|
}
|
|
|
|
// deviceinfo.InitfsCompression needs a little more post-processing
|
|
compressionFormat, compressionLevel := archive.ExtractFormatLevel(devinfo.InitfsCompression)
|
|
log.Printf("Using compression format %s with level %q\n", compressionFormat, compressionLevel)
|
|
|
|
defer misc.TimeFunc(time.Now(), "mkinitfs")
|
|
|
|
kernVer, err := osutil.GetKernelVersion()
|
|
if err != nil {
|
|
log.Println(err)
|
|
retCode = 1
|
|
return
|
|
}
|
|
|
|
// temporary working dir
|
|
workDir, err := os.MkdirTemp("", "mkinitfs")
|
|
if err != nil {
|
|
log.Println(err)
|
|
log.Println("unable to create temporary work directory")
|
|
retCode = 1
|
|
return
|
|
}
|
|
defer func() {
|
|
e := os.RemoveAll(workDir)
|
|
if e != nil && err == nil {
|
|
err = e
|
|
retCode = 1
|
|
}
|
|
}()
|
|
|
|
log.Print("Generating for kernel version: ", kernVer)
|
|
log.Print("Output directory: ", *outDir)
|
|
|
|
if err := generateArchive("initramfs", compressionFormat, compressionLevel, workDir, []filelist.FileLister{
|
|
hookdirs.New("/usr/share/mkinitfs/dirs"),
|
|
hookdirs.New("/etc/mkinitfs/dirs"),
|
|
hookfiles.New("/usr/share/mkinitfs/files"),
|
|
hookfiles.New("/etc/mkinitfs/files"),
|
|
hookscripts.New("/usr/share/mkinitfs/hooks"),
|
|
hookscripts.New("/etc/mkinitfs/hooks"),
|
|
modules.New(strings.Fields(devinfo.ModulesInitfs), "/usr/share/mkinitfs/modules"),
|
|
modules.New([]string{}, "/etc/mkinitfs/modules"),
|
|
}); err != nil {
|
|
log.Println(err)
|
|
log.Println("failed to generate: ", "initramfs")
|
|
retCode = 1
|
|
return
|
|
}
|
|
|
|
// Note: compression disabled for initramfs-extra, since it slows down boot
|
|
// and can add more requirements to the initramfs (e.g. need to add support
|
|
// for extracting zstd)
|
|
if err := generateArchive("initramfs-extra", archive.FormatNone, archive.LevelDefault, workDir, []filelist.FileLister{
|
|
hookfiles.New("/usr/share/mkinitfs/files-extra"),
|
|
hookfiles.New("/etc/mkinitfs/files-extra"),
|
|
hookscripts.New("/usr/share/mkinitfs/hooks-extra"),
|
|
hookscripts.New("/etc/mkinitfs/hooks-extra"),
|
|
modules.New([]string{}, "/usr/share/mkinitfs/modules-extra"),
|
|
modules.New([]string{}, "/etc/mkinitfs/modules-extra"),
|
|
osksdl.New(devinfo.MesaDriver),
|
|
}); err != nil {
|
|
log.Println(err)
|
|
log.Println("failed to generate: ", "initramfs-extra")
|
|
retCode = 1
|
|
return
|
|
}
|
|
|
|
// Final processing of initramfs / kernel is done by boot-deploy
|
|
if !disableBootDeploy {
|
|
if err := bootDeploy(workDir, *outDir, devinfo.UbootBoardname); err != nil {
|
|
log.Println(err)
|
|
log.Println("boot-deploy failed")
|
|
retCode = 1
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func bootDeploy(workDir, outDir, ubootBoardname string) error {
|
|
log.Print("== Using boot-deploy to finalize/install files ==")
|
|
defer misc.TimeFunc(time.Now(), "boot-deploy")
|
|
|
|
bd := bootdeploy.New(workDir, outDir, ubootBoardname)
|
|
return bd.Run()
|
|
}
|
|
|
|
func generateArchive(name string, format archive.CompressFormat, level archive.CompressLevel, path string, features []filelist.FileLister) error {
|
|
log.Printf("== Generating %s ==\n", name)
|
|
defer misc.TimeFunc(time.Now(), name)
|
|
a, err := archive.New(format, level)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fs := initramfs.New(features)
|
|
if err := a.AddItems(fs); err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Println("- Writing and verifying archive: ", name)
|
|
if err := a.Write(filepath.Join(path, name), os.FileMode(0644)); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|