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

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

unix.superglobalmegacorp.com

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