📄 program-kernel-init-main-comment.html
字号:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="Author" content="Edward Fu">
<meta name="GENERATOR" content="Mozilla/4.05 [zh-CN] (X11; I; Linux 2.1.127 i686) [Netscape]">
<title>Freesoft Linux FAQ -- 内核原代码init/main的注释</title>
</head>
<body>
#define __LIBRARY__
<br>#include <unistd.h>
<br>#include <time.h>
<p>/*
<br>* we need this inline - forking from kernel space will result
<br>* in NO COPY ON WRITE (!!!), until an execve is executed. This
<br>* is no problem, but for the stack. This is handled by not letting
<br>* main() use the stack at all after fork(). Thus, no function
<br>* calls - which means inline code for fork too, as otherwise we
<br>* would use the stack upon exit from 'fork()'.
<br>*
<br>* Actually only pause and fork are needed inline, so that there
<br>* won't be any messing with the stack from main(), but we define
<br>* some others too.
<br>*/
<br>static inline _syscall0(int,fork) @@定义fork
<br>--sys_fork在unistd.h中定义syscall0
<br>static inline _syscall0(int,pause)
<br>static inline _syscall0(int,setup)
<br>static inline _syscall0(int,sync)
<p>#include <linux/tty.h>
<br>#include <linux/sched.h>
<br>#include <linux/head.h>
<br>#include <asm/system.h>
<br>#include <asm/io.h>
<p>#include <stddef.h>
<br>#include <stdarg.h>
<br>#include <unistd.h>
<br>#include <fcntl.h>
<br>#include <sys/types.h>
<p>#include <linux/fs.h>
<p>static char printbuf[1024];
<p>extern int vsprintf();
<br>extern void init(void);
<br>extern void hd_init(void);
<br>extern long kernel_mktime(struct tm * tm);
<br>extern long startup_time;
<p>/*
<br>* Yeah, yeah, it's ugly, but I cannot find how to do this correctly
<br>* and this seems to work. I anybody has more info on the real-time
<br>* clock I'd be interested. Most of this was trial and error, and some
<br>* bios-listing reading. Urghh.
<br>*/
<p>#define CMOS_READ(addr) ({ \
<br>outb_p(0x80|addr,0x70); \
<br>inb_p(0x71); \
<br>})
<p>#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
<p>static void time_init(void)
<br>{
<br>struct tm time;
<p>do {
<br> time.tm_sec = CMOS_READ(0);
<br> time.tm_min = CMOS_READ(2);
<br> time.tm_hour = CMOS_READ(4);
<br> time.tm_mday = CMOS_READ(7);
<br> time.tm_mon = CMOS_READ(8)-1;
<br> time.tm_year = CMOS_READ(9);
<br>} while (time.tm_sec != CMOS_READ(0));
<br>BCD_TO_BIN(time.tm_sec);
<br>BCD_TO_BIN(time.tm_min);
<br>BCD_TO_BIN(time.tm_hour);
<br>BCD_TO_BIN(time.tm_mday);
<br>BCD_TO_BIN(time.tm_mon);
<br>BCD_TO_BIN(time.tm_year);
<br>startup_time = kernel_mktime(&time);
<br>}
<p>void main(void) /* This really IS void, no error here. */
<br>{ /* The startup routine assumes (well, ...) this */
<br>/*
<br>* Interrupts are still disabled. Do necessary setups, then
<br>* enable them
<br>*/
<br>time_init();
<br>tty_init();
<br>trap_init();
<br>sched_init();
<br>buffer_init();
<br>hd_init();
<br>sti();
<br>move_to_user_mode(); @@切至用户模式???到哪去了,回来了!!!
<br>if (!fork()) { /* we count on this going ok */
<br> init(); @@fork在unistd.h有其宏扩展int 0x80
<br>
如何返回两次?应该说子进程如何激活?
<br>}
<br>/*
<br>* NOTE!! For any other task 'pause()' would
mean we have to get a
<br>* signal to awaken, but task0 is the sole exception (see 'schedule()')
<br>* as task 0 gets activated at every idle moment (when no other tasks
<br>* can run). For task0 'pause()' just means we go check if some other
<br>* task can run, and if not we return here.
<br>*/
<br>for(;;) pause();
<br> @@pause 同fork在unistd.h有其宏扩展int 0x80 然后调schedule()
<br>}
<p>static int printf(const char *fmt, ...)
<br>{
<br>va_list args;
<br>int i;
<p>va_start(args, fmt);
<br>write(1,printbuf,i=vsprintf(printbuf, fmt, args));
<br>va_end(args);
<br>return i;
<br>}
<p>static char * argv[] = { "-",NULL };
<br>static char * envp[] = { "HOME=/usr/root", NULL };
<p>void init(void)
<br>{
<br>int i,j;
<p>setup(); @@系统0号调用
<br>if (!fork())
<br> _exit(execve("/bin/update",NULL,NULL));
<br>(void) open("/dev/tty0",O_RDWR,0); @@打开控制台
<br>(void) dup(0); @@复制
<br>(void) dup(0);
<br>printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,
<br> NR_BUFFERS*BLOCK_SIZE);
<br>printf(" Ok.\n\r");
<br>if ((i=fork())<0)
<br> printf("Fork failed in init\r\n");
<br>else if (!i) { @@启动一root shell进程?
<br> close(0);close(1);close(2);
<br> setsid();
<br> (void) open("/dev/tty0",O_RDWR,0);
<br> (void) dup(0);
<br> (void) dup(0);
<br> _exit(execve("/bin/sh",argv,envp));
<br>}
<br>j=wait(&i);
<br>printf("child %d died with code %04x\n",j,i);
<br>sync();
<br>_exit(0); /* NOTE! _exit, not exit() */
<br>}
<br>
<br>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -