站内搜索

Linux 内核原代码 init/main 的注释

define __LIBRARY__
   #include
   #include
   /*
   * we need this inline - forking from kernel space will result
   * in NO COPY ON WRITE (!!!), until an execve is executed. This
   * is no problem, but for the stack. This is handled by not letting
   * main() use the stack at all after fork(). Thus, no function
   * calls - which means inline code for fork too, as otherwise we
   * would use the stack upon exit from 'fork()'.
   *
   * Actually only pause and fork are needed inline, so that there
   * won't be any messing with the stack from main(), but we define
   * some others too.
   */
   static inline _syscall0(int,fork) @@定义fork
   --sys_fork在unistd.h中定义syscall0
   static inline _syscall0(int,pause)
   static inline _syscall0(int,setup)
   static inline _syscall0(int,sync)

#include
   #include
   #include
   #include
   #include

#include
   #include
   #include
   #include
   #include

#include

static char printbuf[1024];

extern int vsprintf();
   extern void init(void);
   extern void hd_init(void);
   extern long kernel_mktime(struct tm * tm);
   extern long startup_time;

/*
   * 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.
   */

#define CMOS_READ(addr) ({
   outb_p(0x80|addr,0x70);
   inb_p(0x71);
   })

#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)

static void time_init(void)
   {
   struct tm time;

do {
   time.tm_sec = CMOS_READ(0);
   time.tm_min = CMOS_READ(2);
   time.tm_hour = CMOS_READ(4);
   time.tm_mday = CMOS_READ(7);
   time.tm_mon = CMOS_READ(8)-1;
   time.tm_year = CMOS_READ(9);
   } while (time.tm_sec != CMOS_READ(0));
   BCD_TO_BIN(time.tm_sec);
   BCD_TO_BIN(time.tm_min);
   BCD_TO_BIN(time.tm_hour);
   BCD_TO_BIN(time.tm_mday);
   BCD_TO_BIN(time.tm_mon);
   BCD_TO_BIN(time.tm_year);
   startup_time = kernel_mktime(&time);
   }

void main(void) /* This really IS void, no error here. */
   { /* The startup routine assumes (well, ...) this */
   /*
   * Interrupts are still disabled. Do necessary setups, then
   * enable them
   */
   time_init();
   tty_init();
   trap_init();
   sched_init();
   buffer_init();
   hd_init();
   sti();
   move_to_user_mode(); @@切至用户模式???到哪去了,回来了!!!
   if (!fork()) { /* we count on this going ok */
   init(); @@fork在unistd.h有其宏扩展int 0x80 
   如何返回两次?应该说子进程如何激活?
   }
   /*
   * 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();
   @@pause 同fork在unistd.h有其宏扩展int 0x80 然后调schedule()
   }

static int printf(const char *fmt, ...)
   {
   va_list args;
   int i;

va_start(args, fmt);
   write(1,printbuf,i=vsprintf(printbuf, fmt, args));
   va_end(args);
   return i;
   }

static char * argv[] = { "-",NULL };
   static char * envp[] = { "HOME=/usr/root", NULL };

void init(void)
   {
   int i,j;

setup(); @@系统0号调用
   if (!fork())
   _exit(execve("/bin/update",NULL,NULL));
   (void) open("/dev/tty0",O_RDWR,0); @@打开控制台
   (void) dup(0); @@复制
   (void) dup(0);
   printf("%d buffers = %d bytes buffer spacenr",NR_BUFFERS,
   NR_BUFFERS*BLOCK_SIZE);
   printf(" Ok.nr");
   if ((i=fork())<0)
   printf("Fork failed in initrn");
   else if (!i) { @@启动一root shell进程?
   close(0);close(1);close(2);
   setsid();
   (void) open("/dev/tty0",O_RDWR,0);
   (void) dup(0);
   (void) dup(0);
   _exit(execve("/bin/sh",argv,envp));
   }
   j=wait(&i);
   printf("child %d died with code %04xn",j,i);
   sync();
   _exit(0); /* NOTE! _exit, not exit() */
   }

 

  • 上一篇:Linux 内核模块和驱动程序的编写
  • 下一篇:Linux 内核原代码 boot.s 部分的注释