From owner-svn-src-head@FreeBSD.ORG Sat Feb 21 07:01:22 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4E19E106564A; Sat, 21 Feb 2009 07:01:22 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3C2668FC0A; Sat, 21 Feb 2009 07:01:22 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n1L71LSX058252; Sat, 21 Feb 2009 07:01:21 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n1L71LZp058251; Sat, 21 Feb 2009 07:01:21 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <200902210701.n1L71LZp058251@svn.freebsd.org> From: Marcel Moolenaar Date: Sat, 21 Feb 2009 07:01:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r188893 - head/sys/geom/part X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 21 Feb 2009 07:01:23 -0000 Author: marcel Date: Sat Feb 21 07:01:21 2009 New Revision: 188893 URL: http://svn.freebsd.org/changeset/base/188893 Log: Add bootcode handling. Modified: head/sys/geom/part/g_part_bsd.c Modified: head/sys/geom/part/g_part_bsd.c ============================================================================== --- head/sys/geom/part/g_part_bsd.c Sat Feb 21 05:54:06 2009 (r188892) +++ head/sys/geom/part/g_part_bsd.c Sat Feb 21 07:01:21 2009 (r188893) @@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$"); struct g_part_bsd_table { struct g_part_table base; - u_char *label; + u_char *bbarea; uint32_t offset; }; @@ -58,6 +58,7 @@ struct g_part_bsd_entry { static int g_part_bsd_add(struct g_part_table *, struct g_part_entry *, struct g_part_parms *); +static int g_part_bsd_bootcode(struct g_part_table *, struct g_part_parms *); static int g_part_bsd_create(struct g_part_table *, struct g_part_parms *); static int g_part_bsd_destroy(struct g_part_table *, struct g_part_parms *); static void g_part_bsd_dumpconf(struct g_part_table *, struct g_part_entry *, @@ -75,6 +76,7 @@ static int g_part_bsd_write(struct g_par static kobj_method_t g_part_bsd_methods[] = { KOBJMETHOD(g_part_add, g_part_bsd_add), + KOBJMETHOD(g_part_bootcode, g_part_bsd_bootcode), KOBJMETHOD(g_part_create, g_part_bsd_create), KOBJMETHOD(g_part_destroy, g_part_bsd_destroy), KOBJMETHOD(g_part_dumpconf, g_part_bsd_dumpconf), @@ -95,6 +97,7 @@ static struct g_part_scheme g_part_bsd_s .gps_entrysz = sizeof(struct g_part_bsd_entry), .gps_minent = 8, .gps_maxent = 20, + .gps_bootcodesz = BBSIZE, }; G_PART_SCHEME_DECLARE(g_part_bsd); @@ -157,6 +160,30 @@ g_part_bsd_add(struct g_part_table *base } static int +g_part_bsd_bootcode(struct g_part_table *basetable, struct g_part_parms *gpp) +{ + struct g_part_bsd_table *table; + const u_char *codeptr; + size_t hdsz, tlsz; + size_t codesz, tlofs; + + hdsz = 512; + tlofs = hdsz + 148 + basetable->gpt_entries * 16; + tlsz = BBSIZE - tlofs; + table = (struct g_part_bsd_table *)basetable; + bzero(table->bbarea, hdsz); + bzero(table->bbarea + tlofs, tlsz); + codeptr = gpp->gpp_codeptr; + codesz = MIN(hdsz, gpp->gpp_codesize); + if (codesz > 0) + bcopy(codeptr, table->bbarea, codesz); + codesz = MIN(tlsz, gpp->gpp_codesize - tlofs); + if (codesz > 0) + bcopy(codeptr + tlofs, table->bbarea + tlofs, codesz); + return (0); +} + +static int g_part_bsd_create(struct g_part_table *basetable, struct g_part_parms *gpp) { struct g_consumer *cp; @@ -173,13 +200,16 @@ g_part_bsd_create(struct g_part_table *b if (pp->sectorsize < sizeof(struct disklabel)) return (ENOSPC); + if (BBSIZE % pp->sectorsize) + return (ENOTBLK); msize = pp->mediasize / pp->sectorsize; secpercyl = basetable->gpt_sectors * basetable->gpt_heads; ncyls = msize / secpercyl; table = (struct g_part_bsd_table *)basetable; - ptr = table->label = g_malloc(pp->sectorsize, M_WAITOK | M_ZERO); + table->bbarea = g_malloc(BBSIZE, M_WAITOK | M_ZERO); + ptr = table->bbarea + pp->sectorsize; le32enc(ptr + 0, DISKMAGIC); /* d_magic */ le32enc(ptr + 40, pp->sectorsize); /* d_secsize */ @@ -284,6 +314,8 @@ g_part_bsd_probe(struct g_part_table *ta if (pp->sectorsize < sizeof(struct disklabel) || pp->mediasize < BBSIZE) return (ENOSPC); + if (BBSIZE % pp->sectorsize) + return (ENOTBLK); /* Check that there's a disklabel. */ buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error); @@ -313,11 +345,11 @@ g_part_bsd_read(struct g_part_table *bas table = (struct g_part_bsd_table *)basetable; msize = pp->mediasize / pp->sectorsize; - buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error); - if (buf == NULL) + table->bbarea = g_read_data(cp, 0, BBSIZE, &error); + if (table->bbarea == NULL) return (error); - table->label = buf; + buf = table->bbarea + pp->sectorsize; if (le32dec(buf + 40) != pp->sectorsize) goto invalid_label; @@ -388,7 +420,7 @@ g_part_bsd_read(struct g_part_table *bas invalid_label: printf("GEOM: %s: invalid disklabel.\n", pp->name); - g_free(table->label); + g_free(table->bbarea); return (EINVAL); } @@ -421,14 +453,15 @@ g_part_bsd_write(struct g_part_table *ba struct g_part_bsd_entry *entry; struct g_part_bsd_table *table; uint16_t sum; - u_char *p, *pe; + u_char *label, *p, *pe; int error, index; pp = cp->provider; table = (struct g_part_bsd_table *)basetable; baseentry = LIST_FIRST(&basetable->gpt_entry); + label = table->bbarea + pp->sectorsize; for (index = 1; index <= basetable->gpt_entries; index++) { - p = table->label + 148 + (index - 1) * 16; + p = label + 148 + (index - 1) * 16; entry = (baseentry != NULL && index == baseentry->gpe_index) ? (struct g_part_bsd_entry *)baseentry : NULL; if (entry != NULL && !baseentry->gpe_deleted) { @@ -446,13 +479,13 @@ g_part_bsd_write(struct g_part_table *ba } /* Calculate checksum. */ - le16enc(table->label + 136, 0); - pe = table->label + 148 + basetable->gpt_entries * 16; + le16enc(label + 136, 0); + pe = label + 148 + basetable->gpt_entries * 16; sum = 0; - for (p = table->label; p < pe; p += 2) + for (p = label; p < pe; p += 2) sum ^= le16dec(p); - le16enc(table->label + 136, sum); + le16enc(label + 136, sum); - error = g_write_data(cp, pp->sectorsize, table->label, pp->sectorsize); + error = g_write_data(cp, 0, table->bbarea, BBSIZE); return (error); }