Annotation of linux/init/main.c, revision 1.1.1.11

1.1.1.2   root        1: /*
                      2:  *  linux/init/main.c
                      3:  *
1.1.1.10  root        4:  *  Copyright (C) 1991, 1992  Linus Torvalds
1.1.1.2   root        5:  */
                      6: 
1.1.1.7   root        7: #include <stdarg.h>
1.1       root        8: 
1.1.1.7   root        9: #include <asm/system.h>
                     10: #include <asm/io.h>
                     11: 
1.1.1.11! root       12: #include <linux/mktime.h>
1.1.1.10  root       13: #include <linux/types.h>
1.1.1.9   root       14: #include <linux/fcntl.h>
1.1.1.7   root       15: #include <linux/config.h>
                     16: #include <linux/sched.h>
                     17: #include <linux/tty.h>
                     18: #include <linux/head.h>
                     19: #include <linux/unistd.h>
                     20: 
1.1.1.11! root       21: extern unsigned long * prof_buffer;
        !            22: extern unsigned long prof_len;
        !            23: extern int end;
        !            24: extern char *linux_banner;
        !            25: 
1.1       root       26: /*
                     27:  * we need this inline - forking from kernel space will result
                     28:  * in NO COPY ON WRITE (!!!), until an execve is executed. This
                     29:  * is no problem, but for the stack. This is handled by not letting
                     30:  * main() use the stack at all after fork(). Thus, no function
                     31:  * calls - which means inline code for fork too, as otherwise we
                     32:  * would use the stack upon exit from 'fork()'.
                     33:  *
                     34:  * Actually only pause and fork are needed inline, so that there
                     35:  * won't be any messing with the stack from main(), but we define
                     36:  * some others too.
                     37:  */
1.1.1.11! root       38: static inline _syscall0(int,idle)
1.1       root       39: static inline _syscall0(int,fork)
                     40: static inline _syscall0(int,pause)
1.1.1.2   root       41: static inline _syscall1(int,setup,void *,BIOS)
1.1       root       42: static inline _syscall0(int,sync)
1.1.1.7   root       43: static inline _syscall0(pid_t,setsid)
                     44: static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
                     45: static inline _syscall1(int,dup,int,fd)
                     46: static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
1.1.1.9   root       47: static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
1.1.1.7   root       48: static inline _syscall1(int,close,int,fd)
                     49: static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
1.1       root       50: 
1.1.1.7   root       51: static inline pid_t wait(int * wait_stat)
                     52: {
                     53:        return waitpid(-1,wait_stat,0);
                     54: }
1.1.1.4   root       55: 
1.1       root       56: static char printbuf[1024];
                     57: 
                     58: extern int vsprintf();
                     59: extern void init(void);
1.1.1.10  root       60: extern void init_IRQ(void);
1.1.1.9   root       61: extern long blk_dev_init(long,long);
                     62: extern long chr_dev_init(long,long);
1.1.1.2   root       63: extern void floppy_init(void);
1.1.1.7   root       64: extern void sock_init(void);
1.1.1.3   root       65: extern long rd_init(long mem_start, int length);
1.1.1.11! root       66: extern long kernel_mktime(struct mktime * time);
1.1.1.4   root       67: 
1.1.1.7   root       68: #ifdef CONFIG_SCSI
                     69: extern void scsi_dev_init(void);
                     70: #endif
                     71: 
1.1.1.4   root       72: static int sprintf(char * str, const char *fmt, ...)
                     73: {
                     74:        va_list args;
                     75:        int i;
                     76: 
                     77:        va_start(args, fmt);
                     78:        i = vsprintf(str, fmt, args);
                     79:        va_end(args);
                     80:        return i;
                     81: }
1.1       root       82: 
                     83: /*
1.1.1.2   root       84:  * This is set up by the setup-routine at boot-time
                     85:  */
                     86: #define EXT_MEM_K (*(unsigned short *)0x90002)
                     87: #define DRIVE_INFO (*(struct drive_info *)0x90080)
1.1.1.10  root       88: #define SCREEN_INFO (*(struct screen_info *)0x90000)
1.1.1.2   root       89: #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
1.1.1.11! root       90: #define AUX_DEVICE_INFO (*(unsigned char *)0x901FF)
1.1.1.2   root       91: 
                     92: /*
1.1       root       93:  * Yeah, yeah, it's ugly, but I cannot find how to do this correctly
                     94:  * and this seems to work. I anybody has more info on the real-time
                     95:  * clock I'd be interested. Most of this was trial and error, and some
                     96:  * bios-listing reading. Urghh.
                     97:  */
                     98: 
                     99: #define CMOS_READ(addr) ({ \
                    100: outb_p(0x80|addr,0x70); \
                    101: inb_p(0x71); \
                    102: })
                    103: 
                    104: #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
                    105: 
                    106: static void time_init(void)
                    107: {
1.1.1.11! root      108:        struct mktime time;
1.1       root      109: 
                    110:        do {
1.1.1.11! root      111:                time.sec = CMOS_READ(0);
        !           112:                time.min = CMOS_READ(2);
        !           113:                time.hour = CMOS_READ(4);
        !           114:                time.day = CMOS_READ(7);
        !           115:                time.mon = CMOS_READ(8);
        !           116:                time.year = CMOS_READ(9);
        !           117:        } while (time.sec != CMOS_READ(0));
        !           118:        BCD_TO_BIN(time.sec);
        !           119:        BCD_TO_BIN(time.min);
        !           120:        BCD_TO_BIN(time.hour);
        !           121:        BCD_TO_BIN(time.day);
        !           122:        BCD_TO_BIN(time.mon);
        !           123:        BCD_TO_BIN(time.year);
        !           124:        time.mon--;
1.1       root      125:        startup_time = kernel_mktime(&time);
                    126: }
                    127: 
1.1.1.11! root      128: static unsigned long memory_start = 0; /* After mem_init, stores the */
        !           129:                                       /* amount of free user memory */
1.1.1.10  root      130: static unsigned long memory_end = 0;
1.1.1.11! root      131: static unsigned long low_memory_start = 0;
1.1.1.10  root      132: 
1.1.1.4   root      133: static char term[32];
                    134: 
1.1.1.5   root      135: static char * argv_init[] = { "/bin/init", NULL };
                    136: static char * envp_init[] = { "HOME=/", NULL, NULL };
                    137: 
1.1.1.4   root      138: static char * argv_rc[] = { "/bin/sh", NULL };
                    139: static char * envp_rc[] = { "HOME=/", NULL ,NULL };
                    140: 
                    141: static char * argv[] = { "-/bin/sh",NULL };
                    142: static char * envp[] = { "HOME=/usr/root", NULL, NULL };
1.1.1.2   root      143: 
                    144: struct drive_info { char dummy[32]; } drive_info;
1.1.1.10  root      145: struct screen_info screen_info;
1.1.1.2   root      146: 
1.1.1.11! root      147: unsigned char aux_device_present;
        !           148: 
1.1.1.5   root      149: void start_kernel(void)
                    150: {
1.1       root      151: /*
                    152:  * Interrupts are still disabled. Do necessary setups, then
                    153:  * enable them
                    154:  */
1.1.1.2   root      155:        ROOT_DEV = ORIG_ROOT_DEV;
1.1.1.10  root      156:        drive_info = DRIVE_INFO;
                    157:        screen_info = SCREEN_INFO;
1.1.1.11! root      158:        aux_device_present = AUX_DEVICE_INFO;
1.1.1.10  root      159:        sprintf(term, "TERM=con%dx%d", ORIG_VIDEO_COLS, ORIG_VIDEO_LINES);
1.1.1.4   root      160:        envp[1] = term; 
                    161:        envp_rc[1] = term;
1.1.1.5   root      162:        envp_init[1] = term;
1.1.1.2   root      163:        memory_end = (1<<20) + (EXT_MEM_K<<10);
                    164:        memory_end &= 0xfffff000;
1.1.1.11! root      165:        if (memory_end > MAX_MEGABYTES*1024*1024)
        !           166:                memory_end = MAX_MEGABYTES*1024*1024;
1.1.1.10  root      167:        memory_start = 1024*1024;
1.1.1.11! root      168:        low_memory_start = (unsigned long) &end;
        !           169:        low_memory_start += 0xfff;
        !           170:        low_memory_start &= 0xfffff000;
1.1       root      171:        trap_init();
1.1.1.10  root      172:        init_IRQ();
1.1.1.7   root      173:        sched_init();
1.1.1.11! root      174: #ifdef PROFILE_SHIFT
        !           175:        prof_buffer = (unsigned long *) memory_start;
        !           176:        prof_len = (unsigned long) &end;
        !           177:        prof_len >>= PROFILE_SHIFT;
        !           178:        memory_start += prof_len * sizeof(unsigned long);
        !           179: #endif
1.1.1.10  root      180:        memory_start = chr_dev_init(memory_start,memory_end);
                    181:        memory_start = blk_dev_init(memory_start,memory_end);
1.1.1.11! root      182:        mem_init(low_memory_start,memory_start,memory_end);
1.1.1.10  root      183:        buffer_init();
1.1.1.2   root      184:        time_init();
                    185:        floppy_init();
1.1.1.7   root      186:        sock_init();
1.1       root      187:        sti();
1.1.1.7   root      188: #ifdef CONFIG_SCSI
                    189:        scsi_dev_init();
                    190: #endif
1.1.1.11! root      191:        sti();
1.1       root      192:        move_to_user_mode();
1.1.1.11! root      193:        if (!fork())            /* we count on this going ok */
1.1       root      194:                init();
                    195: /*
1.1.1.10  root      196:  * task[0] is meant to be used as an "idle" task: it may not sleep, but
                    197:  * it might do some general things like count free pages or it could be
                    198:  * used to implement a reasonable LRU algorithm for the paging routines:
                    199:  * anything that can be useful, but shouldn't take time from the real
                    200:  * processes.
                    201:  *
1.1.1.11! root      202:  * Right now task[0] just does a infinite idle loop.
1.1       root      203:  */
1.1.1.4   root      204:        for(;;)
1.1.1.11! root      205:                idle();
1.1       root      206: }
                    207: 
                    208: static int printf(const char *fmt, ...)
                    209: {
                    210:        va_list args;
                    211:        int i;
                    212: 
                    213:        va_start(args, fmt);
                    214:        write(1,printbuf,i=vsprintf(printbuf, fmt, args));
                    215:        va_end(args);
                    216:        return i;
                    217: }
                    218: 
                    219: void init(void)
                    220: {
1.1.1.3   root      221:        int pid,i;
1.1       root      222: 
1.1.1.2   root      223:        setup((void *) &drive_info);
1.1.1.4   root      224:        (void) open("/dev/tty1",O_RDWR,0);
1.1       root      225:        (void) dup(0);
                    226:        (void) dup(0);
1.1.1.5   root      227: 
1.1.1.11! root      228:        printf(linux_banner);
1.1.1.6   root      229:        execve("/etc/init",argv_init,envp_init);
1.1.1.5   root      230:        execve("/bin/init",argv_init,envp_init);
                    231:        /* if this fails, fall through to original stuff */
                    232: 
1.1.1.3   root      233:        if (!(pid=fork())) {
                    234:                close(0);
                    235:                if (open("/etc/rc",O_RDONLY,0))
                    236:                        _exit(1);
                    237:                execve("/bin/sh",argv_rc,envp_rc);
                    238:                _exit(2);
                    239:        }
                    240:        if (pid>0)
                    241:                while (pid != wait(&i))
                    242:                        /* nothing */;
                    243:        while (1) {
                    244:                if ((pid=fork())<0) {
                    245:                        printf("Fork failed in init\r\n");
                    246:                        continue;
                    247:                }
                    248:                if (!pid) {
                    249:                        close(0);close(1);close(2);
                    250:                        setsid();
1.1.1.4   root      251:                        (void) open("/dev/tty1",O_RDWR,0);
1.1.1.3   root      252:                        (void) dup(0);
                    253:                        (void) dup(0);
                    254:                        _exit(execve("/bin/sh",argv,envp));
                    255:                }
                    256:                while (1)
                    257:                        if (pid == wait(&i))
                    258:                                break;
                    259:                printf("\n\rchild %d died with code %04x\n\r",pid,i);
                    260:                sync();
1.1       root      261:        }
                    262:        _exit(0);       /* NOTE! _exit, not exit() */
                    263: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.