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

1.1     ! root        1: #define __LIBRARY__
        !             2: #include <unistd.h>
        !             3: #include <time.h>
        !             4: 
        !             5: /*
        !             6:  * we need this inline - forking from kernel space will result
        !             7:  * in NO COPY ON WRITE (!!!), until an execve is executed. This
        !             8:  * is no problem, but for the stack. This is handled by not letting
        !             9:  * main() use the stack at all after fork(). Thus, no function
        !            10:  * calls - which means inline code for fork too, as otherwise we
        !            11:  * would use the stack upon exit from 'fork()'.
        !            12:  *
        !            13:  * Actually only pause and fork are needed inline, so that there
        !            14:  * won't be any messing with the stack from main(), but we define
        !            15:  * some others too.
        !            16:  */
        !            17: static inline _syscall0(int,fork)
        !            18: static inline _syscall0(int,pause)
        !            19: static inline _syscall0(int,setup)
        !            20: static inline _syscall0(int,sync)
        !            21: 
        !            22: #include <linux/tty.h>
        !            23: #include <linux/sched.h>
        !            24: #include <linux/head.h>
        !            25: #include <asm/system.h>
        !            26: #include <asm/io.h>
        !            27: 
        !            28: #include <stddef.h>
        !            29: #include <stdarg.h>
        !            30: #include <unistd.h>
        !            31: #include <fcntl.h>
        !            32: #include <sys/types.h>
        !            33: 
        !            34: #include <linux/fs.h>
        !            35: 
        !            36: static char printbuf[1024];
        !            37: 
        !            38: extern int vsprintf();
        !            39: extern void init(void);
        !            40: extern void hd_init(void);
        !            41: extern long kernel_mktime(struct tm * tm);
        !            42: extern long startup_time;
        !            43: 
        !            44: /*
        !            45:  * Yeah, yeah, it's ugly, but I cannot find how to do this correctly
        !            46:  * and this seems to work. I anybody has more info on the real-time
        !            47:  * clock I'd be interested. Most of this was trial and error, and some
        !            48:  * bios-listing reading. Urghh.
        !            49:  */
        !            50: 
        !            51: #define CMOS_READ(addr) ({ \
        !            52: outb_p(0x80|addr,0x70); \
        !            53: inb_p(0x71); \
        !            54: })
        !            55: 
        !            56: #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
        !            57: 
        !            58: static void time_init(void)
        !            59: {
        !            60:        struct tm time;
        !            61: 
        !            62:        do {
        !            63:                time.tm_sec = CMOS_READ(0);
        !            64:                time.tm_min = CMOS_READ(2);
        !            65:                time.tm_hour = CMOS_READ(4);
        !            66:                time.tm_mday = CMOS_READ(7);
        !            67:                time.tm_mon = CMOS_READ(8)-1;
        !            68:                time.tm_year = CMOS_READ(9);
        !            69:        } while (time.tm_sec != CMOS_READ(0));
        !            70:        BCD_TO_BIN(time.tm_sec);
        !            71:        BCD_TO_BIN(time.tm_min);
        !            72:        BCD_TO_BIN(time.tm_hour);
        !            73:        BCD_TO_BIN(time.tm_mday);
        !            74:        BCD_TO_BIN(time.tm_mon);
        !            75:        BCD_TO_BIN(time.tm_year);
        !            76:        startup_time = kernel_mktime(&time);
        !            77: }
        !            78: 
        !            79: void main(void)                /* This really IS void, no error here. */
        !            80: {                      /* The startup routine assumes (well, ...) this */
        !            81: /*
        !            82:  * Interrupts are still disabled. Do necessary setups, then
        !            83:  * enable them
        !            84:  */
        !            85:        time_init();
        !            86:        tty_init();
        !            87:        trap_init();
        !            88:        sched_init();
        !            89:        buffer_init();
        !            90:        hd_init();
        !            91:        sti();
        !            92:        move_to_user_mode();
        !            93:        if (!fork()) {          /* we count on this going ok */
        !            94:                init();
        !            95:        }
        !            96: /*
        !            97:  *   NOTE!!   For any other task 'pause()' would mean we have to get a
        !            98:  * signal to awaken, but task0 is the sole exception (see 'schedule()')
        !            99:  * as task 0 gets activated at every idle moment (when no other tasks
        !           100:  * can run). For task0 'pause()' just means we go check if some other
        !           101:  * task can run, and if not we return here.
        !           102:  */
        !           103:        for(;;) pause();
        !           104: }
        !           105: 
        !           106: static int printf(const char *fmt, ...)
        !           107: {
        !           108:        va_list args;
        !           109:        int i;
        !           110: 
        !           111:        va_start(args, fmt);
        !           112:        write(1,printbuf,i=vsprintf(printbuf, fmt, args));
        !           113:        va_end(args);
        !           114:        return i;
        !           115: }
        !           116: 
        !           117: static char * argv[] = { "-",NULL };
        !           118: static char * envp[] = { "HOME=/usr/root", NULL };
        !           119: 
        !           120: void init(void)
        !           121: {
        !           122:        int i,j;
        !           123: 
        !           124:        setup();
        !           125:        if (!fork())
        !           126:                _exit(execve("/bin/update",NULL,NULL));
        !           127:        (void) open("/dev/tty0",O_RDWR,0);
        !           128:        (void) dup(0);
        !           129:        (void) dup(0);
        !           130:        printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,
        !           131:                NR_BUFFERS*BLOCK_SIZE);
        !           132:        printf(" Ok.\n\r");
        !           133:        if ((i=fork())<0)
        !           134:                printf("Fork failed in init\r\n");
        !           135:        else if (!i) {
        !           136:                close(0);close(1);close(2);
        !           137:                setsid();
        !           138:                (void) open("/dev/tty0",O_RDWR,0);
        !           139:                (void) dup(0);
        !           140:                (void) dup(0);
        !           141:                _exit(execve("/bin/sh",argv,envp));
        !           142:        }
        !           143:        j=wait(&i);
        !           144:        printf("child %d died with code %04x\n",j,i);
        !           145:        sync();
        !           146:        _exit(0);       /* NOTE! _exit, not exit() */
        !           147: }

unix.superglobalmegacorp.com

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