14 Commits
2.2 ... 2.3.1

Author SHA1 Message Date
Clayton Craft
1a99953aa2 bootdeploy: fallback to vmlinuz* kernels when zboot is set (MR 47)
Some kernel packages (e.g. linux-lts in Alpine) don't ship linux.efi, so
this needs to fallback to "vmlinuz" or else it won't be able to find a
kernel for boot-deploy.
2024-01-29 15:32:25 -08:00
Clayton Craft
e2f4e6254f modules: fix issue with some module extensions being ignored in dirs (MR 46)
There are several valid extensions that kernel modules can have, and the
list I had here was not complete... this meant that mkinitfs would fail
to include modules with extensions like ".ko.gz" when searching
directories.

This makes the check for a "valid" module file name a lot simpler,
allowing any file with ".ko" in the file name. While it's possible for a
non-module file to have ".ko" somewhere in the file name, it seems
unlikely if it's in the kernel modules directory... and this is an OK
compromise for now.
2024-01-29 10:16:28 -08:00
Clayton Craft
2efeb4510d doc: add new deviceinfo var for sd-boot (MR 44) 2024-01-26 11:12:12 -08:00
Caleb Connolly
f0b3c1d992 bootdeploy: support zboot kernel image (MR 44)
As we move towards UEFI on more devices, we want to use systemd-boot and
kernel images built with CONFIG_ZBOOT. However, these images aren't
compatible with existing Android bootloaders. As a result, we must
install both the old vmlinuz image for old bootloaders, and the fancy
new self-extracting EFI image.

When using systemd_boot, use linux.efi as the kernel file name instead
of globbing on vmlinuz*.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
2024-01-26 11:12:11 -08:00
Caleb Connolly
98bdb23f01 deviceinfo: parse GenerateSystemdBoot option (MR 44)
This will be used to adjust behaviour when using systemd boot

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
2024-01-26 11:06:37 -08:00
Clayton Craft
6618e564ad doc: drop unused deviceinfo_mesa_driver (MR 45)
Yay, one less deviceinfo var!
2024-01-26 11:05:23 -08:00
Clayton Craft
6df75d5682 deviceinfo: clean up unused MesaDriver (MR 45)
This deviceinfo var is no longer used in mkinitfs (see previous
commits).
2024-01-26 11:05:17 -08:00
Clayton Craft
9475572811 filelist/osksdl: drop module / support for osk-sdl (MR 42)
This removes code specific to installing osk-sdl in the initramfs
archive. osk-sdl has been deprecated / removed from postmarketOS for FDE
unlocking (in favor of using the app "unl0kr"), and other distros should
consider doing the same.
2023-11-24 18:13:26 -08:00
Pablo Correa Gómez
2b467eb77f Do not support loading modules from "deviceinfo_modules_initfs" (MR 38)
This variable will dissappear from the deviceinfo at some point:
https://gitlab.com/postmarketOS/pmaports/-/merge_requests/4169
so after it does, it would not make much sense to keep its use around
2023-11-24 18:01:24 -08:00
Clayton Craft
d77e1cd11d filelist/osk-sdl: add deprecation warning
Co-authored-by: Oliver Smith <ollieparanoid@postmarketos.org>
2023-10-12 23:26:16 -07:00
Clayton Craft
2ec78bfcfc mkinitfs: print error when failure to rm tmp dir, and make it non-fatal (MR 40)
This prints the error when the work dir can't be removed. This also
changes mkinitfs so that it does't fail in this situation.

The reasoning for this change in behavior is that mkinitfs returning
non-zero will signal to the caller that there's potentially a problem
with configuring boot-related stuff on their system, and a failure to rm
the work dir is just noise. If the cause of that failure is a deeper
problem, the log message should help figure it out.

fixes #35
2023-08-24 17:13:15 -07:00
Clayton Craft
fedf55b573 filelist/*: support comment lines starting with # (MR 41) 2023-08-24 17:11:47 -07:00
Clayton Craft
30681d2f0a filelist/*: skip empty lines (MR 41)
fixes #36
2023-08-24 17:11:22 -07:00
Clayton Craft
74de5f9798 mkinitfs: handle errors from archive.AddItems (MR 41) 2023-08-24 17:10:12 -07:00
10 changed files with 102 additions and 236 deletions

View File

@@ -9,7 +9,6 @@ import (
"log"
"os"
"path/filepath"
"strings"
"time"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/archive"
@@ -20,7 +19,6 @@ import (
"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"
@@ -80,8 +78,8 @@ func main() {
defer func() {
e := os.RemoveAll(workDir)
if e != nil && err == nil {
err = e
retCode = 1
log.Println(e)
log.Println("unable to remove temporary work directory")
}
}()
@@ -105,10 +103,15 @@ func main() {
hookfiles.New("/etc/mkinitfs/files"),
hookscripts.New("/usr/share/mkinitfs/hooks", "/hooks"),
hookscripts.New("/etc/mkinitfs/hooks", "/hooks"),
modules.New(strings.Fields(devinfo.ModulesInitfs), "/usr/share/mkinitfs/modules"),
modules.New([]string{}, "/etc/mkinitfs/modules"),
modules.New("/usr/share/mkinitfs/modules"),
modules.New("/etc/mkinitfs/modules"),
})
initramfsAr.AddItems(initfs)
if err := initramfsAr.AddItems(initfs); err != nil {
log.Println(err)
log.Println("failed to generate: ", "initramfs")
retCode = 1
return
}
if err := initramfsAr.Write(filepath.Join(workDir, "initramfs"), os.FileMode(0644)); err != nil {
log.Println(err)
log.Println("failed to generate: ", "initramfs")
@@ -132,11 +135,15 @@ func main() {
hookfiles.New("/etc/mkinitfs/files-extra"),
hookscripts.New("/usr/share/mkinitfs/hooks-extra", "/hooks-extra"),
hookscripts.New("/etc/mkinitfs/hooks-extra", "/hooks-extra"),
modules.New([]string{}, "/usr/share/mkinitfs/modules-extra"),
modules.New([]string{}, "/etc/mkinitfs/modules-extra"),
osksdl.New(devinfo.MesaDriver),
modules.New("/usr/share/mkinitfs/modules-extra"),
modules.New("/etc/mkinitfs/modules-extra"),
})
initramfsExtraAr.AddItemsExclude(initfsExtra, initfs)
if err := initramfsExtraAr.AddItemsExclude(initfsExtra, initfs); err != nil {
log.Println(err)
log.Println("failed to generate: ", "initramfs-extra")
retCode = 1
return
}
if err := initramfsExtraAr.Write(filepath.Join(workDir, "initramfs-extra"), os.FileMode(0644)); err != nil {
log.Println(err)
log.Println("failed to generate: ", "initramfs-extra")
@@ -147,7 +154,7 @@ func main() {
// Final processing of initramfs / kernel is done by boot-deploy
if !disableBootDeploy {
if err := bootDeploy(workDir, *outDir, devinfo.UbootBoardname); err != nil {
if err := bootDeploy(workDir, *outDir, devinfo); err != nil {
log.Println(err)
log.Println("boot-deploy failed")
retCode = 1
@@ -156,10 +163,10 @@ func main() {
}
}
func bootDeploy(workDir, outDir, ubootBoardname string) error {
func bootDeploy(workDir string, outDir string, devinfo deviceinfo.DeviceInfo) error {
log.Print("== Using boot-deploy to finalize/install files ==")
defer misc.TimeFunc(time.Now(), "boot-deploy")
bd := bootdeploy.New(workDir, outDir, ubootBoardname)
bd := bootdeploy.New(workDir, outDir, devinfo)
return bd.Run()
}

View File

@@ -42,10 +42,9 @@ mkinitfs reads deviceinfo values from */usr/share/deviceinfo/deviceinfo* and
*/etc/deviceinfo*, in that order. The following variables
are *required* by mkinitfs:
- deviceinfo_generate_systemd_boot
- deviceinfo_initfs_compression
- deviceinfo_initfs_extra_compression
- deviceinfo_mesa_driver
- deviceinfo_modules_initfs
- deviceinfo_uboot_boardname
It is a design goal to keep the number of required variables from deviceinfo to
@@ -100,6 +99,9 @@ create/manage. mkinitfs reads configuration from */usr/share/mkinitfs* first, an
path(s) under the relevant directory in */etc/mkinitfs*, and changing
the destination path.
Any lines in these files that start with *#* are considered comments, and
skipped.
## /usr/share/mkinitfs/hooks, /etc/mkinitfs/hooks
## /usr/share/mkinitfs/hooks-extra*, /etc/mkinitfs/hooks-extra
@@ -121,12 +123,18 @@ create/manage. mkinitfs reads configuration from */usr/share/mkinitfs* first, an
Modules are installed in the initramfs archive under the same path they
exist on the system where mkinitfs is executed.
Any lines in these files that start with *#* are considered comments, and
skipped.
## /usr/share/mkinitfs/dirs, /etc/mkinitfs/dirs
Files with the *.dirs* extension in these directories are lists of
directories to create within the initramfs. There is no *-extra* variant,
since directories are of negligible size.
Any lines in these files that start with *#* are considered comments, and
skipped.
# BOOT-DEPLOY
After generating archives, mkinitfs will execute *boot-deploy*, using *$PATH* to

View File

@@ -10,32 +10,32 @@ import (
"path"
"path/filepath"
"strings"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/pkgs/deviceinfo"
)
type BootDeploy struct {
inDir string
outDir string
ubootBoardname string
inDir string
outDir string
devinfo deviceinfo.DeviceInfo
}
// New returns a new BootDeploy, which then runs:
//
// boot-deploy -d indir -o outDir
//
// ubootBoardname is used for copying in some u-boot files prior to running
// boot-deploy. This is optional, passing an empty string is ok if this is not
// needed.
func New(inDir, outDir, ubootBoardname string) *BootDeploy {
// devinfo is used to access some deviceinfo values, such as UbootBoardname
// and GenerateSystemdBoot
func New(inDir string, outDir string, devinfo deviceinfo.DeviceInfo) *BootDeploy {
return &BootDeploy{
inDir: inDir,
outDir: outDir,
ubootBoardname: ubootBoardname,
inDir: inDir,
outDir: outDir,
devinfo: devinfo,
}
}
func (b *BootDeploy) Run() error {
if err := copyUbootFiles(b.inDir, b.ubootBoardname); errors.Is(err, os.ErrNotExist) {
if err := copyUbootFiles(b.inDir, b.devinfo.UbootBoardname); errors.Is(err, os.ErrNotExist) {
log.Println("u-boot files copying skipped: ", err)
} else {
if err != nil {
@@ -43,15 +43,9 @@ func (b *BootDeploy) Run() error {
}
}
return bootDeploy(b.inDir, b.outDir)
}
func bootDeploy(workDir string, outDir string) error {
// boot-deploy expects the kernel to be in the same dir as initramfs.
// Assume that the kernel is in the output dir...
kernels, _ := filepath.Glob(filepath.Join(outDir, "vmlinuz*"))
if len(kernels) == 0 {
return errors.New("Unable to find any kernels at " + filepath.Join(outDir, "vmlinuz*"))
kernels, err := getKernelPath(b.outDir, b.devinfo.GenerateSystemdBoot == "true")
if err != nil {
return err
}
// Pick a kernel that does not have suffixes added by boot-deploy
@@ -71,7 +65,7 @@ func bootDeploy(workDir string, outDir string) error {
defer kernFd.Close()
kernFilename := path.Base(kernFile)
kernFileCopy, err := os.Create(filepath.Join(workDir, kernFilename))
kernFileCopy, err := os.Create(filepath.Join(b.inDir, kernFilename))
if err != nil {
return err
}
@@ -87,8 +81,8 @@ func bootDeploy(workDir string, outDir string) error {
cmd := exec.Command("boot-deploy",
"-i", "initramfs",
"-k", kernFilename,
"-d", workDir,
"-o", outDir,
"-d", b.inDir,
"-o", b.outDir,
"initramfs-extra")
cmd.Stdout = os.Stdout
@@ -100,6 +94,25 @@ func bootDeploy(workDir string, outDir string) error {
return nil
}
func getKernelPath(outDir string, zboot bool) ([]string, error) {
var kernels []string
if zboot {
kernels, _ = filepath.Glob(filepath.Join(outDir, "linux.efi"))
if len(kernels) > 0 {
return kernels, nil
}
// else fallback to vmlinuz* below
}
kernFile := "vmlinuz*"
kernels, _ = filepath.Glob(filepath.Join(outDir, kernFile))
if len(kernels) == 0 {
return nil, errors.New("Unable to find any kernels at " + filepath.Join(outDir, kernFile))
}
return kernels, nil
}
// Copy copies the file at srcFile path to a new file at dstFile path
func copy(srcFile, dstFile string) error {
out, err := os.Create(dstFile)

View File

@@ -6,6 +6,7 @@ import (
"log"
"os"
"path/filepath"
"strings"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist"
)
@@ -44,6 +45,10 @@ func (h *HookDirs) List() (*filelist.FileList, error) {
s := bufio.NewScanner(f)
for s.Scan() {
dir := s.Text()
if len(dir) == 0 || strings.HasPrefix(dir, "#") {
continue
}
files.Add(dir, dir)
}
}

View File

@@ -58,7 +58,12 @@ func slurpFiles(fd io.Reader) (*filelist.FileList, error) {
s := bufio.NewScanner(fd)
for s.Scan() {
src, dest, has_dest := strings.Cut(s.Text(), ":")
line := s.Text()
if len(line) == 0 || strings.HasPrefix(line, "#") {
continue
}
src, dest, has_dest := strings.Cut(line, ":")
fFiles, err := misc.GetFiles([]string{src}, true)
if err != nil {

View File

@@ -17,14 +17,11 @@ import (
type Modules struct {
modulesListPath string
modulesList []string
}
// New returns a new Modules that will use the given moduleto provide a list
// of script files.
func New(modulesList []string, modulesListPath string) *Modules {
// New returns a new Modules that will read in lists of kernel modules in the given path.
func New(modulesListPath string) *Modules {
return &Modules{
modulesList: modulesList,
modulesListPath: modulesListPath,
}
}
@@ -52,20 +49,6 @@ func (m *Modules) List() (*filelist.FileList, error) {
files.Add(file, file)
}
// slurp up given list of modules
if len(m.modulesList) > 0 {
log.Printf("-- Including kernel modules from deviceinfo")
for _, module := range m.modulesList {
if modFilelist, err := getModule(module, modDir); err != nil {
return nil, fmt.Errorf("unable to get modules from deviceinfo: %w", err)
} else {
for _, file := range modFilelist {
files.Add(file, file)
}
}
}
}
// slurp up modules from lists in modulesListPath
log.Printf("- Searching for kernel modules from %s", m.modulesListPath)
fileInfo, err := os.ReadDir(m.modulesListPath)
@@ -95,6 +78,9 @@ func slurpModules(fd io.Reader, modDir string) (*filelist.FileList, error) {
s := bufio.NewScanner(fd)
for s.Scan() {
line := s.Text()
if len(line) == 0 || strings.HasPrefix(line, "#") {
continue
}
dir, file := filepath.Split(line)
if file == "" {
// item is a directory
@@ -132,7 +118,9 @@ func getModulesInDir(modPath string) (files []string, err error) {
// Unable to walk path
return err
}
if filepath.Ext(path) != ".ko" && filepath.Ext(path) != ".xz" {
// this assumes module names are in the format <name>.ko[.format],
// where ".format" (e.g. ".gz") is optional.
if !strings.Contains(".ko", path) {
return nil
}
files = append(files, path)
@@ -194,7 +182,12 @@ func getModuleDeps(modName string, modulesDep io.Reader) ([]string, error) {
s := bufio.NewScanner(modulesDep)
for s.Scan() {
fields := strings.Fields(s.Text())
line := s.Text()
if len(line) == 0 || strings.HasPrefix(line, "#") {
continue
}
fields := strings.Fields(line)
if len(fields) == 0 {
continue
}

View File

@@ -1,158 +0,0 @@
package osksdl
import (
"bufio"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/misc"
)
type OskSdl struct {
mesaDriver string
}
// New returns a new HookScripts that will use the given path to provide a list
// of script files.
func New(mesaDriverName string) *OskSdl {
return &OskSdl{
mesaDriver: mesaDriverName,
}
}
// Get a list of files and their dependencies related to supporting rootfs full
// disk (d)encryption
func (s *OskSdl) List() (*filelist.FileList, error) {
files := filelist.NewFileList()
if exists, err := misc.Exists("/usr/bin/osk-sdl"); !exists {
return files, nil
} else if err != nil {
return files, fmt.Errorf("received unexpected error when getting status for %q: %w", "/usr/bin/osk-sdl", err)
}
log.Println("- Including osk-sdl support")
confFiles := []string{
"/etc/osk.conf",
"/etc/ts.conf",
"/etc/pointercal",
"/etc/fb.modes",
"/etc/directfbrc",
}
confFileList, err := misc.GetFiles(confFiles, false)
if err != nil {
return nil, fmt.Errorf("getFdeFiles: failed to add files: %w", err)
}
for _, file := range confFileList {
files.Add(file, file)
}
// osk-sdl
oskFiles := []string{
"/usr/bin/osk-sdl",
"/sbin/cryptsetup",
"/usr/lib/libGL.so.1",
}
if oskFileList, err := misc.GetFiles(oskFiles, true); err != nil {
return nil, fmt.Errorf("getFdeFiles: failed to add files: %w", err)
} else {
for _, file := range oskFileList {
files.Add(file, file)
}
}
fontFile, err := getOskConfFontPath("/etc/osk.conf")
if err != nil {
return nil, fmt.Errorf("getFdeFiles: failed to add file %q: %w", fontFile, err)
}
files.Add(fontFile, fontFile)
// Directfb
dfbFiles := []string{}
err = filepath.Walk("/usr/lib/directfb-1.7-7", func(path string, f os.FileInfo, err error) error {
if filepath.Ext(path) == ".so" {
dfbFiles = append(dfbFiles, path)
}
return nil
})
if err != nil {
return nil, fmt.Errorf("getFdeFiles: failed to add file %w", err)
}
if dfbFileList, err := misc.GetFiles(dfbFiles, true); err != nil {
return nil, fmt.Errorf("getFdeFiles: failed to add files: %w", err)
} else {
for _, file := range dfbFileList {
files.Add(file, file)
}
}
// tslib
tslibFiles := []string{}
err = filepath.Walk("/usr/lib/ts", func(path string, f os.FileInfo, err error) error {
if filepath.Ext(path) == ".so" {
tslibFiles = append(tslibFiles, path)
}
return nil
})
if err != nil {
return nil, fmt.Errorf("getFdeFiles: failed to add file: %w", err)
}
libts, _ := filepath.Glob("/usr/lib/libts*")
tslibFiles = append(tslibFiles, libts...)
if tslibFileList, err := misc.GetFiles(tslibFiles, true); err != nil {
return nil, fmt.Errorf("getFdeFiles: failed to add files: %w", err)
} else {
for _, file := range tslibFileList {
files.Add(file, file)
}
}
// mesa hw accel
if s.mesaDriver != "" {
mesaFiles := []string{
"/usr/lib/libEGL.so.1",
"/usr/lib/libGLESv2.so.2",
"/usr/lib/libgbm.so.1",
"/usr/lib/libudev.so.1",
"/usr/lib/xorg/modules/dri/" + s.mesaDriver + "_dri.so",
}
if mesaFileList, err := misc.GetFiles(mesaFiles, true); err != nil {
return nil, fmt.Errorf("getFdeFiles: failed to add files: %w", err)
} else {
for _, file := range mesaFileList {
files.Add(file, file)
}
}
}
return files, nil
}
func getOskConfFontPath(oskConfPath string) (string, error) {
var path string
f, err := os.Open(oskConfPath)
if err != nil {
return path, err
}
defer f.Close()
s := bufio.NewScanner(f)
for s.Scan() {
fields := strings.Fields(s.Text())
// "key = val" is 3 fields
if len(fields) > 2 && fields[0] == "keyboard-font" {
path = fields[2]
}
}
if exists, err := misc.Exists(path); !exists {
return path, fmt.Errorf("unable to find font: %s", path)
} else if err != nil {
return path, fmt.Errorf("received unexpected error when getting status for %q: %w", path, err)
}
return path, nil
}

View File

@@ -18,9 +18,8 @@ import (
type DeviceInfo struct {
InitfsCompression string
InitfsExtraCompression string
MesaDriver string
ModulesInitfs string
UbootBoardname string
GenerateSystemdBoot string
}
// Reads the relevant entries from "file" into DeviceInfo struct

View File

@@ -12,8 +12,7 @@ import (
// Test ReadDeviceinfo and the logic of reading from multiple files
func TestReadDeviceinfo(t *testing.T) {
modules_expected := "panfrost foo bar bazz"
mesa_expected := "msm"
compression_expected := "gz -9"
var devinfo DeviceInfo
err := devinfo.ReadDeviceinfo("./test_resources/deviceinfo-missing")
@@ -28,11 +27,8 @@ func TestReadDeviceinfo(t *testing.T) {
if err != nil {
t.Errorf("received an unexpected err: %s", err)
}
if devinfo.ModulesInitfs != modules_expected {
t.Errorf("expected %q, got: %q", modules_expected, devinfo.ModulesInitfs)
}
if devinfo.MesaDriver != mesa_expected {
t.Errorf("expected %q, got: %q", mesa_expected, devinfo.MesaDriver)
if devinfo.InitfsCompression != compression_expected {
t.Errorf("expected %q, got: %q", compression_expected, devinfo.InitfsCompression)
}
}
@@ -44,9 +40,9 @@ func TestNameToField(t *testing.T) {
}{
{"deviceinfo_dtb", "Dtb"},
{"dtb", "Dtb"},
{"deviceinfo_modules_initfs", "ModulesInitfs"},
{"deviceinfo_initfs_compression", "InitfsCompression"},
{"modules_initfs", "ModulesInitfs"},
{"deviceinfo_modules_initfs___", "ModulesInitfs"},
{"deviceinfo_initfs_compression___", "InitfsCompression"},
{"deviceinfo_initfs_extra_compression", "InitfsExtraCompression"},
}
@@ -67,14 +63,12 @@ func TestUnmarshal(t *testing.T) {
in string
expected string
}{
{"ModulesInitfs", "deviceinfo_modules_initfs=\"panfrost foo bar bazz\"\n", "panfrost foo bar bazz"},
{"ModulesInitfs", "deviceinfo_modules_initfs=\"panfrost foo bar bazz\"", "panfrost foo bar bazz"},
{"InitfsCompression", "deviceinfo_initfs_compression=\"gzip:-9\"\n", "gzip:-9"},
// line with multiple '='
{"InitfsCompression", "deviceinfo_initfs_compression=zstd:--foo=1 -T0 --bar=bazz", "zstd:--foo=1 -T0 --bar=bazz"},
// empty option
{"ModulesInitfs", "deviceinfo_modules_initfs=\"\"\n", ""},
{"InitfsCompression", "deviceinfo_initfs_compression=\"\"\n", ""},
// line with comment at the end
{"MesaDriver", "deviceinfo_mesa_driver=\"panfrost\" # this is a nice driver", "panfrost"},
{"", "# this is a comment!\n", ""},
// empty lines are fine
{"", "", ""},

View File

@@ -1,2 +1,2 @@
deviceinfo_modules_initfs="panfrost foo bar bazz"
deviceinfo_initfs_compression="gz -9"
deviceinfo_mesa_driver="panfrost"