Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 Oct 98 19:15:50 +0100 (BST)
From:      iedowse@maths.tcd.ie
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   i386/8146: Some kzipboot improvements
Message-ID:  <9810041915.aa10150@hamilton.maths.tcd.ie>

next in thread | raw e-mail | index | archive | help

>Number:         8146
>Category:       i386
>Synopsis:       kzipboot serial console setup and malloc improvements
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct  4 11:20:01 PDT 1998
>Last-Modified:
>Originator:     Ian Dowse
>Organization:
	School of Mathematics,
	Trinity College Dublin
>Release:        FreeBSD 3.0-BETA i386
>Environment:
	FreeBSD 3.0-BETA i386, also -stable

>Description:

	The patches below address two problems with the kzipboot code:

	- When a serial console is used, kzipboot does not initialise
	the serial port so no kzipboot information or error messages
	are displayed.

	- Some large kernels can generate a 'warning: malloc wrapped'
	message due to the extremely simple malloc implementation.
	Also when netbooting kzipped kernels, malloc can overrun the
	stack which grows down from 0x9e000.

>How-To-Repeat:

>Fix:
	The patches below make kzipboot correctly initialise the serial
	port if RB_SERIAL is specified. 

	The malloc implementation now uses a small cache of recent malloc'd
	blocks so it doesn't require so much memory. The total memory
	available to malloc is reduced from 320k to 256k so that kernels
	can be netbooted, but this is more than enough for the kernels I've
	tested. With the cache size set to its default of 100 entries,
	unzipping the 2.2.7 boot floppy kernel only reqires 10k instead of
	around 300k with the old code.

diff -cr old/kzipboot/Makefile kzipboot/Makefile
*** old/kzipboot/Makefile	Wed May 27 09:06:33 1998
--- kzipboot/Makefile	Sun Oct  4 17:50:29 1998
***************
*** 18,24 ****
  STRIP=	#  very important!! don't let kz*.o be stripped
  
  CFLAGS+= -DKADDR=$(KADDR) -DCSEG=$(CSEG)
! CFLAGS+= -DKZIP -DCOMCONSOLE=0x3F8
  
  kztail.o:  ${OBJS_KZTAIL}
  	$(LD) -r -x -o kztail.o $(OBJS_KZTAIL)
--- 18,24 ----
  STRIP=	#  very important!! don't let kz*.o be stripped
  
  CFLAGS+= -DKADDR=$(KADDR) -DCSEG=$(CSEG)
! CFLAGS+= -DKZIP -DCOMCONSOLE=0x3F8 -DCOMSPEED=9600
  
  kztail.o:  ${OBJS_KZTAIL}
  	$(LD) -r -x -o kztail.o $(OBJS_KZTAIL)
diff -cr old/kzipboot/boot.c kzipboot/boot.c
*** old/kzipboot/boot.c	Tue Jul  1 01:29:33 1997
--- kzipboot/boot.c	Sun Oct  4 17:54:26 1998
***************
*** 9,14 ****
--- 9,17 ----
  
  #include <machine/cpufunc.h>	/* for inb/outb */
  
+ #define COMSPEED_HIGH	((115200/(COMSPEED)) >> 8)
+ #define COMSPEED_LOW	((115200/(COMSPEED)) & 0xff)
+ 
  short *videomem;
  int curs;
  int cols;
***************
*** 131,136 ****
--- 134,155 ----
  		curs = l*cols + c;
  		if (curs > lines*cols)
  			curs = (lines-1) * cols;
+ 	} else {
+ 		int l, h;
+ 
+ 		/* Initialise console serial port */
+ 		outb(COMCONSOLE+1, 0);
+ 		while ((inb(COMCONSOLE+5) & 0x60) != 0x60);
+ 		outb(COMCONSOLE+3, 0x83);
+ 		l = inb(COMCONSOLE);
+ 		h = inb(COMCONSOLE+1);
+ 		if (l != COMSPEED_LOW)
+ 			outb(COMCONSOLE, COMSPEED_LOW);
+ 		if (h != COMSPEED_HIGH)
+ 			outb(COMCONSOLE+1, COMSPEED_HIGH);
+ 		outb(COMCONSOLE+3, 0x03);
+ 		outb(COMCONSOLE+4, (inb(COMCONSOLE+4) & 8) | 3);
+ 
  	}
  
  	putstr ("Uncompressing kernel...");
diff -cr old/kzipboot/malloc.c kzipboot/malloc.c
*** old/kzipboot/malloc.c	Thu Sep  7 22:11:34 1995
--- kzipboot/malloc.c	Sun Oct  4 16:49:14 1998
***************
*** 35,52 ****
  
  extern unsigned char *storage;
  
  void *
  malloc(nbytes, junk1, junk2) /* junk? not used */
  	size_t nbytes;
  	int junk1, junk2;
  {
  	unsigned char *p = storage;
  	storage += nbytes;
! 	if (storage >= (unsigned char *) 0xa0000) {
! 		putstr("warning: malloc wrapped\n");
! 		p = (unsigned char *) 0x50000;
! 		storage = p + nbytes;
! 	}
  	return p;
  }
  
--- 35,76 ----
  
  extern unsigned char *storage;
  
+ /* Simple cache so we can reuse most freed memory */
+ #define MALLOC_CACHE_SIZE 100
+ struct m_cache {
+ 	void *data;
+ 	int size;
+ 	int in_use;
+ } cache[MALLOC_CACHE_SIZE];
+ static int c_used = 0;	/* Number of entries in cache used */
+ static int c_cur = 0;	/* Current entry */
+ 
  void *
  malloc(nbytes, junk1, junk2) /* junk? not used */
  	size_t nbytes;
  	int junk1, junk2;
  {
  	unsigned char *p = storage;
+ 	int i;
+ 
+ 	for (i=0; i<c_used; i++)
+ 		if (!cache[i].in_use && cache[i].size >= nbytes) {
+ 			cache[i].in_use = 1;
+ 			return cache[i].data;
+ 		}
+ 
  	storage += nbytes;
! 	if (storage >= (unsigned char *) 0x90000)
! 		error("Out of memory. Try increasing MALLOC_CACHE_SIZE");
! 
! 	cache[c_cur].data = p;
! 	cache[c_cur].size = nbytes;
! 	cache[c_cur].in_use = 1;
! 	if (++c_cur >= MALLOC_CACHE_SIZE)
! 		c_cur = 0;
! 	if (c_cur > c_used)
! 		c_used = c_cur;
! 	
  	return p;
  }
  
***************
*** 55,58 ****
--- 79,86 ----
  	void *cp;
  	int junk;
  {
+ 	int i;
+ 	for (i=0; i<c_used; i++)
+ 		if (cache[i].data == cp)
+ 			cache[i].in_use = 0;
  }
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9810041915.aa10150>