Changeset View
Standalone View
usr.sbin/bsdinstall/partedit/partedit_x86.c
Show All 23 Lines | |||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <libgeom.h> | |||||
#include "partedit.h" | #include "partedit.h" | ||||
static const char * | static const char * | ||||
x86_bootmethod(void) | x86_bootmethod(void) | ||||
{ | { | ||||
static char fw[255] = ""; | static char fw[255] = ""; | ||||
size_t len = sizeof(fw); | size_t len = sizeof(fw); | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | bootpart_type(const char *scheme) | ||||
return ("freebsd-boot"); | return ("freebsd-boot"); | ||||
} | } | ||||
const char * | const char * | ||||
bootcode_path(const char *part_type) | bootcode_path(const char *part_type) | ||||
{ | { | ||||
if (strcmp(x86_bootmethod(), "UEFI") == 0) | |||||
return (NULL); | |||||
if (strcmp(part_type, "GPT") == 0) | if (strcmp(part_type, "GPT") == 0) | ||||
return ("/boot/pmbr"); | return ("/boot/pmbr"); | ||||
if (strcmp(part_type, "MBR") == 0) | if (strcmp(part_type, "MBR") == 0) | ||||
return ("/boot/mbr"); | return ("/boot/mbr"); | ||||
if (strcmp(part_type, "BSD") == 0) | if (strcmp(part_type, "BSD") == 0) | ||||
return ("/boot/boot"); | return ("/boot/boot"); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
const char * | const char * | ||||
partcode_path(const char *part_type, const char *fs_type) | partcode_path(const char *scheme, const char *fs_type, const char *part_type) | ||||
{ | { | ||||
if (strcmp(part_type, "GPT") == 0) { | if (strcmp(scheme, "GPT") == 0) { | ||||
if (strcmp(x86_bootmethod(), "UEFI") == 0) | if (part_type != NULL && strcmp(part_type, "efi") == 0) | ||||
return ("/boot/boot1.efifat"); | return ("/boot/boot1.efifat"); | ||||
else if (strcmp(fs_type, "zfs") == 0) | else if (strcmp(fs_type, "zfs") == 0) | ||||
return ("/boot/gptzfsboot"); | return ("/boot/gptzfsboot"); | ||||
else | else | ||||
return ("/boot/gptboot"); | return ("/boot/gptboot"); | ||||
} | } | ||||
/* No partcode except for GPT */ | /* No partcode except for GPT */ | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
intmax_t | |||||
create_bootpart(struct ggeom *geom, const char *scheme, intmax_t start, | |||||
intmax_t sector) { | |||||
struct gctl_req *r; | |||||
const char *errstr; | |||||
char sizestr[32], startstr[32], output[64]; | |||||
intmax_t size, totalsize; | |||||
int err; | |||||
err = 0; | |||||
totalsize = 0; | |||||
/* Create the EFI boot partition */ | |||||
size = 800*1024 / sector; | |||||
imp: This hard codes the size of the EFI fat partition. Ideally, we'd stat the boot1.efifat file and… | |||||
rpokalaUnsubmitted Not Done Inline ActionsimpTBH, I never understood why we created boot1.efifat in the first place, rather than just using 'newfs_msdos' and 'cp'. rpokala: ==imp
TBH, I never understood why we created boot1.efifat in the first place, rather than just… | |||||
allanjudeAuthorUnsubmitted Not Done Inline Actionsmy understanding was that our newfs_msdos did not always produce a file system that all computer could boot from. I am not sure the details, maybe emaste knows allanjude: my understanding was that our newfs_msdos did not always produce a file system that all… | |||||
emasteUnsubmitted Not Done Inline Actions@allanjude newfs_msdos can create them: the boot1.efifat images are created with newfs_msdos -F 12 -L EFI $DEVICE. See sys/boot/efi/boot1/generate-fat.sh. I do think we want some improved logic for handling the ESP as part of broader installer improvements - ideally the installer could find an existing ESP on the target device and offer to install boot1.efi into it. The pre-canned FAT image was a convenient way to fit EFI into the existing installer/gpart infrastructure, but there's no reason it has to be done that way. emaste: @allanjude newfs_msdos can create them: the boot1.efifat images are created with `newfs_msdos… | |||||
nwhitehornUnsubmitted Not Done Inline ActionsWe're making boot1.efifat to simplify the logic in the installer. The EFI boot partition is not mounted anywhere in the current scheme of things and we have no other platforms with per-platform file system requirements. Thus, making it with newfs_msdos would require a great deal of specialty logic not otherwise required. nwhitehorn: We're making boot1.efifat to simplify the logic in the installer. The EFI boot partition is not… | |||||
impUnsubmitted Not Done Inline ActionsSome ARM SoCs require a FAT partition with UBOOT (and often other) images on it. We currently kinda hack around that by DDing images created by NanoBSD, Crochet, or the release process onto an SD card. It's a flaw that the installer doesn't support creating them, but since there's usually only one device, you'd have to netboot the installer, which on many SoCs requires those fat partition and files. The UEFI support is just another instance where that's required, but with different files required. imp: Some ARM SoCs require a FAT partition with UBOOT (and often other) images on it. We currently… | |||||
bcranUnsubmitted Not Done Inline Actions@imp We'll probably want at least a 200 MB EFI FAT partition, since there's normally only one per system and it gets used in multi-boot scenarios. https://wiki.archlinux.org/index.php/EFI_system_partition says:
bcran: @imp We'll probably want at least a 200 MB EFI FAT partition, since there's normally only one… | |||||
allanjudeAuthorUnsubmitted Not Done Inline ActionsThis diff is old, currently we create a 200MB FAT16. For many images, 500+MB is getting to be a rather large bit of the available space, especially for VMs and USB images etc. allanjude: This diff is old, currently we create a 200MB FAT16. For many images, 500+MB is getting to be a… | |||||
bcranUnsubmitted Not Done Inline ActionsOh, thanks. Good point about VMs etc., I agree 500+ MB is rather large for them. The UEFI 2.3.1 specification mandates the use of FAT32 though, so FAT16 is non-standard:
(seen via https://bugs.launchpad.net/ubuntu/+source/partman-efi/+bug/811485) bcran: Oh, thanks. Good point about VMs etc., I agree 500+ MB is rather large for them.
The UEFI 2.3. | |||||
r = gctl_get_handle(); | |||||
gctl_ro_param(r, "class", -1, "PART"); | |||||
gctl_ro_param(r, "arg0", -1, geom->lg_name); | |||||
gctl_ro_param(r, "flags", -1, GPART_FLAGS); | |||||
gctl_ro_param(r, "verb", -1, "add"); | |||||
gctl_ro_param(r, "type", -1, "efi"); | |||||
snprintf(sizestr, sizeof(sizestr), "%jd", size); | |||||
gctl_ro_param(r, "size", -1, sizestr); | |||||
snprintf(startstr, sizeof(startstr), "%jd", start); | |||||
gctl_ro_param(r, "start", -1, startstr); | |||||
gctl_rw_param(r, "output", sizeof(output), output); | |||||
errstr = gctl_issue(r); | |||||
if (errstr != NULL && errstr[0] != '\0') { | |||||
printf("Error: %s\n", errstr); | |||||
err = 1; | |||||
} | |||||
gctl_free(r); | |||||
totalsize += size; | |||||
start += size; | |||||
if (err > 0) { | |||||
return (0); /* XXX need error handlingg */ | |||||
} | |||||
/* Create the GPT (BIOS) boot partition */ | |||||
size = 512*1024 / sector; | |||||
impUnsubmitted Not Done Inline ActionsHowever here I'd be tempted to leave this as is because the boot blocks can grow up to about 540k in size before there's issues with boot1. boot1.efi can be substantially larger before there's an issue, but boot1 really can't. imp: However here I'd be tempted to leave this as is because the boot blocks can grow up to about… | |||||
r = gctl_get_handle(); | |||||
gctl_ro_param(r, "class", -1, "PART"); | |||||
gctl_ro_param(r, "arg0", -1, geom->lg_name); | |||||
gctl_ro_param(r, "flags", -1, GPART_FLAGS); | |||||
gctl_ro_param(r, "verb", -1, "add"); | |||||
gctl_ro_param(r, "type", -1, "freebsd-boot"); | |||||
snprintf(sizestr, sizeof(sizestr), "%jd", size); | |||||
gctl_ro_param(r, "size", -1, sizestr); | |||||
snprintf(startstr, sizeof(startstr), "%jd", start); | |||||
gctl_ro_param(r, "start", -1, startstr); | |||||
gctl_rw_param(r, "output", sizeof(output), output); | |||||
errstr = gctl_issue(r); | |||||
if (errstr != NULL && errstr[0] != '\0') { | |||||
printf("Error: %s\n", errstr); | |||||
err = 1; | |||||
} | |||||
gctl_free(r); | |||||
totalsize += size; | |||||
get_part_metadata(strtok(output, " "), 1)->bootcode = 1; | |||||
if (err > 0) { | |||||
return (0); /* XXX need error handlingg */ | |||||
} | |||||
return (totalsize); | |||||
} |
This hard codes the size of the EFI fat partition. Ideally, we'd stat the boot1.efifat file and use its size.
Even better would be to allocate 5MB of space, newfs_msdos it and copy /boot/boot1.efi to there
as efi\boot\bootx64.efi so that people have a little bit of extra space for upgrades to their BIOSes and
such. OTOH, this may be too esoteric to do by default. So if you don't do this, at least do the stat thing.