From owner-svn-src-all@freebsd.org Wed Jul 15 02:23:56 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F2A849A26CF; Wed, 15 Jul 2015 02:23:56 +0000 (UTC) (envelope-from allanjude@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B524B1C55; Wed, 15 Jul 2015 02:23:56 +0000 (UTC) (envelope-from allanjude@FreeBSD.org) Received: from svnmir.geo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t6F2Nuh6083392; Wed, 15 Jul 2015 02:23:56 GMT (envelope-from allanjude@FreeBSD.org) Received: (from allanjude@localhost) by svnmir.geo.freebsd.org (8.14.9/8.14.9/Submit) id t6F2NuL4083390; Wed, 15 Jul 2015 02:23:56 GMT (envelope-from allanjude@FreeBSD.org) Message-Id: <201507150223.t6F2NuL4083390@svnmir.geo.freebsd.org> X-Authentication-Warning: svnmir.geo.freebsd.org: allanjude set sender to allanjude@FreeBSD.org using -f From: Allan Jude Date: Wed, 15 Jul 2015 02:23:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r285594 - in head: sbin/geom/class/part sys/geom/part X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Jul 2015 02:23:57 -0000 Author: allanjude (doc committer) Date: Wed Jul 15 02:23:55 2015 New Revision: 285594 URL: https://svnweb.freebsd.org/changeset/base/285594 Log: Add a new option to gpart(8) to fix Lenovo BIOS boot issue PR: 184910 Reviewed by: ae, wblock Approved by: marcel MFC after: 3 days Relnotes: yes Sponsored by: ScaleEngine Inc. Differential Revision: https://reviews.freebsd.org/D3065 Modified: head/sbin/geom/class/part/gpart.8 head/sys/geom/part/g_part_gpt.c Modified: head/sbin/geom/class/part/gpart.8 ============================================================================== --- head/sbin/geom/class/part/gpart.8 Wed Jul 15 01:04:54 2015 (r285593) +++ head/sbin/geom/class/part/gpart.8 Wed Jul 15 02:23:55 2015 (r285594) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 5, 2015 +.Dd July 14, 2015 .Dt GPART 8 .Os .Sh NAME @@ -933,6 +933,12 @@ start-up script. See .Xr gptboot 8 for more details. +.It Cm lenovofix +Setting this attribute overwrites the Protective MBR with a new one where +the 0xee partition is the second, rather than the first record. +This resolves a BIOS compatibility issue with some Lenovo models including the +X220, T420, and T520, allowing them to boot from GPT partitioned disks +without using EFI. .El .Pp The scheme-specific attributes for MBR: Modified: head/sys/geom/part/g_part_gpt.c ============================================================================== --- head/sys/geom/part/g_part_gpt.c Wed Jul 15 01:04:54 2015 (r285593) +++ head/sys/geom/part/g_part_gpt.c Wed Jul 15 02:23:55 2015 (r285594) @@ -1007,6 +1007,7 @@ g_part_gpt_setunset(struct g_part_table { struct g_part_gpt_entry *entry; struct g_part_gpt_table *table; + struct g_provider *pp; uint8_t *p; uint64_t attr; int i; @@ -1036,6 +1037,21 @@ g_part_gpt_setunset(struct g_part_table } } return (0); + } else if (strcasecmp(attrib, "lenovofix") == 0) { + /* + * Write the 0xee GPT entry to slot #1 (2nd slot) in the pMBR. + * This workaround allows Lenovo X220, T420, T520, etc to boot + * from GPT Partitions in BIOS mode. + */ + + if (entry != NULL) + return (ENXIO); + + pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider; + bzero(table->mbr + DOSPARTOFF, DOSPARTSIZE * NDOSPART); + gpt_write_mbr_entry(table->mbr, ((set) ? 1 : 0), 0xee, 1, + MIN(pp->mediasize / pp->sectorsize - 1, UINT32_MAX)); + return (0); } if (entry == NULL)