~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Minix Cross Reference
Minix/kernel/main.c


  1 /* This file contains the main program of MINIX.  The routine main()
  2  * initializes the system and starts the ball rolling by setting up the proc
  3  * table, interrupt vectors, and scheduling each task to run to initialize
  4  * itself.
  5  *
  6  * The entries into this file are:
  7  *   main:              MINIX main program
  8  *   panic:             abort MINIX due to a fatal error
  9  */
 10 
 11 #include "kernel.h"
 12 #include <unistd.h>
 13 #include <minix/callnr.h>
 14 #include <minix/com.h>
 15 #include "proc.h"
 16 #if (MACHINE == SUN)
 17 #include <minix/boot.h>
 18 #include <sun/syscall.h>
 19 #include "logging.h"
 20 #include <net/gen/ether.h>
 21 #include "bootinfo.h"
 22 #endif
 23 
 24 #if (MACHINE == SUN)
 25 /*
 26  * Must be first thing main's data segment (initialisation ensures that it 
 27  * goes into the data segment).  Also, main.o must be the first file in the
 28  * link that has a data segment.
 29  *
 30  * Because R8192 had to be removed from the data segment entry, the bootstrap
 31  * program can no longer rely on the start of the data segment being aligned
 32  * on an 8192 boundary---it may now start anywhere in the first page reserved
 33  * for the data segment.  The minix bootstrap still aligns the smxboot_info
 34  * to an 8Kb boundary, however.  We declare the smxboot_space structure
 35  * so that we can be sure that there is enough space for the smx_bootinfo
 36  * structure, even if the data segment is 8Kb aligned.  We also use the
 37  * address of smxboot_space to initialise smxboot, as they must both lie
 38  * on the same 8Kb page.
 39  */
 40 struct smx_bootinfo smxboot_space = {{{1}}};
 41 struct smx_bootinfo *smxboot;
 42 #endif
 43 
 44 static char rcsid[] = "$Id: main.c,v 1.6 1996/08/14 04:39:57 paul Exp $";   /* Must follow smxboot! */
 45 
 46 
 47 /*===========================================================================*
 48  *                                   main                                    *
 49  *===========================================================================*/
 50 PUBLIC void main()
 51 {
 52 /* Start the ball rolling. */
 53 
 54   register struct proc *rp;
 55   register int t;
 56   int sizeindex;
 57   phys_clicks text_base = 0;
 58   vir_clicks text_clicks;
 59   vir_clicks data_clicks;
 60 #if (MACHINE != SUN)
 61   phys_bytes phys_b;
 62 #endif
 63   reg_t ktsb;                   /* kernel task stack base */
 64   struct memory *memp = 0;
 65   struct tasktab *ttp;
 66 #if (MACHINE == SUN)
 67   unsigned long addr;
 68   int prog_num;
 69   smxboot = (struct smx_bootinfo *) downclick((int) &smxboot_space);
 70   
 71   log_init();
 72 
 73   /* fetch values that were placed by the minix bootstrap */
 74   code_base = smxboot->prog[KERNEL_PROG].text_vaddr;
 75   tot_mem_size = smxboot->mem_bytes >> CLICK_SHIFT;
 76   set_debug_level(smxboot->debug);
 77 #if ENABLE_NETWORKING
 78   se_init((char *)&smxboot->ether_addr);
 79 #endif
 80   
 81 
 82   debug_str("Starting kernel - debugging on; smxboot addr = ");
 83   debug_int((int) &smxboot);
 84   debug_str("\n");
 85 
 86   /*
 87    * Unmap the text and data segments of the minix bootstrap program.  They
 88    * are no longer needed, and we will map in init and all other user programs
 89    * in that address range.
 90    */
 91   for (addr = 0x10000; addr < (unsigned long)code_base; addr += CLICK_SIZE) {
 92         SunOS(SYS_munmap, addr, CLICK_SIZE);
 93   }
 94 
 95   lock();    /* Lock out non-error SunOS signals until initialisation done */
 96 #endif
 97 
 98 
 99 #if (CHIP == INTEL)
100   /* Initialize the interrupt controller. */
101   intr_init(1);
102 #endif
103 
104   /* Interpret memory sizes. */
105   mem_init();
106 
107   /* Clear the process table.
108    * Set up mappings for proc_addr() and proc_number() macros.
109    */
110   for (rp = BEG_PROC_ADDR, t = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++t) {
111         rp->p_flags = P_SLOT_FREE;
112 #if (MACHINE == SUN)
113         rp->p_stn = INVALID_STN;   /* not currently part of an interaction */
114 #endif
115         rp->p_nr = t;           /* proc number from ptr */
116         (pproc_addr + NR_TASKS)[t] = rp;        /* proc ptr from number */
117   }
118 
119   /* Set up proc table entries for tasks and servers.  The stacks of the
120    * kernel tasks are initialized to an array in data space.  The stacks
121    * of the servers have been added to the data segment by the monitor, so
122    * the stack pointer is set to the end of the data segment.  All the
123    * processes are in low memory on the 8086.  On the 386 only the kernel
124    * is in low memory, the rest if loaded in extended memory.
125    */
126 
127   /* Task stacks. */
128   ktsb = (reg_t) t_stack;
129 
130   for (t = -NR_TASKS; t <= LOW_USER; ++t) {
131         rp = proc_addr(t);                      /* t's process slot */
132         ttp = &tasktab[t + NR_TASKS];           /* t's task attributes */
133         strcpy(rp->p_name, ttp->name);
134 
135 #if (MACHINE == SUN)
136         /*
137          * Initialise the context for each process with the current
138          * context of the SunOS process.  Critical values (sp, pc, npc)
139          * will be set before the context is used to start the smx process.
140          */
141         SunOS(SYS_context, 0, &rp->p_reg);
142 #endif
143 
144         if (t < 0) {
145                 if (ttp->stksize > 0) {
146                         rp->p_stguard = (reg_t *) ktsb;
147                         *rp->p_stguard = STACK_GUARD;
148                 }
149                 ktsb += ttp->stksize;
150                 rp->p_reg.sp = ktsb;
151                 text_base = code_base >> CLICK_SHIFT;
152                                         /* tasks are all in the kernel */
153                 sizeindex = 0;          /* and use the full kernel sizes */
154                 memp = &mem[0];         /* remove from this memory chunk */
155         } else {
156                 sizeindex = 2 * t + 2;  /* MM, FS, INIT have their own sizes*/
157         }
158         rp->p_reg.pc = (reg_t) ttp->initial_pc;
159         rp->p_reg.psw = istaskp(rp) ? INIT_TASK_PSW : INIT_PSW;
160 
161 #if (MACHINE == SUN)
162         /*
163          * Use the boot info to determine the sizes of the text and
164          * data segments.  All tasks are within the kernel.
165          */
166         if (istaskp(rp) || isidlehardware(proc_number(rp))) {
167                 prog_num = KERNEL_PROG;
168         } else {
169                 prog_num = proc_number(rp) + (MM_PROG - MM_PROC_NR);
170         }
171 
172         text_clicks = smxboot->prog[prog_num].text_clicks;
173         data_clicks = smxboot->prog[prog_num].data_clicks;
174 #endif
175 
176         rp->p_map[T].mem_phys = text_base;
177         rp->p_map[T].mem_len  = text_clicks;
178         rp->p_map[D].mem_phys = text_base + text_clicks;
179         rp->p_map[D].mem_len  = data_clicks;
180         rp->p_map[S].mem_phys = text_base + text_clicks + data_clicks;
181         rp->p_map[S].mem_vir  = data_clicks;    /* empty - stack is in data */
182 
183 #if (MACHINE == SUN)
184         /*
185          * Servers and user programs are mapped into the standard
186          * SunOS addresses.  The Virtual addresses are specified in
187          * the boot info.  The kernel is executed "in-situ", so the
188          * virtual addresses are the same as physical addresses.
189          */
190         if (istaskp(rp) || isidlehardware(proc_number(rp))) {
191                 rp->p_map[T].mem_vir = rp->p_map[T].mem_phys;
192                 rp->p_map[D].mem_vir = rp->p_map[D].mem_phys;
193                 rp->p_map[S].mem_vir = rp->p_map[S].mem_phys;
194         } else {
195                 rp->p_map[T].mem_vir = smxboot->prog[prog_num].text_vaddr >>
196                     CLICK_SHIFT;
197                 rp->p_map[D].mem_vir = smxboot->prog[prog_num].data_vaddr >>
198                     CLICK_SHIFT;
199                 rp->p_map[S].mem_vir = rp->p_map[D].mem_vir + data_clicks;
200                 rp->p_reg.pc = smxboot->prog[prog_num].entry;
201                 rp->p_reg.sp = rp->p_map[S].mem_vir << CLICK_SHIFT;
202         }
203         if (prog_num == INIT_PROG) {
204             /*
205              * Take the last click of the data/stack segment for the stack.
206              * The src/tools/Makefile must ensure that the gap is big
207              * enough to allow this.
208              */
209             rp->p_map[S].mem_len = 1;
210             rp->p_map[S].mem_phys -= 1;
211             rp->p_map[S].mem_vir = (code_base >> CLICK_SHIFT) -
212                 rp->p_map[S].mem_len;
213             rp->p_reg.sp = (rp->p_map[S].mem_vir + rp->p_map[S].mem_len) <<
214                 CLICK_SHIFT;
215             rp->p_map[D].mem_len -= 1;
216         } else {
217             rp->p_map[S].mem_len = 0;
218         }
219         rp->p_reg.npc = rp->p_reg.pc + 4;
220         rp->p_reg.sp -= INIT_SP;       /*leave room for a stack frame*/
221 
222 #endif /* MACHINE == SUN */
223         debug_str("Process "); debug_int(t);
224         debug_str(": pc = "); debug_int(rp->p_reg.pc);
225         debug_str(", sp = "); debug_int(rp->p_reg.sp);
226         debug_str("\n");
227         text_base += text_clicks + data_clicks; /* ready for next, if server */
228 
229         memp->size -= (text_base - memp->base);
230         memp->base = text_base;                 /* memory no longer free */
231 
232 #if (CHIP == INTEL)
233         if (t >= 0) {
234                 /* Initialize the server stack pointer.  Take it down one word
235                  * to give crtso.s something to use as "argc".
236                  */
237                 rp->p_reg.sp = (rp->p_map[S].mem_vir +
238                                 rp->p_map[S].mem_len) << CLICK_SHIFT;
239                 rp->p_reg.sp -= sizeof(reg_t);
240         }
241 
242 #if _WORD_SIZE == 4
243         /* Servers are loaded in extended memory if in 386 mode. */
244         if (t < 0) {
245                 memp = &mem[1];
246                 text_base = 0x100000 >> CLICK_SHIFT;
247         }
248 #endif
249 #endif /* CHIP == INTEL */
250         if (!isidlehardware(t)) lock_ready(rp); /* IDLE, HARDWARE neveready */
251         rp->p_flags = 0;
252 
253 #if (CHIP == INTEL)
254         alloc_segments(rp);
255 #endif
256   }
257 
258   proc[NR_TASKS+INIT_PROC_NR].p_pid = 1;/* INIT of course has pid 1 */
259   bill_ptr = proc_addr(IDLE);           /* it has to point somewhere */
260   lock_pick_proc();
261 
262 #if (MACHINE == SUN)
263   init_sun_handlers();                 /* Initialise sun signal handling */
264   /*
265    * Setup the smx boot information.
266    */
267   boot_parameters.bp_rootdev = DEV_FD0;
268   boot_parameters.bp_ramimagedev = 0;
269   boot_parameters.bp_ramsize = 0;
270   boot_parameters.bp_processor = CHIP;
271 
272   /*
273    * Initialise the protection according to the protection level
274    * specified from the minix bootstrap.
275    */
276   protect_init(code_base, smxboot->prog[KERNEL_PROG].text_clicks,
277                smxboot->prog[KERNEL_PROG].data_clicks, tot_mem_size,
278                smxboot->prot_lev);
279 
280   /* enable all SunOS signals */
281   unlock();
282 #endif /* MACHINE == SUN */
283 
284   debug_str("In kernel main---about to call restart\n");
285 
286   /* Now go to the assembly code to start running the current process. */
287   restart();
288 }
289 
290 
291 /*===========================================================================*
292  *                                   panic                                   *
293  *===========================================================================*/
294 PUBLIC void panic(s,n)
295 _CONST char *s;
296 int n;
297 {
298 /* The system has run aground of a fatal error.  Terminate execution.
299  * If the panic originated in MM or FS, the string will be empty and the
300  * file system already syncked.  If the panic originates in the kernel, we are
301  * kind of stuck.
302  */
303 
304   if (*s != 0) {
305         printf("\nKernel panic: %s",s);
306         if (n != NO_NUM) printf(" %d", n);
307         printf("\n");
308   }
309 #if (MACHINE == SUN)
310   /* a useful register and context dump */
311   do_dump();
312 #endif
313   wreboot(RBT_PANIC);
314 }
315 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.