• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2022 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #pragma once
17 
18 #include <utility>
19 #include <optional>
20 #include <string>
21 #include <vector>
22 
23 #include "host/libs/config/cuttlefish_config.h"
24 #include "common/libs/utils/environment.h"
25 
26 namespace cuttlefish {
27 
28 // For licensing and build reproducibility reasons, pick up the bootloaders
29 // from the host Linux distribution (if present) and pack them into the
30 // automatically generated ESP. If the user wants their own bootloaders,
31 // they can use -esp_image=/path/to/esp.img to override, so we don't need
32 // to accommodate customizations of this packing process.
33 
34 // Currently we only support Debian based distributions, and GRUB is built
35 // for those distros to always load grub.cfg from EFI/debian/grub.cfg, and
36 // nowhere else. If you want to add support for other distros, make the
37 // extra directories below and copy the initial grub.cfg there as well
38 //
39 // Currently the Cuttlefish bootloaders are built only for x86 (32-bit),
40 // ARM (QEMU only, 32-bit) and AArch64 (64-bit), and U-Boot will hard-code
41 // these search paths. Install all bootloaders to one of these paths.
42 // NOTE: For now, just ignore the 32-bit ARM version, as Debian doesn't
43 //       build an EFI monolith for this architecture.
44 // These are the paths Debian installs the monoliths to. If another distro
45 // uses an alternative monolith path, add it to this table
46 static constexpr char kBootSrcPathIA32[] = "/usr/lib/grub/i386-efi/monolithic/grubia32.efi";
47 static constexpr char kBootDestPathIA32[] = "/EFI/BOOT/BOOTIA32.EFI";
48 
49 static constexpr char kBootSrcPathAA64[] = "/usr/lib/grub/arm64-efi/monolithic/grubaa64.efi";
50 static constexpr char kBootDestPathAA64[] = "/EFI/BOOT/BOOTAA64.EFI";
51 
52 static constexpr char kMultibootModuleSrcPathIA32[] = "/usr/lib/grub/i386-efi/multiboot.mod";
53 static constexpr char kMultibootModuleDestPathIA32[] = "/EFI/modules/multiboot.mod";
54 
55 static constexpr char kMultibootModuleSrcPathAA64[] = "/usr/lib/grub/arm64-efi/multiboot.mod";
56 static constexpr char kMultibootModuleDestPathAA64[] = "/EFI/modules/multiboot.mod";
57 
58 static constexpr char kKernelDestPath[] = "/vmlinuz";
59 static constexpr char kInitrdDestPath[] = "/initrd";
60 static constexpr char kZedbootDestPath[] = "/zedboot.zbi";
61 static constexpr char kMultibootBinDestPath[] = "/multiboot.bin";
62 
63 // TODO(b/260338443, b/260337906) remove ubuntu and debian variations
64 // after migrating to grub-mkimage or adding grub binaries as a prebuilt
65 static constexpr char kGrubDebianConfigDestPath[] = "/EFI/debian/grub.cfg";
66 static constexpr char kGrubUbuntuConfigDestPath[] = "/EFI/ubuntu/grub.cfg";
67 static constexpr char kGrubConfigDestDirectoryPath[] = "/boot/grub";
68 static constexpr char kGrubConfigDestPath[] = "/boot/grub/grub.cfg";
69 
70 const std::vector<std::string> kGrubModulesX86 =
71     {"normal", "configfile", "linux", "linuxefi", "multiboot",
72      "ls", "cat", "help", "fat", "part_msdos", "part_gpt"};
73 static constexpr char kGrubModulesPath[] = "/usr/lib/grub/";
74 static constexpr char kGrubModulesX86Name[] = "i386-efi";
75 static constexpr char kGrubModulesArm64Name[] = "arm64-efi";
76 
77 class LinuxEspBuilder final {
78  public:
79   LinuxEspBuilder() = delete;
LinuxEspBuilder(std::string image_path)80   LinuxEspBuilder(std::string image_path): image_path_(std::move(image_path)) {}
81 
82   LinuxEspBuilder& Argument(std::string key, std::string value) &;
83   LinuxEspBuilder& Argument(std::string value) &;
84   LinuxEspBuilder& Root(std::string root) &;
85   LinuxEspBuilder& Kernel(std::string kernel) &;
86   LinuxEspBuilder& Initrd(std::string initrd) &;
87   LinuxEspBuilder& Architecture(Arch arch) &;
88 
89   bool Build() const;
90 
91  private:
92   std::string DumpConfig() const;
93 
94   const std::string image_path_;
95   std::vector<std::pair<std::string, std::string>> arguments_;
96   std::vector<std::string> single_arguments_;
97   std::string root_;
98   std::string kernel_;
99   std::string initrd_;
100   std::optional<Arch> arch_;
101 };
102 
103 class FuchsiaEspBuilder {
104  public:
105   FuchsiaEspBuilder() = delete;
FuchsiaEspBuilder(std::string image_path)106   FuchsiaEspBuilder(std::string image_path): image_path_(std::move(image_path)) {}
107 
108   FuchsiaEspBuilder& MultibootBinary(std::string multiboot) &;
109   FuchsiaEspBuilder& Zedboot(std::string zedboot) &;
110   FuchsiaEspBuilder& Architecture(Arch arch) &;
111 
112   bool Build() const;
113 
114  private:
115   std::string DumpConfig() const;
116 
117   const std::string image_path_;
118   std::string multiboot_bin_;
119   std::string zedboot_;
120   std::optional<Arch> arch_;
121 };
122 
123 bool NewfsMsdos(const std::string& data_image, int data_image_mb,
124                 int offset_num_mb);
125 
126 bool CanGenerateEsp(Arch arch);
127 
128 } // namespace cuttlefish
129