summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2002-01-17 22:39:19 +0000
committeriedowse <iedowse@FreeBSD.org>2002-01-17 22:39:19 +0000
commit8ff94b6175cd5516e900191484ef535e5eee1d25 (patch)
treefb2c807268ae674315c10833a8d717e69f90c7f9 /sys/boot
parentb38e892818e28c91f91e7c45b4353838c5820f06 (diff)
downloadFreeBSD-src-8ff94b6175cd5516e900191484ef535e5eee1d25.zip
FreeBSD-src-8ff94b6175cd5516e900191484ef535e5eee1d25.tar.gz
Oops, the previous revision (1.35) broke booting from floppies
because the buffers we use could end up spanning a 64k boundary. Unfortunately it causes too much bloat (228 -> 72 bytes free) to just reinstate the old malloc() function. Instead, define a structure that contains all 4 buffers which must not cross 64k boundaries. We allocate a 64k-aligned instance in main() using the magic that was in the old boot2 malloc() function. This brings the free space down to 168 bytes, but that is still better than it was before revision 1.35 (136 bytes). Reported by: Mike Brancato <funnyguy@digitalsmackdown.net> Pointy-hat to: iedowse
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/i386/boot2/boot2.c24
-rw-r--r--sys/boot/i386/gptboot/gptboot.c24
2 files changed, 36 insertions, 12 deletions
diff --git a/sys/boot/i386/boot2/boot2.c b/sys/boot/i386/boot2/boot2.c
index a44eefc..fd2145d 100644
--- a/sys/boot/i386/boot2/boot2.c
+++ b/sys/boot/i386/boot2/boot2.c
@@ -88,6 +88,14 @@
#define TYPE_FD 3
#define TYPE_DA 4
+/* Buffers that must not span a 64k boundary. */
+static struct dmadat {
+ char blkbuf[VBLKSIZE]; /* filesystem blocks */
+ ufs_daddr_t indbuf[VBLKSIZE / sizeof(ufs_daddr_t)]; /* indir blocks */
+ char sbbuf[SBSIZE]; /* superblock */
+ char secbuf[DEV_BSIZE]; /* for MBR/disklabel */
+} *dmadat;
+
extern uint32_t _end;
static const char optstr[NOPT] = "DhaCcdgPrsv";
@@ -254,6 +262,7 @@ main(void)
{
int autoboot, i;
+ dmadat = (void *)(roundup2(__base + _end, 0x10000) - __base);
v86.ctl = V86_FLAGS;
dsk.drive = *(uint8_t *)PTOV(ARGS);
dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD;
@@ -530,21 +539,23 @@ xfsread(ino_t inode, void *buf, size_t nbyte)
static ssize_t
fsread(ino_t inode, void *buf, size_t nbyte)
{
- static char blkbuf[VBLKSIZE];
- static ufs_daddr_t indbuf[VBLKSIZE / sizeof(ufs_daddr_t)];
- static char sbbuf[SBSIZE];
static struct dinode din;
- static struct fs *fs = (struct fs *)sbbuf;
static ino_t inomap;
static daddr_t blkmap, indmap;
+ char *blkbuf;
+ ufs_daddr_t *indbuf;
+ struct fs *fs;
char *s;
ufs_daddr_t lbn, addr;
daddr_t vbaddr;
size_t n, nb, off, vboff;
+ blkbuf = dmadat->blkbuf;
+ indbuf = dmadat->indbuf;
+ fs = (struct fs *)dmadat->sbbuf;
if (!dsk.meta) {
inomap = 0;
- if (dskread(sbbuf, SBOFF / DEV_BSIZE, SBSIZE / DEV_BSIZE))
+ if (dskread(fs, SBOFF / DEV_BSIZE, SBSIZE / DEV_BSIZE))
return -1;
if (fs->fs_magic != FS_MAGIC) {
printf("Not ufs\n");
@@ -605,12 +616,13 @@ fsread(ino_t inode, void *buf, size_t nbyte)
static int
dskread(void *buf, unsigned lba, unsigned nblk)
{
- static char sec[DEV_BSIZE];
struct dos_partition *dp;
struct disklabel *d;
+ char *sec;
unsigned sl, i;
if (!dsk.meta) {
+ sec = dmadat->secbuf;
dsk.start = 0;
if (drvread(sec, DOSBBSECTOR, 1))
return -1;
diff --git a/sys/boot/i386/gptboot/gptboot.c b/sys/boot/i386/gptboot/gptboot.c
index a44eefc..fd2145d 100644
--- a/sys/boot/i386/gptboot/gptboot.c
+++ b/sys/boot/i386/gptboot/gptboot.c
@@ -88,6 +88,14 @@
#define TYPE_FD 3
#define TYPE_DA 4
+/* Buffers that must not span a 64k boundary. */
+static struct dmadat {
+ char blkbuf[VBLKSIZE]; /* filesystem blocks */
+ ufs_daddr_t indbuf[VBLKSIZE / sizeof(ufs_daddr_t)]; /* indir blocks */
+ char sbbuf[SBSIZE]; /* superblock */
+ char secbuf[DEV_BSIZE]; /* for MBR/disklabel */
+} *dmadat;
+
extern uint32_t _end;
static const char optstr[NOPT] = "DhaCcdgPrsv";
@@ -254,6 +262,7 @@ main(void)
{
int autoboot, i;
+ dmadat = (void *)(roundup2(__base + _end, 0x10000) - __base);
v86.ctl = V86_FLAGS;
dsk.drive = *(uint8_t *)PTOV(ARGS);
dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD;
@@ -530,21 +539,23 @@ xfsread(ino_t inode, void *buf, size_t nbyte)
static ssize_t
fsread(ino_t inode, void *buf, size_t nbyte)
{
- static char blkbuf[VBLKSIZE];
- static ufs_daddr_t indbuf[VBLKSIZE / sizeof(ufs_daddr_t)];
- static char sbbuf[SBSIZE];
static struct dinode din;
- static struct fs *fs = (struct fs *)sbbuf;
static ino_t inomap;
static daddr_t blkmap, indmap;
+ char *blkbuf;
+ ufs_daddr_t *indbuf;
+ struct fs *fs;
char *s;
ufs_daddr_t lbn, addr;
daddr_t vbaddr;
size_t n, nb, off, vboff;
+ blkbuf = dmadat->blkbuf;
+ indbuf = dmadat->indbuf;
+ fs = (struct fs *)dmadat->sbbuf;
if (!dsk.meta) {
inomap = 0;
- if (dskread(sbbuf, SBOFF / DEV_BSIZE, SBSIZE / DEV_BSIZE))
+ if (dskread(fs, SBOFF / DEV_BSIZE, SBSIZE / DEV_BSIZE))
return -1;
if (fs->fs_magic != FS_MAGIC) {
printf("Not ufs\n");
@@ -605,12 +616,13 @@ fsread(ino_t inode, void *buf, size_t nbyte)
static int
dskread(void *buf, unsigned lba, unsigned nblk)
{
- static char sec[DEV_BSIZE];
struct dos_partition *dp;
struct disklabel *d;
+ char *sec;
unsigned sl, i;
if (!dsk.meta) {
+ sec = dmadat->secbuf;
dsk.start = 0;
if (drvread(sec, DOSBBSECTOR, 1))
return -1;
OpenPOWER on IntegriCloud