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

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: 
1.1.1.4 ! root       42: #include <string.h>
        !            43: 
1.1       root       44: static char printbuf[1024];
                     45: 
1.1.1.4 ! root       46: extern char *strcpy();
1.1       root       47: extern int vsprintf();
                     48: extern void init(void);
1.1.1.2   root       49: extern void blk_dev_init(void);
                     50: extern void chr_dev_init(void);
1.1       root       51: extern void hd_init(void);
1.1.1.2   root       52: extern void floppy_init(void);
                     53: extern void mem_init(long start, long end);
1.1.1.3   root       54: extern long rd_init(long mem_start, int length);
1.1       root       55: extern long kernel_mktime(struct tm * tm);
1.1.1.4 ! root       56: 
        !            57: static int sprintf(char * str, const char *fmt, ...)
        !            58: {
        !            59:        va_list args;
        !            60:        int i;
        !            61: 
        !            62:        va_start(args, fmt);
        !            63:        i = vsprintf(str, fmt, args);
        !            64:        va_end(args);
        !            65:        return i;
        !            66: }
1.1       root       67: 
                     68: /*
1.1.1.2   root       69:  * This is set up by the setup-routine at boot-time
                     70:  */
                     71: #define EXT_MEM_K (*(unsigned short *)0x90002)
1.1.1.4 ! root       72: #define CON_ROWS ((*(unsigned short *)0x9000e) & 0xff)
        !            73: #define CON_COLS (((*(unsigned short *)0x9000e) & 0xff00) >> 8)
1.1.1.2   root       74: #define DRIVE_INFO (*(struct drive_info *)0x90080)
                     75: #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
1.1.1.4 ! root       76: #define ORIG_SWAP_DEV (*(unsigned short *)0x901FA)
1.1.1.2   root       77: 
                     78: /*
1.1       root       79:  * Yeah, yeah, it's ugly, but I cannot find how to do this correctly
                     80:  * and this seems to work. I anybody has more info on the real-time
                     81:  * clock I'd be interested. Most of this was trial and error, and some
                     82:  * bios-listing reading. Urghh.
                     83:  */
                     84: 
                     85: #define CMOS_READ(addr) ({ \
                     86: outb_p(0x80|addr,0x70); \
                     87: inb_p(0x71); \
                     88: })
                     89: 
                     90: #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
                     91: 
                     92: static void time_init(void)
                     93: {
                     94:        struct tm time;
                     95: 
                     96:        do {
                     97:                time.tm_sec = CMOS_READ(0);
                     98:                time.tm_min = CMOS_READ(2);
                     99:                time.tm_hour = CMOS_READ(4);
                    100:                time.tm_mday = CMOS_READ(7);
1.1.1.2   root      101:                time.tm_mon = CMOS_READ(8);
1.1       root      102:                time.tm_year = CMOS_READ(9);
                    103:        } while (time.tm_sec != CMOS_READ(0));
                    104:        BCD_TO_BIN(time.tm_sec);
                    105:        BCD_TO_BIN(time.tm_min);
                    106:        BCD_TO_BIN(time.tm_hour);
                    107:        BCD_TO_BIN(time.tm_mday);
                    108:        BCD_TO_BIN(time.tm_mon);
                    109:        BCD_TO_BIN(time.tm_year);
1.1.1.2   root      110:        time.tm_mon--;
1.1       root      111:        startup_time = kernel_mktime(&time);
                    112: }
                    113: 
1.1.1.2   root      114: static long memory_end = 0;
                    115: static long buffer_memory_end = 0;
1.1.1.3   root      116: static long main_memory_start = 0;
1.1.1.4 ! root      117: static char term[32];
        !           118: 
        !           119: static char * argv_rc[] = { "/bin/sh", NULL };
        !           120: static char * envp_rc[] = { "HOME=/", NULL ,NULL };
        !           121: 
        !           122: static char * argv[] = { "-/bin/sh",NULL };
        !           123: static char * envp[] = { "HOME=/usr/root", NULL, NULL };
1.1.1.2   root      124: 
                    125: struct drive_info { char dummy[32]; } drive_info;
                    126: 
1.1       root      127: void main(void)                /* This really IS void, no error here. */
                    128: {                      /* The startup routine assumes (well, ...) this */
                    129: /*
                    130:  * Interrupts are still disabled. Do necessary setups, then
                    131:  * enable them
                    132:  */
1.1.1.2   root      133:        ROOT_DEV = ORIG_ROOT_DEV;
1.1.1.4 ! root      134:        SWAP_DEV = ORIG_SWAP_DEV;
        !           135:        sprintf(term, "TERM=con%dx%d", CON_COLS, CON_ROWS);
        !           136:        envp[1] = term; 
        !           137:        envp_rc[1] = term;
1.1.1.2   root      138:        drive_info = DRIVE_INFO;
                    139:        memory_end = (1<<20) + (EXT_MEM_K<<10);
                    140:        memory_end &= 0xfffff000;
                    141:        if (memory_end > 16*1024*1024)
                    142:                memory_end = 16*1024*1024;
1.1.1.3   root      143:        if (memory_end > 12*1024*1024) 
                    144:                buffer_memory_end = 4*1024*1024;
                    145:        else if (memory_end > 6*1024*1024)
1.1.1.2   root      146:                buffer_memory_end = 2*1024*1024;
                    147:        else
                    148:                buffer_memory_end = 1*1024*1024;
1.1.1.3   root      149:        main_memory_start = buffer_memory_end;
                    150: #ifdef RAMDISK
                    151:        main_memory_start += rd_init(main_memory_start, RAMDISK*1024);
                    152: #endif
                    153:        mem_init(main_memory_start,memory_end);
1.1       root      154:        trap_init();
1.1.1.2   root      155:        blk_dev_init();
                    156:        chr_dev_init();
                    157:        tty_init();
                    158:        time_init();
1.1       root      159:        sched_init();
1.1.1.2   root      160:        buffer_init(buffer_memory_end);
1.1       root      161:        hd_init();
1.1.1.2   root      162:        floppy_init();
1.1       root      163:        sti();
                    164:        move_to_user_mode();
                    165:        if (!fork()) {          /* we count on this going ok */
                    166:                init();
                    167:        }
                    168: /*
                    169:  *   NOTE!!   For any other task 'pause()' would mean we have to get a
                    170:  * signal to awaken, but task0 is the sole exception (see 'schedule()')
                    171:  * as task 0 gets activated at every idle moment (when no other tasks
                    172:  * can run). For task0 'pause()' just means we go check if some other
                    173:  * task can run, and if not we return here.
                    174:  */
1.1.1.4 ! root      175:        for(;;)
        !           176:                __asm__("int $0x80"::"a" (__NR_pause):"ax");
1.1       root      177: }
                    178: 
                    179: static int printf(const char *fmt, ...)
                    180: {
                    181:        va_list args;
                    182:        int i;
                    183: 
                    184:        va_start(args, fmt);
                    185:        write(1,printbuf,i=vsprintf(printbuf, fmt, args));
                    186:        va_end(args);
                    187:        return i;
                    188: }
                    189: 
                    190: void init(void)
                    191: {
1.1.1.3   root      192:        int pid,i;
1.1       root      193: 
1.1.1.2   root      194:        setup((void *) &drive_info);
1.1.1.4 ! root      195:        (void) open("/dev/tty1",O_RDWR,0);
1.1       root      196:        (void) dup(0);
                    197:        (void) dup(0);
                    198:        printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,
                    199:                NR_BUFFERS*BLOCK_SIZE);
1.1.1.3   root      200:        printf("Free mem: %d bytes\n\r",memory_end-main_memory_start);
                    201:        if (!(pid=fork())) {
                    202:                close(0);
                    203:                if (open("/etc/rc",O_RDONLY,0))
                    204:                        _exit(1);
                    205:                execve("/bin/sh",argv_rc,envp_rc);
                    206:                _exit(2);
                    207:        }
                    208:        if (pid>0)
                    209:                while (pid != wait(&i))
                    210:                        /* nothing */;
                    211:        while (1) {
                    212:                if ((pid=fork())<0) {
                    213:                        printf("Fork failed in init\r\n");
                    214:                        continue;
                    215:                }
                    216:                if (!pid) {
                    217:                        close(0);close(1);close(2);
                    218:                        setsid();
1.1.1.4 ! root      219:                        (void) open("/dev/tty1",O_RDWR,0);
1.1.1.3   root      220:                        (void) dup(0);
                    221:                        (void) dup(0);
                    222:                        _exit(execve("/bin/sh",argv,envp));
                    223:                }
                    224:                while (1)
                    225:                        if (pid == wait(&i))
                    226:                                break;
                    227:                printf("\n\rchild %d died with code %04x\n\r",pid,i);
                    228:                sync();
1.1       root      229:        }
                    230:        _exit(0);       /* NOTE! _exit, not exit() */
                    231: }

unix.superglobalmegacorp.com

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