diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
commit | e7c2a72e2680827d6a733931273a93461c0d8d1b (patch) | |
tree | c9abeda78ef7504062bb2e816bcf3e3c9d680112 /arch/i386/main.c | |
parent | ec6044459060a8c9ce7f64405c465d141898548c (diff) |
Import of Linux/MIPS 1.3.0
Diffstat (limited to 'arch/i386/main.c')
-rw-r--r-- | arch/i386/main.c | 481 |
1 files changed, 0 insertions, 481 deletions
diff --git a/arch/i386/main.c b/arch/i386/main.c deleted file mode 100644 index 49606d4de..000000000 --- a/arch/i386/main.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * linux/init/main.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include <stdarg.h> - -#include <asm/system.h> -#include <asm/io.h> - -#include <linux/types.h> -#include <linux/fcntl.h> -#include <linux/config.h> -#include <linux/sched.h> -#include <linux/tty.h> -#include <linux/head.h> -#include <linux/unistd.h> -#include <linux/string.h> -#include <linux/timer.h> -#include <linux/fs.h> -#include <linux/ctype.h> -#include <linux/delay.h> -#include <linux/utsname.h> -#include <linux/ioport.h> - -extern unsigned long * prof_buffer; -extern unsigned long prof_len; -extern char edata, end; -extern char *linux_banner; -asmlinkage void lcall7(void); -struct desc_struct default_ldt; - -/* - * we need this inline - forking from kernel space will result - * in NO COPY ON WRITE (!!!), until an execve is executed. This - * is no problem, but for the stack. This is handled by not letting - * main() use the stack at all after fork(). Thus, no function - * calls - which means inline code for fork too, as otherwise we - * would use the stack upon exit from 'fork()'. - * - * Actually only pause and fork are needed inline, so that there - * won't be any messing with the stack from main(), but we define - * some others too. - */ -#define __NR__exit __NR_exit -static inline _syscall0(int,idle) -static inline _syscall0(int,fork) -static inline _syscall0(int,pause) -static inline _syscall0(int,setup) -static inline _syscall0(int,sync) -static inline _syscall0(pid_t,setsid) -static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) -static inline _syscall1(int,dup,int,fd) -static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) -static inline _syscall3(int,open,const char *,file,int,flag,int,mode) -static inline _syscall1(int,close,int,fd) -static inline _syscall1(int,_exit,int,exitcode) -static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) - -static inline pid_t wait(int * wait_stat) -{ - return waitpid(-1,wait_stat,0); -} - -static char printbuf[1024]; - -extern int console_loglevel; - -extern char empty_zero_page[PAGE_SIZE]; -extern void init(void); -extern void init_IRQ(void); -extern void init_modules(void); -extern long console_init(long, long); -extern long kmalloc_init(long,long); -extern long blk_dev_init(long,long); -extern long chr_dev_init(long,long); -extern void sock_init(void); -extern long rd_init(long mem_start, int length); -unsigned long net_dev_init(unsigned long, unsigned long); -extern long bios32_init(long, long); - -extern void hd_setup(char *str, int *ints); -extern void bmouse_setup(char *str, int *ints); -extern void eth_setup(char *str, int *ints); -extern void xd_setup(char *str, int *ints); -extern void mcd_setup(char *str, int *ints); -extern void st_setup(char *str, int *ints); -extern void st0x_setup(char *str, int *ints); -extern void tmc8xx_setup(char *str, int *ints); -extern void t128_setup(char *str, int *ints); -extern void pas16_setup(char *str, int *ints); -extern void generic_NCR5380_setup(char *str, int *intr); -extern void aha152x_setup(char *str, int *ints); -extern void aha1542_setup(char *str, int *ints); -extern void aha274x_setup(char *str, int *ints); -extern void scsi_luns_setup(char *str, int *ints); -extern void sound_setup(char *str, int *ints); -#ifdef CONFIG_SBPCD -extern void sbpcd_setup(char *str, int *ints); -#endif CONFIG_SBPCD -#ifdef CONFIG_CDU31A -extern void cdu31a_setup(char *str, int *ints); -#endif CONFIG_CDU31A -void ramdisk_setup(char *str, int *ints); - -#ifdef CONFIG_SYSVIPC -extern void ipc_init(void); -#endif -#ifdef CONFIG_SCSI -extern unsigned long scsi_dev_init(unsigned long, unsigned long); -#endif - -/* - * This is set up by the setup-routine at boot-time - */ -#define PARAM empty_zero_page -#define EXT_MEM_K (*(unsigned short *) (PARAM+2)) -#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80)) -#define SCREEN_INFO (*(struct screen_info *) (PARAM+0)) -#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2)) -#define RAMDISK_SIZE (*(unsigned short *) (PARAM+0x1F8)) -#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC)) -#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF)) - -/* - * Boot command-line arguments - */ -void copy_options(char * to, char * from); -void parse_options(char *line); -#define MAX_INIT_ARGS 8 -#define MAX_INIT_ENVS 8 -#define COMMAND_LINE ((char *) (PARAM+2048)) -#define COMMAND_LINE_SIZE 256 - -extern void time_init(void); - -static unsigned long memory_start = 0; /* After mem_init, stores the */ - /* amount of free user memory */ -static unsigned long memory_end = 0; -static unsigned long low_memory_start = 0; - -static char term[21]; -int rows, cols; - -static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; -static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", term, NULL, }; - -static char * argv_rc[] = { "/bin/sh", NULL }; -static char * envp_rc[] = { "HOME=/", term, NULL }; - -static char * argv[] = { "-/bin/sh",NULL }; -static char * envp[] = { "HOME=/usr/root", term, NULL }; - -struct drive_info_struct { char dummy[32]; } drive_info; -struct screen_info screen_info; - -unsigned char aux_device_present; -int ramdisk_size; -int root_mountflags = 0; - -static char fpu_error = 0; - -static char command_line[COMMAND_LINE_SIZE] = { 0, }; - -char *get_options(char *str, int *ints) -{ - char *cur = str; - int i=1; - - while (cur && isdigit(*cur) && i <= 10) { - ints[i++] = simple_strtoul(cur,NULL,0); - if ((cur = strchr(cur,',')) != NULL) - cur++; - } - ints[0] = i-1; - return(cur); -} - -struct { - char *str; - void (*setup_func)(char *, int *); -} bootsetups[] = { - { "reserve=", reserve_setup }, - { "ramdisk=", ramdisk_setup }, -#ifdef CONFIG_INET - { "ether=", eth_setup }, -#endif -#ifdef CONFIG_SCSI - { "max_scsi_luns=", scsi_luns_setup }, -#endif -#ifdef CONFIG_BLK_DEV_HD - { "hd=", hd_setup }, -#endif -#ifdef CONFIG_CHR_DEV_ST - { "st=", st_setup }, -#endif -#ifdef CONFIG_BUSMOUSE - { "bmouse=", bmouse_setup }, -#endif -#ifdef CONFIG_SCSI_SEAGATE - { "st0x=", st0x_setup }, - { "tmc8xx=", tmc8xx_setup }, -#endif -#ifdef CONFIG_SCSI_T128 - { "t128=", t128_setup }, -#endif -#ifdef CONFIG_SCSI_PAS16 - { "pas16=", pas16_setup }, -#endif -#ifdef CONFIG_SCSI_GENERIC_NCR5380 - { "ncr5380=", generic_NCR5380_setup }, -#endif -#ifdef CONFIG_SCSI_AHA152X - { "aha152x=", aha152x_setup}, -#endif -#ifdef CONFIG_SCSI_AHA1542 - { "aha1542=", aha1542_setup}, -#endif -#ifdef CONFIG_SCSI_AHA274X - { "aha274x=", aha274x_setup}, -#endif -#ifdef CONFIG_BLK_DEV_XD - { "xd=", xd_setup }, -#endif -#ifdef CONFIG_MCD - { "mcd=", mcd_setup }, -#endif -#ifdef CONFIG_SOUND - { "sound=", sound_setup }, -#endif -#ifdef CONFIG_SBPCD - { "sbpcd=", sbpcd_setup }, -#endif CONFIG_SBPCD -#ifdef CONFIG_CDU31A - { "cdu31a=", cdu31a_setup }, -#endif CONFIG_CDU31A - { 0, 0 } -}; - -void ramdisk_setup(char *str, int *ints) -{ - if (ints[0] > 0 && ints[1] >= 0) - ramdisk_size = ints[1]; -} - -static int checksetup(char *line) -{ - int i = 0; - int ints[11]; - - while (bootsetups[i].str) { - int n = strlen(bootsetups[i].str); - if (!strncmp(line,bootsetups[i].str,n)) { - bootsetups[i].setup_func(get_options(line+n,ints), ints); - return 1; - } - i++; - } - return 0; -} - -unsigned long loops_per_sec = 1; - -static void calibrate_delay(void) -{ - int ticks; - - printk("Calibrating delay loop.. "); - while (loops_per_sec <<= 1) { - ticks = jiffies; - __delay(loops_per_sec); - ticks = jiffies - ticks; - if (ticks >= HZ) { - __asm__("mull %1 ; divl %2" - :"=a" (loops_per_sec) - :"d" (HZ), - "r" (ticks), - "0" (loops_per_sec) - :"dx"); - printk("ok - %lu.%02lu BogoMips\n", - loops_per_sec/500000, - (loops_per_sec/5000) % 100); - return; - } - } - printk("failed\n"); -} - -/* - * parse machine depended options - */ -int parse_machine_options(char *line) -{ - if (!strcmp(line,"no-hlt")) { - hlt_works_ok = 0; - return 1; - } - if (!strcmp(line,"no387")) { - hard_math = 0; - __asm__("movl %%cr0,%%eax\n\t" - "orl $0xE,%%eax\n\t" - "movl %%eax,%%cr0\n\t" : : : "ax"); - return 1; - } -} - -static void copro_timeout(void) -{ - fpu_error = 1; - timer_table[COPRO_TIMER].expires = jiffies+100; - timer_active |= 1<<COPRO_TIMER; - printk("387 failed: trying to reset\n"); - send_sig(SIGFPE, last_task_used_math, 1); - outb_p(0,0xf1); - outb_p(0,0xf0); -} - -static void check_fpu(void) -{ - static double x = 4195835.0; - static double y = 3145727.0; - unsigned short control_word; - int i; - - if (!hard_math) { -#ifndef CONFIG_MATH_EMULATION - printk("No coprocessor found and no math emulation present.\n"); - printk("Giving up.\n"); - for (;;) ; -#endif - return; - } - /* - * check if exception 16 works correctly.. This is truly evil - * code: it disables the high 8 interrupts to make sure that - * the irq13 doesn't happen. But as this will lead to a lockup - * if no exception16 arrives, it depends on the fact that the - * high 8 interrupts will be re-enabled by the next timer tick. - * So the irq13 will happen eventually, but the exception 16 - * should get there first.. - */ - printk("Checking 386/387 coupling... "); - timer_table[COPRO_TIMER].expires = jiffies+50; - timer_table[COPRO_TIMER].fn = copro_timeout; - timer_active |= 1<<COPRO_TIMER; - __asm__("clts ; fninit ; fnstcw %0 ; fwait":"=m" (*&control_word)); - control_word &= 0xffc0; - __asm__("fldcw %0 ; fwait": :"m" (*&control_word)); - outb_p(inb_p(0x21) | (1 << 2), 0x21); - __asm__("fldz ; fld1 ; fdiv %st,%st(1) ; fwait"); - timer_active &= ~(1<<COPRO_TIMER); - if (fpu_error) - return; - if (!ignore_irq13) { - printk("Ok, fpu using old IRQ13 error reporting\n"); - return; - } - __asm__("fninit\n\t" - "fldl %1\n\t" - "fdivl %2\n\t" - "fmull %2\n\t" - "fldl %1\n\t" - "fsubp %%st,%%st(1)\n\t" - "fistpl %0\n\t" - "fwait\n\t" - "fninit" - : "=m" (*&i) - : "m" (*&x), "m" (*&y)); - if (!i) { - printk("Ok, fpu using exception 16 error reporting.\n"); - return; - - } - printk("Ok, FDIV bug i%c86 system\n", '0'+x86); -} - -static void check_hlt(void) -{ - printk("Checking 'hlt' instruction... "); - if (!hlt_works_ok) { - printk("disabled\n"); - return; - } - __asm__ __volatile__("hlt ; hlt ; hlt ; hlt"); - printk("Ok.\n"); -} - -static void check_bugs(void) -{ - check_fpu(); - check_hlt(); -} - -asmlinkage void start_kernel(void) -{ -/* - * Interrupts are still disabled. Do necessary setups, then - * enable them - */ - set_call_gate(&default_ldt,lcall7); - ROOT_DEV = ORIG_ROOT_DEV; - drive_info = DRIVE_INFO; - screen_info = SCREEN_INFO; - aux_device_present = AUX_DEVICE_INFO; - memory_end = (1<<20) + (EXT_MEM_K<<10); - memory_end &= PAGE_MASK; - ramdisk_size = RAMDISK_SIZE; - copy_options(command_line,COMMAND_LINE); -#ifdef CONFIG_MAX_16M - if (memory_end > 16*1024*1024) - memory_end = 16*1024*1024; -#endif - if (MOUNT_ROOT_RDONLY) - root_mountflags |= MS_RDONLY; - if ((unsigned long)&end >= (1024*1024)) { - memory_start = (unsigned long) &end; - low_memory_start = PAGE_SIZE; - } else { - memory_start = 1024*1024; - low_memory_start = (unsigned long) &end; - } - low_memory_start = PAGE_ALIGN(low_memory_start); - memory_start = paging_init(memory_start,memory_end); - if (strncmp((char*)0x0FFFD9, "EISA", 4) == 0) - EISA_bus = 1; - trap_init(); - init_IRQ(); - sched_init(); - parse_options(command_line); - init_modules(); -#ifdef CONFIG_PROFILE - prof_buffer = (unsigned long *) memory_start; - prof_len = (unsigned long) &end; - prof_len >>= 2; - memory_start += prof_len * sizeof(unsigned long); -#endif - memory_start = console_init(memory_start,memory_end); - memory_start = bios32_init(memory_start,memory_end); - memory_start = kmalloc_init(memory_start,memory_end); - memory_start = chr_dev_init(memory_start,memory_end); - memory_start = blk_dev_init(memory_start,memory_end); - sti(); - calibrate_delay(); -#ifdef CONFIG_SCSI - memory_start = scsi_dev_init(memory_start,memory_end); -#endif -#ifdef CONFIG_INET - memory_start = net_dev_init(memory_start,memory_end); -#endif - memory_start = inode_init(memory_start,memory_end); - memory_start = file_table_init(memory_start,memory_end); - memory_start = name_cache_init(memory_start,memory_end); - mem_init(low_memory_start,memory_start,memory_end); - buffer_init(); - time_init(); - sock_init(); -#ifdef CONFIG_SYSVIPC - ipc_init(); -#endif - sti(); - check_bugs(); - - system_utsname.machine[1] = '0' + x86; - printk(linux_banner); - - move_to_user_mode(); - if (!fork()) /* we count on this going ok */ - init(); -/* - * task[0] is meant to be used as an "idle" task: it may not sleep, but - * it might do some general things like count free pages or it could be - * used to implement a reasonable LRU algorithm for the paging routines: - * anything that can be useful, but shouldn't take time from the real - * processes. - * - * Right now task[0] just does a infinite idle loop. - */ - for(;;) - idle(); -} |