voidmain(void)/* This really IS void, no error here. */ { /* The startup routine assumes (well, ...) this */ /* * Interrupts are still disabled. Do necessary setups, then * enable them */ ROOT_DEV = ORIG_ROOT_DEV; drive_info = DRIVE_INFO; memory_end = (1<<20) + (EXT_MEM_K<<10); memory_end &= 0xfffff000; if (memory_end > 16*1024*1024) memory_end = 16*1024*1024; if (memory_end > 12*1024*1024) buffer_memory_end = 4*1024*1024; elseif (memory_end > 6*1024*1024) buffer_memory_end = 2*1024*1024; else buffer_memory_end = 1*1024*1024; main_memory_start = buffer_memory_end; #ifdef RAMDISK main_memory_start += rd_init(main_memory_start, RAMDISK*1024); #endif mem_init(main_memory_start,memory_end); trap_init(); blk_dev_init(); chr_dev_init(); tty_init(); time_init(); sched_init(); buffer_init(buffer_memory_end); hd_init(); floppy_init(); sti(); move_to_user_mode(); if (!fork()) { /* we count on this going ok */ init(); } /* * NOTE!! For any other task 'pause()' would mean we have to get a * signal to awaken, but task0 is the sole exception (see 'schedule()') * as task 0 gets activated at every idle moment (when no other tasks * can run). For task0 'pause()' just means we go check if some other * task can run, and if not we return here. */ for(;;) pause(); }
voidmain(void)/* This really IS void, no error here. */ { sti(); move_to_user_mode(); if (!fork()) { /*we count on this going ok*/ init(); } }
最后一部分是个死循环,当没有任何任务运行时,操作系统就会一直在这个死循环中。
1 2 3 4 5 6 7 8 9 10 11
voidmain(void)/* This really IS void, no error here. */ { /* * NOTE!! For any other task 'pause()' would mean we have to get a * signal to awaken, but task0 is the sole exception (see 'schedule()') * as task 0 gets activated at every idle moment (when no other tasks * can run). For task0 'pause()' just means we go check if some other * task can run, and if not we return here. */ for(;;) pause(); }
/* these are not to be changed without changing head.s etc */ #define LOW_MEM 0x100000 #define PAGING_MEMORY (15*1024*1024) #define PAGING_PAGES (PAGING_MEMORY>>12) #define MAP_NR(addr) (((addr)-LOW_MEM)>>12) #define USED 100
/* * NR_REQUEST is the number of entries in the request-queue. * NOTE that writes may use only the low 2/3 of these: reads * take precedence. * * 32 seems to be a reasonable number: enough to get some benefit * from the elevator-mechanism, but not so much as to lock a lot of * buffers when they are in the queue. 64 seems to be too many (easily * long pauses in reading when heavy writing/syncing is going on) */ #define NR_REQUEST 32 /* * Ok, this is an expanded form so that we can use the same * request for paging requests when that is implemented. In * paging, 'bh' is NULL, and 'waiting' is used to wait for * read/write completion. */ structrequest { int dev; /* -1 if no request */ int cmd; /* READ or WRITE */ int errors; unsignedlong sector; unsignedlong nr_sectors; char * buffer; structtask_struct * waiting; structbuffer_head * bh; structrequest * next; };
/* * The request-struct contains all necessary data * to load a nr of sectors into memory */ structrequestrequest[NR_REQUEST];
/* * void con_init(void); * * This routine initalizes console interrupts, and does nothing * else. If you want the screen to clear, call tty_write with * the appropriate escape-sequece. * * Reads the information preserved by setup.s to determine the current display * type and sets everything accordingly. */ voidcon_init(void) { registerunsignedchar a; char *display_desc = "????"; char *display_ptr;
/* Let the user known what kind of display driver we are using */ display_ptr = ((char *)video_mem_start) + video_size_row - 8; while (*display_desc) { *display_ptr++ = *display_desc++; display_ptr++; } /* Initialize the variables used for scrolling (mostly EGA/VGA) */ origin = video_mem_start; scr_end = video_mem_start + video_num_lines * video_size_row; top = 0; bottom = video_num_lines;
/* * Yeah, yeah, it's ugly, but I cannot find how to do this correctly * and this seems to work. I anybody has more info on the real-time * clock I'd be interested. Most of this was trial and error, and some * bios-listing reading. Urghh. */
longkernel_mktime(struct tm * tm) { long res; int year;
year = tm->tm_year - 70; /* magic offsets (y+1) needed to get leapyears right.*/ res = YEAR*year + DAY*((year+1)/4); res += month[tm->tm_mon]; /* and (y+2) here. If it wasn't a leap-year, we have to adjust */ if (tm->tm_mon>1 && ((year+2)%4)) res -= DAY; res += DAY*(tm->tm_mday-1); res += HOUR*tm->tm_hour; res += MINUTE*tm->tm_min; res += tm->tm_sec; return res; }
structtss_struct { long back_link; /* 16 high bits zero */ long esp0; long ss0; /* 16 high bits zero */ long esp1; long ss1; /* 16 high bits zero */ long esp2; long ss2; /* 16 high bits zero */ long cr3; long eip; long eflags; long eax,ecx,edx,ebx; long esp; long ebp; long esi; long edi; long es; /* 16 high bits zero */ long cs; /* 16 high bits zero */ long ss; /* 16 high bits zero */ long ds; /* 16 high bits zero */ long fs; /* 16 high bits zero */ long gs; /* 16 high bits zero */ long ldt; /* 16 high bits zero */ long trace_bitmap; /* bits: trace 0, bitmap 16-31 */ structi387_structi387; };
structtask_struct { /* these are hardcoded - don't touch */ long state; /* -1 unrunnable, 0 runnable, >0 stopped */ long counter; long priority; long signal; structsigactionsigaction[32]; long blocked; /* bitmap of masked signals */ /* various fields */ int exit_code; unsignedlong start_code,end_code,end_data,brk,start_stack; long pid,father,pgrp,session,leader; unsignedshort uid,euid,suid; unsignedshort gid,egid,sgid; long alarm; long utime,stime,cutime,cstime,start_time; unsignedshort used_math; /* file system info */ int tty; /* -1 if no tty, so it must be signed */ unsignedshort umask; structm_inode * pwd; structm_inode * root; structm_inode * executable; unsignedlong close_on_exec; structfile * filp[NR_OPEN]; /* ldt for this task 0 - zero 1 - cs 2 - ds&ss */ structdesc_structldt[3]; /* tss for this task */ structtss_structtss; };