From 1963bbaa8f035c0a3c71233a049a7a4d7cd32711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= Date: Thu, 26 Mar 2020 13:47:40 +0800 Subject: [PATCH 1/5] firmware-utils: ptgen: add GPT support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add GPT support to ptgen, so we can generate EFI bootable images. Introduced two options: -g generate GPT partition table -G GUID use GUID for disk and increase last bit for all partitions We drop The alternate partition table to reduce size, This may cause problems when generate vmdk images or vdi images. We have to pad enough sectors when generate these images. Signed-off-by: 李国 [fixed compilation on macOS] Signed-off-by: Petr Štetiar --- tools/firmware-utils/Makefile | 2 +- tools/firmware-utils/src/ptgen.c | 341 ++++++++++++++++++++++++++++--- 2 files changed, 319 insertions(+), 24 deletions(-) diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile index 97c89eec27..561d6d868f 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile @@ -32,7 +32,7 @@ define Host/Compile $(call cc,dgfirmware) $(call cc,mksenaofw md5, -Wall --std=gnu99) $(call cc,trx2usr) - $(call cc,ptgen) + $(call cc,ptgen cyg_crc32) $(call cc,srec2bin) $(call cc,mkmylofw) $(call cc,mkcsysimg) diff --git a/tools/firmware-utils/src/ptgen.c b/tools/firmware-utils/src/ptgen.c index 0192bb65e5..83067c104d 100644 --- a/tools/firmware-utils/src/ptgen.c +++ b/tools/firmware-utils/src/ptgen.c @@ -5,6 +5,9 @@ * uses parts of afdisk * Copyright (C) 2002 by David Roetzel * + * UUID/GUID definition stolen from kernel/include/uapi/linux/uuid.h + * Copyright (C) 2010, Intel Corp. Huang Ying + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -29,17 +32,69 @@ #include #include #include +#include #include #include +#include "cyg_crc.h" #if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le16(x) bswap_16(x) #define cpu_to_le32(x) bswap_32(x) +#define cpu_to_le64(x) bswap_64(x) #elif __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_le16(x) (x) #define cpu_to_le32(x) (x) +#define cpu_to_le64(x) (x) #else #error unknown endianness! #endif +#define swap(a, b) \ + do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) + +typedef struct { + uint8_t b[16]; +} guid_t; + +#define GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ +((guid_t) \ +{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ + (b) & 0xff, ((b) >> 8) & 0xff, \ + (c) & 0xff, ((c) >> 8) & 0xff, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) + +#define GUID_STRING_LENGTH 36 + +#define GPT_SIGNATURE 0x5452415020494645ULL +#define GPT_REVISION 0x00010000 + +#define GUID_PARTITION_SYSTEM \ + GUID_INIT( 0xC12A7328, 0xF81F, 0x11d2, \ + 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B) + +#define GUID_PARTITION_BASIC_DATA \ + GUID_INIT( 0xEBD0A0A2, 0xB9E5, 0x4433, \ + 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7) + +#define GUID_PARTITION_BIOS_BOOT \ + GUID_INIT( 0x21686148, 0x6449, 0x6E6F, \ + 0x74, 0x4E, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49) + +#define GPT_HEADER_SIZE 92 +#define GPT_ENTRY_SIZE 128 +#define GPT_ENTRY_MAX 128 +#define GPT_ENTRY_NAME_SIZE 72 + +#define GPT_HEADER_SECTOR 1 +#define GPT_FIRST_ENTRY_SECTOR 2 + +#define MBR_ENTRY_MAX 4 +#define MBR_DISK_SIGNATURE_OFFSET 440 +#define MBR_PARTITION_ENTRY_OFFSET 446 +#define MBR_BOOT_SIGNATURE_OFFSET 510 + +#define DISK_SECTOR_SIZE 512 + /* Partition table entry */ struct pte { uint8_t active; @@ -55,13 +110,43 @@ struct partinfo { int type; }; +/* GPT Partition table header */ +struct gpth { + uint64_t signature; + uint32_t revision; + uint32_t size; + uint32_t crc32; + uint32_t reserved; + uint64_t self; + uint64_t alternate; + uint64_t first_usable; + uint64_t last_usable; + guid_t disk_guid; + uint64_t first_entry; + uint32_t entry_num; + uint32_t entry_size; + uint32_t entry_crc32; +} __attribute__((packed)); + +/* GPT Partition table entry */ +struct gpte { + guid_t type; + guid_t guid; + uint64_t start; + uint64_t end; + uint64_t attr; + char name[GPT_ENTRY_NAME_SIZE]; +} __attribute__((packed)); + + int verbose = 0; int active = 1; int heads = -1; int sectors = -1; int kb_align = 0; bool ignore_null_sized_partition = false; -struct partinfo parts[4]; +bool use_guid_partition_table = false; +struct partinfo parts[GPT_ENTRY_MAX]; char *filename = NULL; @@ -91,7 +176,7 @@ static long to_kbytes(const char *string) end++; if (*end) { - fprintf(stderr, "garbage after end of number\n"); + fputs("garbage after end of number\n", stderr); return 0; } @@ -132,20 +217,73 @@ static inline unsigned long round_to_kb(long sect) { return ((sect - 1) / kb_align + 1) * kb_align; } +/* Compute a CRC for guid partition table */ +static inline unsigned long gpt_crc32(void *buf, unsigned long len) +{ + return cyg_crc32_accumulate(~0L, buf, len) ^ ~0L; +} + +/* Parse a guid string to guid_t struct */ +static inline int guid_parse(char *buf, guid_t *guid) +{ + char b[4] = {0}; + char *p = buf; + unsigned i = 0; + if (strnlen(buf, GUID_STRING_LENGTH) != GUID_STRING_LENGTH) + return -1; + for (i = 0; i < sizeof(guid_t); i++) { + if (*p == '-') + p++; + if (*p == '\0') + return -1; + memcpy(b, p, 2); + guid->b[i] = strtol(b, 0, 16); + p += 2; + } + swap(guid->b[0], guid->b[3]); + swap(guid->b[1], guid->b[2]); + swap(guid->b[4], guid->b[5]); + swap(guid->b[6], guid->b[7]); + return 0; +} + +/* init an utf-16 string from utf-8 string */ +static inline void init_utf16(char *str, uint16_t *buf, unsigned bufsize) +{ + unsigned i, n = 0; + for (i = 0; i < bufsize; i++) { + if (str[n] == 0x00) { + buf[i] = 0x00; + return ; + } else if ((str[n] & 0x80) == 0x00) {//0xxxxxxx + buf[i] = cpu_to_le16(str[n++]); + } else if ((str[n] & 0xE0) == 0xC0) {//110xxxxx + buf[i] = cpu_to_le16((str[n] & 0x1F) << 6 | (str[n + 1] & 0x3F)); + n += 2; + } else if ((str[n] & 0xF0) == 0xE0) {//1110xxxx + buf[i] = cpu_to_le16((str[n] & 0x0F) << 12 | (str[n + 1] & 0x3F) << 6 | (str[n + 2] & 0x3F)); + n += 3; + } else { + buf[i] = cpu_to_le16('?'); + n++; + } + } +} + /* check the partition sizes and write the partition table */ static int gen_ptable(uint32_t signature, int nr) { - struct pte pte[4]; - unsigned long sect = 0; - int i, fd, ret = -1, start, len; + struct pte pte[MBR_ENTRY_MAX]; + unsigned long start, len, sect = 0; + int i, fd, ret = -1; - memset(pte, 0, sizeof(struct pte) * 4); + memset(pte, 0, sizeof(struct pte) * MBR_ENTRY_MAX); for (i = 0; i < nr; i++) { if (!parts[i].size) { if (ignore_null_sized_partition) continue; fprintf(stderr, "Invalid size in partition %d!\n", i); - return -1; + return ret; } pte[i].active = ((i + 1) == active) ? 0x80 : 0; @@ -165,30 +303,34 @@ static int gen_ptable(uint32_t signature, int nr) to_chs(start + len - 1, pte[i].chs_end); if (verbose) - fprintf(stderr, "Partition %d: start=%ld, end=%ld, size=%ld\n", i, (long)start * 512, ((long)start + (long)len) * 512, (long)len * 512); - printf("%ld\n", (long)start * 512); - printf("%ld\n", (long)len * 512); + fprintf(stderr, "Partition %d: start=%ld, end=%ld, size=%ld\n", + i, + (long)start * DISK_SECTOR_SIZE, + (long)(start + len) * DISK_SECTOR_SIZE, + (long)len * DISK_SECTOR_SIZE); + printf("%ld\n", (long)start * DISK_SECTOR_SIZE); + printf("%ld\n", (long)len * DISK_SECTOR_SIZE); } if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { fprintf(stderr, "Can't open output file '%s'\n",filename); - return -1; + return ret; } - lseek(fd, 440, SEEK_SET); + lseek(fd, MBR_DISK_SIGNATURE_OFFSET, SEEK_SET); if (write(fd, &signature, sizeof(signature)) != sizeof(signature)) { - fprintf(stderr, "write failed.\n"); + fputs("write failed.\n", stderr); goto fail; } - lseek(fd, 446, SEEK_SET); - if (write(fd, pte, sizeof(struct pte) * 4) != sizeof(struct pte) * 4) { - fprintf(stderr, "write failed.\n"); + lseek(fd, MBR_PARTITION_ENTRY_OFFSET, SEEK_SET); + if (write(fd, pte, sizeof(struct pte) * MBR_ENTRY_MAX) != sizeof(struct pte) * MBR_ENTRY_MAX) { + fputs("write failed.\n", stderr); goto fail; } - lseek(fd, 510, SEEK_SET); + lseek(fd, MBR_BOOT_SIGNATURE_OFFSET, SEEK_SET); if (write(fd, "\x55\xaa", 2) != 2) { - fprintf(stderr, "write failed.\n"); + fputs("write failed.\n", stderr); goto fail; } @@ -198,20 +340,161 @@ fail: return ret; } +/* check the partition sizes and write the guid partition table */ +static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr) +{ + struct pte pte; + struct gpth gpth = { + .signature = cpu_to_le64(GPT_SIGNATURE), + .revision = cpu_to_le32(GPT_REVISION), + .size = cpu_to_le32(GPT_HEADER_SIZE), + .self = cpu_to_le64(GPT_HEADER_SECTOR), + .first_usable = cpu_to_le64(GPT_FIRST_ENTRY_SECTOR + GPT_ENTRY_SIZE * GPT_ENTRY_MAX / DISK_SECTOR_SIZE), + .first_entry = cpu_to_le64(GPT_FIRST_ENTRY_SECTOR), + .disk_guid = guid, + .entry_num = cpu_to_le32(GPT_ENTRY_MAX), + .entry_size = cpu_to_le32(GPT_ENTRY_SIZE), + }; + struct gpte gpte[GPT_ENTRY_MAX]; + uint64_t start, end, sect = 0; + int fd, ret = -1; + unsigned i; + + memset(gpte, 0, GPT_ENTRY_SIZE * GPT_ENTRY_MAX); + for (i = 0; i < nr; i++) { + if (!parts[i].size) { + if (ignore_null_sized_partition) + continue; + fprintf(stderr, "Invalid size in partition %d!\n", i); + return ret; + } + start = sect + sectors; + if (kb_align != 0) + start = round_to_kb(start); + gpte[i].start = cpu_to_le64(start); + + sect = start + parts[i].size * 2; + if (kb_align == 0) + sect = round_to_cyl(sect); + gpte[i].end = cpu_to_le64(sect -1); + gpte[i].guid = guid; + gpte[i].guid.b[sizeof(guid_t) -1] += i + 1; + if (parts[i].type == 0xEF || (i + 1) == (unsigned)active) { + gpte[i].type = GUID_PARTITION_SYSTEM; + init_utf16("EFI System Partition", (uint16_t *)gpte[i].name, GPT_ENTRY_NAME_SIZE / sizeof(uint16_t)); + } else { + gpte[i].type = GUID_PARTITION_BASIC_DATA; + } + + if (verbose) + fprintf(stderr, "Partition %d: start=%" PRIu64 ", end=%" PRIu64 ", size=%" PRIu64 "\n", + i, + start * DISK_SECTOR_SIZE, sect * DISK_SECTOR_SIZE, + (sect - start) * DISK_SECTOR_SIZE); + printf("%" PRIu64 "\n", start * DISK_SECTOR_SIZE); + printf("%" PRIu64 "\n", (sect - start) * DISK_SECTOR_SIZE); + } + + gpte[GPT_ENTRY_MAX - 1].start = cpu_to_le64(GPT_FIRST_ENTRY_SECTOR + GPT_ENTRY_SIZE * GPT_ENTRY_MAX / DISK_SECTOR_SIZE); + gpte[GPT_ENTRY_MAX - 1].end = cpu_to_le64((kb_align ? round_to_kb(sectors) : (unsigned long)sectors) - 1); + gpte[GPT_ENTRY_MAX - 1].type = GUID_PARTITION_BIOS_BOOT; + gpte[GPT_ENTRY_MAX - 1].guid = guid; + gpte[GPT_ENTRY_MAX - 1].guid.b[sizeof(guid_t) -1] += GPT_ENTRY_MAX; + + end = sect + sectors - 1; + + pte.type = 0xEE; + pte.start = cpu_to_le32(GPT_HEADER_SECTOR); + pte.length = cpu_to_le32(end); + to_chs(GPT_HEADER_SECTOR, pte.chs_start); + to_chs(end, pte.chs_end); + + gpth.last_usable = cpu_to_le64(end - GPT_ENTRY_SIZE * GPT_ENTRY_MAX / DISK_SECTOR_SIZE - 1); + gpth.alternate = cpu_to_le64(end); + gpth.entry_crc32 = cpu_to_le32(gpt_crc32(gpte, GPT_ENTRY_SIZE * GPT_ENTRY_MAX)); + gpth.crc32 = cpu_to_le32(gpt_crc32((char *)&gpth, GPT_HEADER_SIZE)); + + if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { + fprintf(stderr, "Can't open output file '%s'\n",filename); + return ret; + } + + lseek(fd, MBR_DISK_SIGNATURE_OFFSET, SEEK_SET); + if (write(fd, &signature, sizeof(signature)) != sizeof(signature)) { + fputs("write failed.\n", stderr); + goto fail; + } + + lseek(fd, MBR_PARTITION_ENTRY_OFFSET, SEEK_SET); + if (write(fd, &pte, sizeof(struct pte)) != sizeof(struct pte)) { + fputs("write failed.\n", stderr); + goto fail; + } + + lseek(fd, MBR_BOOT_SIGNATURE_OFFSET, SEEK_SET); + if (write(fd, "\x55\xaa", 2) != 2) { + fputs("write failed.\n", stderr); + goto fail; + } + + if (write(fd, &gpth, GPT_HEADER_SIZE) != GPT_HEADER_SIZE) { + fputs("write failed.\n", stderr); + goto fail; + } + + lseek(fd, GPT_FIRST_ENTRY_SECTOR * DISK_SECTOR_SIZE, SEEK_SET); + if (write(fd, &gpte, GPT_ENTRY_SIZE * GPT_ENTRY_MAX) != GPT_ENTRY_SIZE * GPT_ENTRY_MAX) { + fputs("write failed.\n", stderr); + goto fail; + } + +#ifdef WANT_ALTERNATE_PTABLE + /* The alternate partition table (We omit it by default) */ + swap(gpth.self, gpth.alternate); + gpth.first_entry = cpu_to_le64(end - GPT_ENTRY_SIZE * GPT_ENTRY_MAX / DISK_SECTOR_SIZE), + gpth.crc32 = 0; + gpth.crc32 = cpu_to_le32(gpt_crc32(&gpth, GPT_HEADER_SIZE)); + + lseek(fd, end * DISK_SECTOR_SIZE - GPT_ENTRY_SIZE * GPT_ENTRY_MAX, SEEK_SET); + if (write(fd, &gpte, GPT_ENTRY_SIZE * GPT_ENTRY_MAX) != GPT_ENTRY_SIZE * GPT_ENTRY_MAX) { + fputs("write failed.\n", stderr); + goto fail; + } + + lseek(fd, end * DISK_SECTOR_SIZE, SEEK_SET); + if (write(fd, &gpth, GPT_HEADER_SIZE) != GPT_HEADER_SIZE) { + fputs("write failed.\n", stderr); + goto fail; + } + lseek(fd, (end + 1) * DISK_SECTOR_SIZE -1, SEEK_SET); + if (write(fd, "\x00", 1) != 1) { + fputs("write failed.\n", stderr); + goto fail; + } +#endif + + ret = 0; +fail: + close(fd); + return ret; +} + static void usage(char *prog) { - fprintf(stderr, "Usage: %s [-v] [-n] -h -s -o [-a 0..4] [-l ] [[-t ] -p ...] \n", prog); + fprintf(stderr, "Usage: %s [-v] [-n] [-g] -h -s -o [-a 0..4] [-l ] [-G ] [[-t ] -p ...] \n", prog); exit(EXIT_FAILURE); } int main (int argc, char **argv) { - char type = 0x83; + unsigned char type = 0x83; int ch; int part = 0; uint32_t signature = 0x5452574F; /* 'OWRT' */ + guid_t guid = GUID_INIT( signature, 0x2211, 0x4433, \ + 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x00); - while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vnl:S:")) != -1) { + while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vngl:S:G:")) != -1) { switch (ch) { case 'o': filename = optarg; @@ -222,6 +505,9 @@ int main (int argc, char **argv) case 'n': ignore_null_sized_partition = true; break; + case 'g': + use_guid_partition_table = 1; + break; case 'h': heads = (int)strtoul(optarg, NULL, 0); break; @@ -229,8 +515,8 @@ int main (int argc, char **argv) sectors = (int)strtoul(optarg, NULL, 0); break; case 'p': - if (part > 3) { - fprintf(stderr, "Too many partitions\n"); + if (part > GPT_ENTRY_MAX - 1 || (!use_guid_partition_table && part > 3)) { + fputs("Too many partitions\n", stderr); exit(EXIT_FAILURE); } parts[part].size = to_kbytes(optarg); @@ -250,6 +536,12 @@ int main (int argc, char **argv) case 'S': signature = strtoul(optarg, NULL, 0); break; + case 'G': + if (guid_parse(optarg, &guid)) { + fputs("Invalid guid string\n", stderr); + exit(EXIT_FAILURE); + } + break; case '?': default: usage(argv[0]); @@ -259,5 +551,8 @@ int main (int argc, char **argv) if (argc || (heads <= 0) || (sectors <= 0) || !filename) usage(argv[0]); + if (use_guid_partition_table) + return gen_gptable(signature, guid, part) ? EXIT_FAILURE : EXIT_SUCCESS; + return gen_ptable(signature, part) ? EXIT_FAILURE : EXIT_SUCCESS; } From d9228514ccecfb9d1500e3a82470f66f2ea41a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= Date: Thu, 26 Mar 2020 13:51:32 +0800 Subject: [PATCH 2/5] grub2: make some change to add efi platform support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.generate boot image at Package/install section 2.move boot image to $(STAGING_DIR_IMAGE)/grub2/ 3.add efi variant to support efi platform Signed-off-by: 李国 --- package/boot/grub2/Makefile | 100 ++++++++++++++++++++------------ target/linux/x86/image/Makefile | 9 ++- 2 files changed, 68 insertions(+), 41 deletions(-) diff --git a/package/boot/grub2/Makefile b/package/boot/grub2/Makefile index 980a6e372a..840401fa3a 100644 --- a/package/boot/grub2/Makefile +++ b/package/boot/grub2/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=grub PKG_CPE_ID:=cpe:/a:gnu:grub2 PKG_VERSION:=2.04 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/grub @@ -27,14 +27,18 @@ PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/host-build.mk include $(INCLUDE_DIR)/package.mk -define Package/grub2 +define Package/grub2/Default CATEGORY:=Boot Loaders SECTION:=boot - TITLE:=GRand Unified Bootloader + TITLE:=GRand Unified Bootloader ($(1)) URL:=http://www.gnu.org/software/grub/ DEPENDS:=@TARGET_x86 + VARIANT:=$(1) endef +Package/grub2=$(call Package/grub2/Default,pc) +Package/grub2-efi=$(call Package/grub2/Default,efi) + define Package/grub2-editenv CATEGORY:=Utilities SECTION:=utils @@ -42,6 +46,7 @@ define Package/grub2-editenv TITLE:=Grub2 Environment editor URL:=http://www.gnu.org/software/grub/ DEPENDS:=@TARGET_x86 + VARIANT:=pc endef define Package/grub2-editenv/description @@ -60,7 +65,7 @@ CONFIGURE_ARGS += \ --disable-device-mapper \ --disable-libzfs \ --disable-grub-mkfont \ - --with-platform=none + --with-platform=$(BUILD_VARIANT) HOST_CONFIGURE_VARS += \ grub_build_mkfont_excuse="don't want fonts" @@ -71,51 +76,73 @@ HOST_CONFIGURE_ARGS += \ --sbindir="$(STAGING_DIR_HOST)/bin" \ --disable-werror \ --disable-libzfs \ - --disable-nls + --disable-nls \ + --with-platform=none HOST_MAKE_FLAGS += \ TARGET_RANLIB=$(TARGET_RANLIB) \ LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a +TARGET_CFLAGS := + define Host/Configure $(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in $(Host/Configure/Default) endef -define Host/Install - $(call Host/Install/Default) - - $(INSTALL_DIR) $(STAGING_DIR_HOST)/lib/grub/grub2-generic - $(STAGING_DIR_HOST)/bin/grub-mkimage \ - -d $(STAGING_DIR_HOST)/lib/grub/i386-pc \ - -p /boot/grub \ - -O i386-pc \ - -c ./files/grub-early.cfg \ - -o $(STAGING_DIR_HOST)/lib/grub/grub2-generic/core.img \ - at_keyboard biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga - - $(INSTALL_DIR) $(STAGING_DIR_HOST)/lib/grub/grub2-iso - $(STAGING_DIR_HOST)/bin/grub-mkimage \ - -d $(STAGING_DIR_HOST)/lib/grub/i386-pc \ - -p /boot/grub \ - -O i386-pc \ - -c ./files/grub-early.cfg \ - -o $(STAGING_DIR_HOST)/lib/grub/grub2-iso/eltorito.img \ - at_keyboard biosdisk boot chain configfile iso9660 linux ls part_msdos reboot serial vga - - $(INSTALL_DIR) $(STAGING_DIR_HOST)/lib/grub/grub2-legacy - $(STAGING_DIR_HOST)/bin/grub-mkimage \ - -d $(STAGING_DIR_HOST)/lib/grub/i386-pc \ - -p /boot/grub \ - -O i386-pc \ - -c ./files/grub-early.cfg \ - -o $(STAGING_DIR_HOST)/lib/grub/grub2-legacy/core.img \ - biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga -endef - define Package/grub2/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-bios-setup $(1)/usr/sbin/ + $(INSTALL_DIR) $(STAGING_DIR_IMAGE)/grub2 + $(CP) $(PKG_BUILD_DIR)/grub-core/boot.img $(STAGING_DIR_IMAGE)/grub2/ + $(CP) $(PKG_BUILD_DIR)/grub-core/cdboot.img $(STAGING_DIR_IMAGE)/grub2/ + sed 's#msdos1#gpt1#g' ./files/grub-early.cfg >$(PKG_BUILD_DIR)/grub-early.cfg + $(STAGING_DIR_HOST)/bin/grub-mkimage \ + -d $(PKG_BUILD_DIR)/grub-core \ + -p /boot/grub \ + -O i386-pc \ + -c $(PKG_BUILD_DIR)/grub-early.cfg \ + -o $(STAGING_DIR_IMAGE)/grub2/gpt-core.img \ + at_keyboard biosdisk boot chain configfile fat linux ls part_gpt reboot serial vga + $(STAGING_DIR_HOST)/bin/grub-mkimage \ + -d $(PKG_BUILD_DIR)/grub-core \ + -p /boot/grub \ + -O i386-pc \ + -c ./files/grub-early.cfg \ + -o $(STAGING_DIR_IMAGE)/grub2/generic-core.img \ + at_keyboard biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga + $(STAGING_DIR_HOST)/bin/grub-mkimage \ + -d $(PKG_BUILD_DIR)/grub-core \ + -p /boot/grub \ + -O i386-pc \ + -c ./files/grub-early.cfg \ + -o $(STAGING_DIR_IMAGE)/grub2/eltorito.img \ + at_keyboard biosdisk boot chain configfile iso9660 linux ls part_msdos reboot serial test vga + $(STAGING_DIR_HOST)/bin/grub-mkimage \ + -d $(PKG_BUILD_DIR)/grub-core \ + -p /boot/grub \ + -O i386-pc \ + -c ./files/grub-early.cfg \ + -o $(STAGING_DIR_IMAGE)/grub2/legacy-core.img \ + biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga +endef + +define Package/grub2-efi/install + sed 's#msdos1#gpt1#g' ./files/grub-early.cfg >$(PKG_BUILD_DIR)/grub-early.cfg + $(STAGING_DIR_HOST)/bin/grub-mkimage \ + -d $(PKG_BUILD_DIR)/grub-core \ + -p /boot/grub \ + -O $(CONFIG_ARCH)-efi \ + -c $(PKG_BUILD_DIR)/grub-early.cfg \ + -o $(STAGING_DIR_IMAGE)/grub2/boot$(if $(CONFIG_x86_64),x64,ia32).efi \ + at_keyboard boot chain configfile fat linux ls part_gpt reboot serial efi_gop efi_uga + $(STAGING_DIR_HOST)/bin/grub-mkimage \ + -d $(PKG_BUILD_DIR)/grub-core \ + -p /boot/grub \ + -O $(CONFIG_ARCH)-efi \ + -c ./files/grub-early.cfg \ + -o $(STAGING_DIR_IMAGE)/grub2/iso-boot$(if $(CONFIG_x86_64),x64,ia32).efi \ + at_keyboard boot chain configfile fat iso9660 linux ls part_msdos part_gpt reboot serial test efi_gop efi_uga endef define Package/grub2-editenv/install @@ -125,4 +152,5 @@ endef $(eval $(call HostBuild)) $(eval $(call BuildPackage,grub2)) +$(eval $(call BuildPackage,grub2-efi)) $(eval $(call BuildPackage,grub2-editenv)) diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile index c0c5c8323a..4915f639fa 100644 --- a/target/linux/x86/image/Makefile +++ b/target/linux/x86/image/Makefile @@ -70,9 +70,8 @@ endef define Build/grub-install rm -fR $@.grub2 $(INSTALL_DIR) $@.grub2 - $(CP) $(STAGING_DIR_HOST)/lib/grub/i386-pc/*.img \ - $(STAGING_DIR_HOST)/lib/grub/grub2-$(GRUB2_VARIANT)/core.img \ - $@.grub2/ + $(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img $@.grub2/ + $(CP) $(STAGING_DIR_IMAGE)/grub2/$(GRUB2_VARIANT)-core.img $@.grub2/core.img echo '(hd0) $@' > $@.grub2/device.map $(STAGING_DIR_HOST)/bin/grub-bios-setup \ -m "$@.grub2/device.map" \ @@ -84,8 +83,8 @@ endef define Build/iso $(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz cat \ - $(STAGING_DIR_HOST)/lib/grub/i386-pc/cdboot.img \ - $(STAGING_DIR_HOST)/lib/grub/grub2-iso/eltorito.img \ + $(STAGING_DIR_IMAGE)/grub2/cdboot.img \ + $(STAGING_DIR_IMAGE)/grub2/eltorito.img \ > $@.boot/boot/grub/eltorito.img -$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/ mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \ From a6b7c3e672764858fd294998406ae791f5964b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= Date: Thu, 26 Mar 2020 14:05:33 +0800 Subject: [PATCH 3/5] x86: generate EFI platform bootable images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add EFI platform bootable images for x86 platforms. These images can also boot from legacy BIOS platform. EFI System Partition need to be fat12/fat16/fat32 (not need to load filesystem drivers), so the first partition of EFI images are not ext4 filesystem any more. GPT partition table has an alternate partition table, we did not generate it. This may cause problems when use these images as qemu disk (kernel can not find rootfs), we pad enough sectors will be ok. Signed-off-by: 李国 [part_magic_* refactoring, removed genisoimage checks] Signed-off-by: Petr Štetiar --- config/Config-images.in | 29 ++++++--- include/image.mk | 1 + .../base-files/files/lib/upgrade/common.sh | 62 ++++++++++++++++--- scripts/gen_image_generic.sh | 10 ++- .../x86/base-files/lib/preinit/79_move_config | 5 +- .../lib/preinit/81_upgrade_bootloader | 1 + .../x86/base-files/lib/upgrade/platform.sh | 27 +++++--- target/linux/x86/generic/config-4.19 | 1 + target/linux/x86/generic/config-5.4 | 1 + target/linux/x86/image/Makefile | 46 +++++++++++--- target/linux/x86/image/grub-efi.cfg | 13 ++++ target/linux/x86/image/grub-iso.cfg | 7 ++- 12 files changed, 165 insertions(+), 38 deletions(-) create mode 100644 target/linux/x86/image/grub-efi.cfg diff --git a/config/Config-images.in b/config/Config-images.in index e4db0482ce..4c54ac9399 100644 --- a/config/Config-images.in +++ b/config/Config-images.in @@ -188,19 +188,28 @@ menu "Target Images" select PACKAGE_grub2 default y + config GRUB_EFI_IMAGES + bool "Build GRUB EFI images (Linux x86 or x86_64 host only)" + depends on TARGET_x86 + depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS + select PACKAGE_grub2 + select PACKAGE_grub2-efi + select PACKAGE_kmod-fs-vfat + default y + config GRUB_CONSOLE bool "Use Console Terminal (in addition to Serial)" - depends on GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES default y config GRUB_SERIAL string "Serial port device" - depends on GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES default "ttyS0" config GRUB_BAUDRATE int "Serial port baud rate" - depends on GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES default 38400 if TARGET_x86_generic default 115200 @@ -211,20 +220,20 @@ menu "Target Images" config GRUB_BOOTOPTS string "Extra kernel boot options" - depends on GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES help If you don't know, just leave it blank. config GRUB_TIMEOUT string "Seconds to wait before booting the default entry" - depends on GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES default "5" help If you don't know, 5 seconds is a reasonable default. config GRUB_TITLE string "Title for the menu entry in GRUB" - depends on GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES default "OpenWrt" help This is the title of the GRUB menu entry. @@ -233,18 +242,18 @@ menu "Target Images" config ISO_IMAGES bool "Build LiveCD image (ISO)" depends on TARGET_x86 - select GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES config VDI_IMAGES bool "Build VirtualBox image files (VDI)" depends on TARGET_x86 - select GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES select PACKAGE_kmod-e1000 config VMDK_IMAGES bool "Build VMware image files (VMDK)" depends on TARGET_x86 - select GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES select PACKAGE_kmod-e1000 config TARGET_IMAGES_GZIP @@ -272,7 +281,7 @@ menu "Target Images" config TARGET_ROOTFS_PARTNAME string "Root partition on target device" - depends on GRUB_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES help Override the root partition on the final device. If left empty, it will be mounted by PARTUUID which makes the kernel find the diff --git a/include/image.mk b/include/image.mk index 8af5905c60..6204e8ab61 100644 --- a/include/image.mk +++ b/include/image.mk @@ -45,6 +45,7 @@ IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$ IMG_ROOTFS:=$(IMG_PREFIX)-rootfs IMG_COMBINED:=$(IMG_PREFIX)-combined IMG_PART_SIGNATURE:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | mkhash md5 | cut -b1-8) +IMG_PART_DISKGUID:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | mkhash md5 | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/') MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index a986cc0b5c..2cbc69e5dd 100644 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh @@ -102,6 +102,24 @@ get_magic_long() { (get_image "$@" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null } +get_magic_gpt() { + (get_image "$@" | dd bs=8 count=1 skip=64) 2>/dev/null +} + +get_magic_vfat() { + (get_image "$@" | dd bs=1 count=3 skip=54) 2>/dev/null +} + +part_magic_efi() { + local magic=$(get_magic_gpt "$@") + [ "$magic" = "EFI PART" ] +} + +part_magic_fat() { + local magic=$(get_magic_vfat "$@") + [ "$magic" = "FAT" ] +} + export_bootdevice() { local cmdline bootdisk rootpart uuid blockdev uevent line class local MAJOR MINOR DEVNAME DEVTYPE @@ -136,6 +154,17 @@ export_bootdevice() { fi done ;; + PARTUUID=????????-????-????-????-??????????02) + uuid="${rootpart#PARTUUID=}" + uuid="${uuid%02}00" + for disk in $(find /dev -type b); do + set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"') + if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then + uevent="/sys/class/block/${disk##*/}/uevent" + break + fi + done + ;; /dev/*) uevent="/sys/class/block/${rootpart##*/}/../uevent" ;; @@ -207,17 +236,34 @@ get_partitions() { # rm -f "/tmp/partmap.$filename" local part - for part in 1 2 3 4; do - set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk") + part_magic_efi "$disk" && { + #export_partdevice will fail when partition number is greater than 15, as + #the partition major device number is not equal to the disk major device number + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do + set -- $(hexdump -v -n 48 -s "$((0x380 + $part * 0x80))" -e '4/4 "%08x"" "4/4 "%08x"" "4/4 "0x%08X "' "$disk") - local type="$(( $(hex_le32_to_cpu $1) % 256))" - local lba="$(( $(hex_le32_to_cpu $2) ))" - local num="$(( $(hex_le32_to_cpu $3) ))" + local type="$1" + local lba="$(( $(hex_le32_to_cpu $4) * 0x100000000 + $(hex_le32_to_cpu $3) ))" + local end="$(( $(hex_le32_to_cpu $6) * 0x100000000 + $(hex_le32_to_cpu $5) ))" + local num="$(( $end - $lba ))" - [ $type -gt 0 ] || continue + [ "$type" = "00000000000000000000000000000000" ] && continue - printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename" - done + printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename" + done + } || { + for part in 1 2 3 4; do + set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk") + + local type="$(( $(hex_le32_to_cpu $1) % 256))" + local lba="$(( $(hex_le32_to_cpu $2) ))" + local num="$(( $(hex_le32_to_cpu $3) ))" + + [ $type -gt 0 ] || continue + + printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename" + done + } fi } diff --git a/scripts/gen_image_generic.sh b/scripts/gen_image_generic.sh index 2c57d56f07..53f73dc6e1 100755 --- a/scripts/gen_image_generic.sh +++ b/scripts/gen_image_generic.sh @@ -20,7 +20,7 @@ sect=63 cyl=$(( (KERNELSIZE + ROOTFSSIZE) * 1024 * 1024 / (head * sect * 512))) # create partition table -set $(ptgen -o "$OUTPUT" -h $head -s $sect -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE}) +set $(ptgen -o "$OUTPUT" -h $head -s $sect ${GUID:+-g} -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE} ${GUID:+-G $GUID}) KERNELOFFSET="$(($1 / 512))" KERNELSIZE="$2" @@ -30,6 +30,12 @@ ROOTFSSIZE="$(($4 / 512))" [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE" dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc -make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR" +if [ -n "$GUID" ]; then + [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$(($ROOTFSOFFSET + $ROOTFSSIZE))" conv=notrunc count="$sect" + mkfs.fat -n kernel -C "$OUTPUT.kernel" -S 512 "$(($KERNELSIZE / 1024))" + mcopy -s -i "$OUTPUT.kernel" "$KERNELDIR"/* ::/ +else + make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR" +fi dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc rm -f "$OUTPUT.kernel" diff --git a/target/linux/x86/base-files/lib/preinit/79_move_config b/target/linux/x86/base-files/lib/preinit/79_move_config index 702da9e873..338398c947 100644 --- a/target/linux/x86/base-files/lib/preinit/79_move_config +++ b/target/linux/x86/base-files/lib/preinit/79_move_config @@ -2,13 +2,14 @@ # Copyright (C) 2012-2015 OpenWrt.org move_config() { - local partdev + local partdev parttype=ext4 . /lib/upgrade/common.sh if export_bootdevice && export_partdevice partdev 1; then mkdir -p /boot - mount -t ext4 -o rw,noatime "/dev/$partdev" /boot + part_magic_fat "/dev/$partdev" && parttype=vfat + mount -t $parttype -o rw,noatime "/dev/$partdev" /boot if [ -f "/boot/$BACKUP_FILE" ]; then mv -f "/boot/$BACKUP_FILE" / fi diff --git a/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader b/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader index 3a4e756b1e..1379c9b2cb 100644 --- a/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader +++ b/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader @@ -6,6 +6,7 @@ upgrade_bootloader() { . /lib/upgrade/common.sh if [ ! -f /boot/grub/upgraded ] && export_bootdevice && export_partdevice diskdev 0; then + part_magic_efi "/dev/$diskdev" && return 0 echo "(hd0) /dev/$diskdev" > /tmp/device.map /usr/sbin/grub-bios-setup \ -m "/tmp/device.map" \ diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh index 53c751861c..ee88dfb082 100644 --- a/target/linux/x86/base-files/lib/upgrade/platform.sh +++ b/target/linux/x86/base-files/lib/upgrade/platform.sh @@ -20,7 +20,7 @@ platform_check_image() { get_partitions "/dev/$diskdev" bootdisk #extract the boot sector from the image - get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null + get_image "$@" | dd of=/tmp/image.bs count=63 bs=512b 2>/dev/null get_partitions /tmp/image.bs image @@ -37,29 +37,31 @@ platform_check_image() { } platform_copy_config() { - local partdev + local partdev parttype=ext4 if export_partdevice partdev 1; then - mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt + part_magic_fat "/dev/$partdev" && parttype=vfat + mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE" umount /mnt fi } platform_do_bootloader_upgrade() { - local bootpart + local bootpart parttable=msdos local diskdev="$1" if export_partdevice bootpart 1; then mkdir -p /tmp/boot mount -o rw,noatime "/dev/$bootpart" /tmp/boot echo "(hd0) /dev/$diskdev" > /tmp/device.map + part_magic_efi "/dev/$diskdev" && parttable=gpt echo "Upgrading bootloader on /dev/$diskdev..." grub-bios-setup \ -m "/tmp/device.map" \ -d "/tmp/boot/boot/grub" \ - -r "hd0,msdos1" \ + -r "hd0,${parttable}1" \ "/dev/$diskdev" \ && touch /boot/grub/upgraded @@ -81,7 +83,7 @@ platform_do_upgrade() { get_partitions "/dev/$diskdev" bootdisk #extract the boot sector from the image - get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b + get_image "$@" | dd of=/tmp/image.bs count=63 bs=512b >/dev/null get_partitions /tmp/image.bs image @@ -106,7 +108,7 @@ platform_do_upgrade() { while read part start size; do if export_partdevice partdev $part; then echo "Writing image to /dev/$partdev..." - get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync + get_image "$@" | dd of="/dev/$partdev" ibs=512 obs=1M skip="$start" count="$size" conv=fsync else echo "Unable to find partition $part device, skipped." fi @@ -117,4 +119,15 @@ platform_do_upgrade() { get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync platform_do_bootloader_upgrade "$diskdev" + local parttype=ext4 + part_magic_efi "/dev/$diskdev" || return 0 + + if export_partdevice partdev 1; then + part_magic_fat "/dev/$partdev" && parttype=vfat + mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt + set -- $(dd if="/dev/$diskdev" bs=1 skip=1168 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"') + sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1$4$3$2$1-$6$5-$8$7-$9/ig" /mnt/boot/grub/grub.cfg + umount /mnt + fi + } diff --git a/target/linux/x86/generic/config-4.19 b/target/linux/x86/generic/config-4.19 index 4a689ca026..ada81ce04e 100644 --- a/target/linux/x86/generic/config-4.19 +++ b/target/linux/x86/generic/config-4.19 @@ -139,6 +139,7 @@ CONFIG_FB_DEFERRED_IO=y CONFIG_FB_EFI=y CONFIG_FB_HYPERV=y # CONFIG_FB_I810 is not set +CONFIG_FB_SIMPLE=y CONFIG_FB_SYS_COPYAREA=y CONFIG_FB_SYS_FILLRECT=y CONFIG_FB_SYS_FOPS=y diff --git a/target/linux/x86/generic/config-5.4 b/target/linux/x86/generic/config-5.4 index 4a689ca026..ada81ce04e 100644 --- a/target/linux/x86/generic/config-5.4 +++ b/target/linux/x86/generic/config-5.4 @@ -139,6 +139,7 @@ CONFIG_FB_DEFERRED_IO=y CONFIG_FB_EFI=y CONFIG_FB_HYPERV=y # CONFIG_FB_I810 is not set +CONFIG_FB_SIMPLE=y CONFIG_FB_SYS_COPYAREA=y CONFIG_FB_SYS_FILLRECT=y CONFIG_FB_SYS_FOPS=y diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile index 4915f639fa..7864dfa1f8 100644 --- a/target/linux/x86/image/Makefile +++ b/target/linux/x86/image/Makefile @@ -38,6 +38,8 @@ endif ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME)) ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(IMG_PART_SIGNATURE)-02) +GPT_ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME)) +GPT_ROOTPART:=$(if $(GPT_ROOTPART),$(GPT_ROOTPART),PARTUUID=$(shell echo $(IMG_PART_DISKGUID) | sed 's/00$$/02/')) GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT)) GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE)) @@ -47,7 +49,12 @@ BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS)) define Build/combined $(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz -$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/ - PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" $(SCRIPT_DIR)/gen_image_generic.sh \ + $(if $(filter $(1),efi), + $(INSTALL_DIR) $@.boot/efi/boot + $(CP) $(STAGING_DIR_IMAGE)/grub2/boot$(if $(CONFIG_x86_64),x64,ia32).efi $@.boot/efi/boot/ + ) + PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" \ + $(if $(filter $(1),efi),GUID="$(IMG_PART_DISKGUID)") $(SCRIPT_DIR)/gen_image_generic.sh \ $@ \ $(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \ $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \ @@ -61,6 +68,7 @@ define Build/grub-config -e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \ -e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \ -e 's#@ROOTPART@#root=$(ROOTPART) rootwait#g' \ + -e 's#@GPT_ROOTPART@#root=$(GPT_ROOTPART) rootwait#g' \ -e 's#@CMDLINE@#$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE)#g' \ -e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \ -e 's#@TITLE@#$(GRUB_TITLE)#g' \ @@ -71,12 +79,12 @@ define Build/grub-install rm -fR $@.grub2 $(INSTALL_DIR) $@.grub2 $(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img $@.grub2/ - $(CP) $(STAGING_DIR_IMAGE)/grub2/$(GRUB2_VARIANT)-core.img $@.grub2/core.img + $(CP) $(STAGING_DIR_IMAGE)/grub2/$(if $(filter $(1),efi),gpt,$(GRUB2_VARIANT))-core.img $@.grub2/core.img echo '(hd0) $@' > $@.grub2/device.map $(STAGING_DIR_HOST)/bin/grub-bios-setup \ -m "$@.grub2/device.map" \ -d "$@.grub2" \ - -r "hd0,msdos1" \ + -r "hd0,$(if $(filter $(1),efi),gpt1,msdos1)" \ $@ endef @@ -87,7 +95,15 @@ define Build/iso $(STAGING_DIR_IMAGE)/grub2/eltorito.img \ > $@.boot/boot/grub/eltorito.img -$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/ + $(if $(filter $(1),efi), + mkfs.fat -C $@.boot/boot/grub/isoboot.img -S 512 1440 + mmd -i $@.boot/boot/grub/isoboot.img ::/efi ::/efi/boot + mcopy -i $@.boot/boot/grub/isoboot.img \ + $(STAGING_DIR_IMAGE)/grub2/iso-boot$(if $(CONFIG_x86_64),x64,ia32).efi \ + ::/efi/boot/boot$(if $(CONFIG_x86_64),x64,ia32).efi + ) mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \ + $(if $(filter $(1),efi),-boot-load-size 4 -c boot.cat -eltorito-alt-boot -b boot/grub/isoboot.img -no-emul-boot) \ -o $@ $@.boot $(TARGET_DIR) endef @@ -100,23 +116,37 @@ define Device/Default IMAGE/combined.vmdk := grub-config pc | combined | grub-install | qemu-image vmdk IMAGE/rootfs.img := append-rootfs IMAGE/rootfs.img.gz := append-rootfs | gzip + ARTIFACT/image-efi.iso := grub-config iso | iso efi + IMAGE/combined-efi.img := grub-config efi | combined efi | grub-install efi + IMAGE/combined-efi.img.gz := grub-config efi | combined efi | grub-install efi | gzip + IMAGE/combined-efi.vdi := grub-config efi | combined efi | grub-install efi | qemu-image vdi + IMAGE/combined-efi.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y) - IMAGES := combined.img.gz rootfs.img.gz + IMAGES-y := rootfs.img.gz + IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img.gz + IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img.gz else - IMAGES := combined.img rootfs.img + IMAGES-y := rootfs.img + IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img + IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img endif KERNEL := kernel-bin KERNEL_INSTALL := 1 KERNEL_NAME := bzImage ifeq ($(CONFIG_ISO_IMAGES),y) - ARTIFACTS := image.iso + ARTIFACTS-$$(CONFIG_GRUB_IMAGES) += image.iso + ARTIFACTS-$$(CONFIG_GRUB_EFI_IMAGES) += image-efi.iso endif ifeq ($(CONFIG_VDI_IMAGES),y) - IMAGES += combined.vdi + IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vdi + IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vdi endif ifeq ($(CONFIG_VMDK_IMAGES),y) - IMAGES += combined.vmdk + IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vmdk + IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vmdk endif + IMAGES := $$(IMAGES-y) + ARTIFACTS := $$(ARTIFACTS-y) endef $(eval $(call Image/gzip-ext4-padded-squashfs)) diff --git a/target/linux/x86/image/grub-efi.cfg b/target/linux/x86/image/grub-efi.cfg new file mode 100644 index 0000000000..14d30e88e4 --- /dev/null +++ b/target/linux/x86/image/grub-efi.cfg @@ -0,0 +1,13 @@ +@SERIAL_CONFIG@ +@TERMINAL_CONFIG@ + +set default="0" +set timeout="@TIMEOUT@" +set root='(hd0,gpt1)' + +menuentry "@TITLE@" { + linux /boot/vmlinuz @GPT_ROOTPART@ @CMDLINE@ noinitrd +} +menuentry "@TITLE@ (failsafe)" { + linux /boot/vmlinuz failsafe=true @GPT_ROOTPART@ @CMDLINE@ noinitrd +} diff --git a/target/linux/x86/image/grub-iso.cfg b/target/linux/x86/image/grub-iso.cfg index f5848b3853..4bef492a41 100644 --- a/target/linux/x86/image/grub-iso.cfg +++ b/target/linux/x86/image/grub-iso.cfg @@ -3,7 +3,12 @@ set default="0" set timeout="@TIMEOUT@" -set root='(cd)' + +if [ "${grub_platform}" = "efi" ]; then + set root='(cd0)' +else + set root='(cd)' +fi menuentry "@TITLE@" { linux /boot/vmlinuz root=/dev/sr0 rootfstype=iso9660 rootwait @CMDLINE@ noinitrd From 533b130adcc109ff257bfc4447cade2358c1eb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= Date: Fri, 27 Mar 2020 19:16:26 +0800 Subject: [PATCH 4/5] x86/64: add cdrom and iso9660 drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iso image need cdrom and iso9660 drivers to boot, otherwise it will hang when mounting the root file system Signed-off-by: 李国 --- target/linux/x86/64/config-4.19 | 4 ++++ target/linux/x86/64/config-5.4 | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/target/linux/x86/64/config-4.19 b/target/linux/x86/64/config-4.19 index f5c82dcb91..00ed09a4a6 100644 --- a/target/linux/x86/64/config-4.19 +++ b/target/linux/x86/64/config-4.19 @@ -69,12 +69,15 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GENERIC=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BALLOON_COMPACTION=y +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_BLK_DEV_INTEGRITY=y CONFIG_BLK_DEV_NVME=y CONFIG_NVME_MULTIPATH=y CONFIG_BLK_MQ_VIRTIO=y # CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set CONFIG_BTT=y +CONFIG_CDROM=y # CONFIG_CALGARY_IOMMU is not set # CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT is not set CONFIG_CONNECTOR=y @@ -294,6 +297,7 @@ CONFIG_IOSF_MBI=y # CONFIG_IOSF_MBI_DEBUG is not set # CONFIG_ISCSI_IBFT is not set # CONFIG_ISCSI_IBFT_FIND is not set +CONFIG_ISO9660_FS=y CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y # CONFIG_KVM_DEBUG_FS is not set CONFIG_KVM_GUEST=y diff --git a/target/linux/x86/64/config-5.4 b/target/linux/x86/64/config-5.4 index ceee923b0f..899668f77e 100644 --- a/target/linux/x86/64/config-5.4 +++ b/target/linux/x86/64/config-5.4 @@ -64,12 +64,15 @@ CONFIG_AUDIT_ARCH=y CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GENERIC=y CONFIG_BALLOON_COMPACTION=y +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_BLK_DEV_INTEGRITY=y CONFIG_BLK_DEV_NVME=y CONFIG_BLK_MQ_VIRTIO=y CONFIG_BLK_PM=y # CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set CONFIG_BTT=y +CONFIG_CDROM=y # CONFIG_CALGARY_IOMMU is not set # CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT is not set CONFIG_CONNECTOR=y @@ -280,6 +283,7 @@ CONFIG_IOMMU_HELPER=y CONFIG_IOSF_MBI=y # CONFIG_IOSF_MBI_DEBUG is not set # CONFIG_ISCSI_IBFT is not set +CONFIG_ISO9660_FS=y CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y # CONFIG_KVM_DEBUG_FS is not set CONFIG_KVM_GUEST=y From 5562c5add2faa5d407c308a98517b2b5cc6d84da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Tue, 31 Mar 2020 16:03:55 +0200 Subject: [PATCH 5/5] ipq40xx: fix DAP-2610 boot failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Albert has reported, that his DAP-2610 wont boot with the latest snapshot and Fredrik has found out, that the device gets stuck at "Waiting for root device ..." due to missing 5.4 kernel config symbol CONFIG_MTD_SPLIT_WRGG_FW which was probably lost during the kernel version bump. Ref: https://forum.openwrt.org/t/dap-2610-bricked-help-needed Fixes: 272e0a702a2b ("ipq40xx: add v5.4 support") Suggested-by: Fredrik Olofsson Signed-off-by: Petr Štetiar --- target/linux/ipq40xx/config-5.4 | 1 + 1 file changed, 1 insertion(+) diff --git a/target/linux/ipq40xx/config-5.4 b/target/linux/ipq40xx/config-5.4 index 86fabe6010..ba9ac7ddc4 100644 --- a/target/linux/ipq40xx/config-5.4 +++ b/target/linux/ipq40xx/config-5.4 @@ -344,6 +344,7 @@ CONFIG_MTD_SPI_NAND=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPLIT_FIRMWARE=y CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MTD_SPLIT_WRGG_FW=y CONFIG_MTD_UBI=y CONFIG_MTD_UBI_BEB_LIMIT=20 CONFIG_MTD_UBI_BLOCK=y