Home | History | Annotate | Line # | Download | only in loadbsd
loadbsd.c revision 1.3
      1  1.3       mw /*	$Id: loadbsd.c,v 1.3 1993/09/02 18:08:26 mw Exp $ */
      2  1.2  mycroft 
      3  1.1       mw #include <sys/types.h>
      4  1.1       mw #include <a.out.h>
      5  1.1       mw #include <stdio.h>
      6  1.1       mw 
      7  1.1       mw #include <exec/types.h>
      8  1.1       mw #include <exec/execbase.h>
      9  1.1       mw #include <exec/memory.h>
     10  1.1       mw #include <libraries/configregs.h>
     11  1.1       mw #include <libraries/expansionbase.h>
     12  1.1       mw 
     13  1.1       mw #include <inline/exec.h>
     14  1.1       mw #include <inline/expansion.h>
     15  1.1       mw 
     16  1.3       mw /* Get definitions for boothowto */
     17  1.3       mw #include "reboot.h"
     18  1.3       mw 
     19  1.1       mw struct ExpansionBase *ExpansionBase;
     20  1.1       mw 
     21  1.1       mw #undef __LDPGSZ
     22  1.1       mw #define __LDPGSZ 8192
     23  1.1       mw 
     24  1.1       mw void get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size);
     25  1.1       mw 
     26  1.1       mw int
     27  1.1       mw main (int argc, char *argv[])
     28  1.1       mw {
     29  1.1       mw   struct exec e;
     30  1.1       mw   int fd;
     31  1.3       mw   int boothowto = RB_SINGLE;
     32  1.1       mw 
     33  1.1       mw   if (argc >= 2)
     34  1.1       mw     {
     35  1.1       mw       if ((fd = open (argv[1], 0)) >= 0)
     36  1.1       mw         {
     37  1.1       mw           if (read (fd, &e, sizeof (e)) == sizeof (e))
     38  1.1       mw             {
     39  1.1       mw               if (e.a_magic == NMAGIC)
     40  1.1       mw                 {
     41  1.1       mw                   u_char *kernel;
     42  1.1       mw 		  int text_size;
     43  1.1       mw 		  struct ConfigDev *cd;
     44  1.1       mw 		  int num_cd;
     45  1.1       mw 
     46  1.1       mw 		  ExpansionBase= (struct ExpansionBase *) OpenLibrary ("expansion.library", 0);
     47  1.1       mw 		  if (! ExpansionBase)	/* not supposed to fail... */
     48  1.1       mw 		    abort();
     49  1.1       mw 		  for (cd = 0, num_cd = 0; cd = FindConfigDev (cd, -1, -1); num_cd++) ;
     50  1.1       mw 
     51  1.1       mw 		  text_size = (e.a_text + __LDPGSZ - 1) & (-__LDPGSZ);
     52  1.1       mw 		  kernel = (u_char *) malloc (text_size + e.a_data + e.a_bss
     53  1.1       mw 				              + num_cd*sizeof(*cd) + 4);
     54  1.1       mw 
     55  1.1       mw                   if (kernel)
     56  1.1       mw                     {
     57  1.1       mw 		      if (read (fd, kernel, e.a_text) == e.a_text
     58  1.1       mw 			  && read (fd, kernel + text_size, e.a_data) == e.a_data)
     59  1.1       mw 			{
     60  1.1       mw 			  int *knum_cd;
     61  1.1       mw 			  struct ConfigDev *kcd;
     62  1.1       mw 			  void *fastmem_start;
     63  1.1       mw 			  u_long fastmem_size, chipmem_size;
     64  1.1       mw 
     65  1.1       mw 			  get_mem_config (&fastmem_start, &fastmem_size, &chipmem_size);
     66  1.1       mw 
     67  1.3       mw 			  if (argc >= 3 && (!strcmp (argv[2], "-k")
     68  1.3       mw 			      || !strcmp (argv[3], "-k")) )
     69  1.1       mw 			    {
     70  1.1       mw 			      fastmem_start += 4*1024*1024;
     71  1.1       mw 			      fastmem_size  -= 4*1024*1024;
     72  1.1       mw 			    }
     73  1.1       mw 
     74  1.3       mw 			  if (argc >= 3 && (!strcmp (argv[2], "-a")
     75  1.3       mw 			      || !strcmp (argv[3], "-a")) )
     76  1.3       mw 			    {
     77  1.3       mw 			      printf("Autobooting...");
     78  1.3       mw 			      boothowto = RB_AUTOBOOT;
     79  1.3       mw 			    }
     80  1.3       mw 
     81  1.1       mw 			  printf ("Using %dM FASTMEM at 0x%x, %dM CHIPMEM\n",
     82  1.1       mw 				  fastmem_size>>20, fastmem_start, chipmem_size>>20);
     83  1.1       mw 			  /* give them a chance to read the information... */
     84  1.1       mw 			  sleep(2);
     85  1.1       mw 
     86  1.1       mw 			  bzero (kernel + text_size + e.a_data, e.a_bss);
     87  1.1       mw 			  knum_cd = (int *) (kernel + text_size + e.a_data + e.a_bss);
     88  1.1       mw 			  *knum_cd = num_cd;
     89  1.1       mw 			  if (num_cd)
     90  1.1       mw 			    for (kcd = (struct ConfigDev *) (knum_cd+1);
     91  1.1       mw 			         cd = FindConfigDev (cd, -1, -1);
     92  1.1       mw 			         *kcd++ = *cd) ;
     93  1.1       mw 			  startit (kernel,
     94  1.1       mw 				   text_size + e.a_data + e.a_bss + num_cd*sizeof(*cd) + 4,
     95  1.1       mw 				   e.a_entry, fastmem_start,
     96  1.3       mw 				   fastmem_size, chipmem_size,
     97  1.3       mw 				   boothowto );
     98  1.1       mw 			}
     99  1.1       mw 		      else
    100  1.1       mw 			fprintf (stderr, "Executable corrupt!\n");
    101  1.1       mw                     }
    102  1.1       mw                   else
    103  1.1       mw 		    fprintf (stderr, "Out of memory! (%d)\n", text_size + e.a_data + e.a_bss
    104  1.1       mw 				   + num_cd*sizeof(*cd) + 4);
    105  1.1       mw                 }
    106  1.1       mw 	      else
    107  1.1       mw 	        fprintf (stderr, "Unsupported executable: %o\n", e.a_magic);
    108  1.1       mw             }
    109  1.1       mw           else
    110  1.1       mw 	    fprintf (stderr, "Can't read header of %s\n", argv[1]);
    111  1.1       mw 
    112  1.1       mw 	  close (fd);
    113  1.1       mw         }
    114  1.1       mw       else
    115  1.1       mw 	perror ("open");
    116  1.1       mw     }
    117  1.1       mw   else
    118  1.3       mw     fprintf (stderr, "%s some-vmunix [-a] [-k]\n", argv[0]);
    119  1.1       mw }
    120  1.1       mw 
    121  1.1       mw 
    122  1.1       mw void
    123  1.1       mw get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size)
    124  1.1       mw {
    125  1.1       mw   extern struct ExecBase *SysBase;
    126  1.1       mw   struct MemHeader *mh, *nmh;
    127  1.1       mw 
    128  1.1       mw   *fastmem_size = 0;
    129  1.1       mw   *chipmem_size = 0;
    130  1.1       mw 
    131  1.1       mw   /* walk thru the exec memory list */
    132  1.1       mw   Forbid ();
    133  1.1       mw   for (mh  = (struct MemHeader *) SysBase->MemList.lh_Head;
    134  1.1       mw        nmh = (struct MemHeader *) mh->mh_Node.ln_Succ;
    135  1.1       mw        mh  = nmh)
    136  1.1       mw     {
    137  1.1       mw       if (mh->mh_Attributes & MEMF_CHIP)
    138  1.1       mw         {
    139  1.1       mw 	  /* there should hardly be more than one entry for chip mem, but
    140  1.1       mw 	     handle it the same nevertheless */
    141  1.1       mw 	  if ((u_int)mh->mh_Upper - (u_int)mh->mh_Lower > *chipmem_size)
    142  1.1       mw 	    {
    143  1.1       mw 	      *chipmem_size = (u_int)mh->mh_Upper - (u_int)mh->mh_Lower;
    144  1.1       mw 	      /* round to multiple of 512K */
    145  1.1       mw 	      *chipmem_size = (*chipmem_size + 512*1024 - 1) & -(512*1024);
    146  1.1       mw 
    147  1.1       mw 	      /* chipmem always starts at 0, so don't remember start
    148  1.1       mw 	         address */
    149  1.1       mw 	    }
    150  1.1       mw         }
    151  1.1       mw       else
    152  1.1       mw 	{
    153  1.1       mw 	  if ((u_int)mh->mh_Upper - (u_int)mh->mh_Lower > *fastmem_size)
    154  1.1       mw 	    {
    155  1.1       mw 	      u_int start = (u_int) mh->mh_Lower;
    156  1.1       mw 	      u_int end = (u_int) mh->mh_Upper;
    157  1.1       mw 
    158  1.1       mw 	      /* some heuristics.. */
    159  1.1       mw 	      start &= -__LDPGSZ;
    160  1.1       mw 	      /* get the mem back stolen by incore kickstart on A3000 with
    161  1.1       mw 	         V36 bootrom. */
    162  1.1       mw 	      if (end == 0x07f80000)
    163  1.1       mw 	        end = 0x08000000;
    164  1.1       mw 
    165  1.1       mw 	      *fastmem_size = end - start;
    166  1.1       mw 	      *fastmem_start = (void *)start;
    167  1.1       mw 	    }
    168  1.1       mw 	}
    169  1.1       mw     }
    170  1.1       mw   Permit();
    171  1.1       mw }
    172  1.1       mw 
    173  1.1       mw 
    174  1.1       mw 
    175  1.1       mw 
    176  1.1       mw asm ("
    177  1.1       mw 	.set	ABSEXECBASE,4
    178  1.1       mw 
    179  1.1       mw 	.text
    180  1.1       mw 	.globl	_startit
    181  1.1       mw 
    182  1.1       mw _startit:
    183  1.1       mw 	movel	sp,a3
    184  1.1       mw 	movel	4:w,a6
    185  1.1       mw 	lea	pc@(start_super-.+2),a5
    186  1.1       mw 	jmp	a6@(-0x1e)		| supervisor-call
    187  1.1       mw 
    188  1.1       mw start_super:
    189  1.1       mw 	movew	#0x2700,sr
    190  1.1       mw 
    191  1.1       mw 	| the BSD kernel wants values into the following registers:
    192  1.1       mw 	| a0:  fastmem-start
    193  1.1       mw 	| d0:  fastmem-size
    194  1.1       mw 	| d1:  chipmem-size
    195  1.3       mw 	| d7:  boothowto
    196  1.1       mw 
    197  1.1       mw 	movel	a3@(4),a1		| loaded kernel
    198  1.1       mw 	movel	a3@(8),d2		| length of loaded kernel
    199  1.1       mw 	movel	a3@(12),a2		| entry point
    200  1.1       mw 	movel	a3@(16),a0		| fastmem-start
    201  1.1       mw 	movel	a3@(20),d0		| fastmem-size
    202  1.1       mw 	movel	a3@(24),d1		| chipmem-size
    203  1.3       mw 	movel	a3@(28),d7		| boothowto
    204  1.1       mw 	subl	a4,a4			| target, load to 0
    205  1.1       mw 
    206  1.1       mw 	lea	pc@(zero-.+2),a3
    207  1.1       mw 	pmove	a3@,tc			| Turn off MMU
    208  1.1       mw 	lea	pc@(nullrp-.+2),a3
    209  1.1       mw 	pmove	a3@,crp			| Turn off MMU some more
    210  1.1       mw 	pmove	a3@,srp			| Really, really, turn off MMU
    211  1.1       mw 
    212  1.1       mw | Turn off 68030 TT registers
    213  1.1       mw 
    214  1.1       mw 	btst	#2,(ABSEXECBASE)@(0x129) | AFB_68030,SysBase->AttnFlags
    215  1.1       mw 	beq	nott			| Skip TT registers if not 68030
    216  1.1       mw 	lea	pc@(zero-.+2),a3
    217  1.1       mw 	.word 0xf013,0x0800		| pmove a3@,tt0 (gas only knows about 68851 ops..)
    218  1.1       mw 	.word 0xf013,0x0c00		| pmove a3@,tt1 (gas only knows about 68851 ops..)
    219  1.1       mw 
    220  1.1       mw nott:
    221  1.1       mw 
    222  1.1       mw 	movew	#(1<<9),0xdff096	| disable DMA
    223  1.1       mw 
    224  1.1       mw L0:
    225  1.1       mw 	moveb	a1@+,a4@+
    226  1.1       mw 	subl	#1,d2
    227  1.1       mw 	bcc	L0
    228  1.1       mw 
    229  1.1       mw 
    230  1.1       mw 	jmp	a2@
    231  1.1       mw 
    232  1.1       mw 
    233  1.1       mw | A do-nothing MMU root pointer (includes the following long as well)
    234  1.1       mw 
    235  1.1       mw nullrp:	.long	0x7fff0001
    236  1.1       mw zero:	.long	0
    237  1.1       mw 
    238  1.1       mw 
    239  1.1       mw ");
    240  1.1       mw 
    241