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

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

unix.superglobalmegacorp.com

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