blob: 78eccfbd6bf55dc16a1f6836001dd769258ae867 [file] [log] [blame]
Lorenz Brunae0d90d2019-09-05 17:53:56 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package main
18
19import (
20 "fmt"
21 "io/ioutil"
22 "os"
23 "smalltown/generated/common"
24 "smalltown/internal/config"
25
26 "github.com/diskfs/go-diskfs"
27 "github.com/diskfs/go-diskfs/disk"
28 "github.com/diskfs/go-diskfs/filesystem"
29 "github.com/diskfs/go-diskfs/partition/gpt"
30 "github.com/naoina/toml"
31)
32
33var SmalltownDataPartition gpt.Type = gpt.Type("9eeec464-6885-414a-b278-4305c51f7966")
34
35func mibToSectors(size uint64) uint64 {
36 return (size * 1024 * 1024) / 512
37}
38
39var cfg = config.Config{
40 NodeName: "smalltown-testing",
41 DataDirectory: "/data",
42 ExternalHost: "",
43 TrustBackend: common.TrustBackend_DUMMY,
44}
45
46func main() {
Lorenz Brunf95909d2019-09-11 19:48:26 +020047 if len(os.Args) < 3 {
48 fmt.Println("Usage: mkimage <UEFI payload> <image path>")
49 os.Exit(2)
50 }
51 os.Remove(os.Args[2])
52 diskImg, err := diskfs.Create(os.Args[2], 3*1024*1024*1024, diskfs.Raw)
Lorenz Brunae0d90d2019-09-05 17:53:56 +020053 if err != nil {
54 fmt.Printf("Failed to create disk: %v", err)
55 os.Exit(1)
56 }
57
58 table := &gpt.Table{
59 // This is appropriate at least for virtio disks. Might need to be adjusted for real ones.
60 LogicalSectorSize: 512,
61 PhysicalSectorSize: 512,
62 ProtectiveMBR: true,
63 Partitions: []*gpt.Partition{
64 {
65 Type: gpt.EFISystemPartition,
66 Name: "ESP",
67 Start: mibToSectors(1),
68 End: mibToSectors(128) - 1,
69 },
70 {
71 Type: SmalltownDataPartition,
72 Name: "SIGNOS-DATA",
73 Start: mibToSectors(128),
74 End: mibToSectors(2560) - 1,
75 },
76 },
77 }
78 if err := diskImg.Partition(table); err != nil {
79 fmt.Printf("Failed to apply partition table: %v", err)
80 os.Exit(1)
81 }
82
83 fs, err := diskImg.CreateFilesystem(disk.FilesystemSpec{Partition: 1, FSType: filesystem.TypeFat32, VolumeLabel: "ESP"})
84 if err != nil {
85 fmt.Printf("Failed to create filesystem: %v", err)
86 os.Exit(1)
87 }
88 if err := fs.Mkdir("/EFI"); err != nil {
89 panic(err)
90 }
91 if err := fs.Mkdir("/EFI/BOOT"); err != nil {
92 panic(err)
93 }
94 if err := fs.Mkdir("/EFI/smalltown"); err != nil {
95 panic(err)
96 }
97 efiPayload, err := fs.OpenFile("/EFI/BOOT/BOOTX64.EFI", os.O_CREATE|os.O_RDWR)
98 if err != nil {
99 fmt.Printf("Failed to open EFI payload for writing: %v", err)
100 os.Exit(1)
101 }
102 efiPayloadSrc, err := os.Open(os.Args[1])
103 if err != nil {
104 fmt.Printf("Failed to open EFI payload for reading: %v", err)
105 os.Exit(1)
106 }
107 defer efiPayloadSrc.Close()
108 // If this is streamed (e.g. using io.Copy) it exposes a bug in diskfs, so do it in one go.
109 efiPayloadFull, err := ioutil.ReadAll(efiPayloadSrc)
110 if err != nil {
111 panic(err)
112 }
113 if _, err := efiPayload.Write(efiPayloadFull); err != nil {
114 fmt.Printf("Failed to write EFI payload: %v", err)
115 os.Exit(1)
116 }
117 configFile, err := fs.OpenFile("/EFI/smalltown/config.toml", os.O_CREATE|os.O_RDWR)
118 if err != nil {
119 fmt.Printf("Failed to open config for writing: %v", err)
120 os.Exit(1)
121 }
122 configData, _ := toml.Marshal(cfg)
123 if _, err := configFile.Write(configData); err != nil {
124 fmt.Printf("Failed to write config: %v", err)
125 os.Exit(1)
126 }
127 if err := diskImg.File.Close(); err != nil {
128 fmt.Printf("Failed to write image: %v", err)
129 os.Exit(1)
130 }
131 fmt.Println("Success! You can now boot smalltown.img")
132}