📄 1127.html
字号:
sti();接受硬件中断<br>
<br>
kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);<br>
current->need_resched = 1; need_resched标志增加,调用schedule(调度里面会详细说明)<br>
cpu_idle(NULL) 进入idle循环以消耗空闲的cpu时间片<br>
<br>
已经基本完成内核初始化工作,已经把需要完成的少量责任传递给了init,所身于地工作不过是进入idle循环以消耗空闲的cpu时间片。所以在这里调用了cpu_idle(NULL),它从不返回,所以当有实际工作好处理时,该函数就会被抢占。<br>
<br>
parse_options函数:<br>
static void __init parse_options(char *line)/*参数收集在一条长命令行中,内核被赋给指向该命令行头部的指针*/<br>
{<br>
char *next;<br>
char *quote;<br>
int args, envs;<br>
<br>
if (!*line)<br>
return;<br>
args = 0;<br>
envs = 1;/* TERM is set to 'linux' by default */<br>
next = line;<br>
while ((line = next) != NULL) {<br>
<br>
quote = strchr(line,'"');<br>
next = strchr(line, ' ');<br>
while (next != NULL && quote != NULL && quote < next) {<br>
<br>
next = strchr(quote+1, '"');<br>
if (next != NULL) {<br>
quote = strchr(next+1, '"');<br>
next = strchr(next+1, ' ');<br>
}<br>
}<br>
if (next != NULL)<br>
*next++ = 0;<br>
/*<br>
* check for kernel options first..<br>
*/<br>
if (!strcmp(line,"ro")) {<br>
root_mountflags |= MS_RDONLY;<br>
continue;<br>
}<br>
if (!strcmp(line,"rw")) {<br>
root_mountflags &= ~MS_RDONLY;<br>
continue;<br>
}<br>
if (!strcmp(line,"debug")) {<br>
console_loglevel = 10;<br>
continue;<br>
}<br>
if (!strcmp(line,"quiet")) {<br>
console_loglevel = 4;<br>
continue;<br>
}<br>
if (!strncmp(line,"init=",5)) {<br>
line += 5;<br>
execute_command = line;<br>
args = 0;<br>
continue;<br>
}<br>
if (checksetup(line))<br>
continue;<br>
<br>
if (strchr(line,'=')) {<br>
if (envs >= MAX_INIT_ENVS)<br>
break;<br>
envp_init[++envs] = line;<br>
} else {<br>
if (args >= MAX_INIT_ARGS)<br>
break;<br>
argv_init[++args] = line;<br>
}<br>
}<br>
argv_init[args+1] = NULL;<br>
envp_init[envs+1] = NULL;<br>
}<br>
<br>
<br>
<br>
[这个贴子最后由e4gle在 2002/08/25 06:30pm 编辑]<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// setup.txt<br>
// Copyright(C) 2001, Feiyun Wang<br>
////////////////////////////////////////////////////////////////////<br>
// analysis on linux/arch/i386/boot/setup.S (for linux 2.2.17)<br>
////////////////////////////////////////////////////////////////////<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// export the margin tags for .text, .data and .bss<br>
{<br>
.text<br>
begtext:<br>
<br>
.data<br>
begdata:<br>
<br>
.bss<br>
begbss:<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
.text<br>
start()<br>
SYSSEG = 0x1000<br>
SETUPSEG = 0x9020<br>
modelist = end of .text:<br>
{<br>
// if loaded by bootsect.S,<br>
// you can assume CS=SETUPSEG (=0x9020), otherwise...<br>
goto start_of_setup();<br>
<br>
/*<br>
http://lxr.linux.no/source/Documentation/i386/boot.txt<br>
Offset/Size Proto Name Meaning<br>
01F1/1 ALL setup_sects The size of the setup in sectors<br>
01F2/2 ALL root_flags If set, the root is mounted readonly<br>
01F4/2 ALL syssize DO NOT USE - for bootsect.S use only<br>
01F6/2 ALL swap_dev DO NOT USE - obsolete<br>
01F8/2 ALL ram_size DO NOT USE - for bootsect.S use only<br>
01FA/2 ALL vid_mode Video mode control<br>
01FC/2 ALL root_dev Default root device number<br>
01FE/2 ALL boot_flag 0xAA55 magic number<br>
0200/2 2.00+ jump Jump instruction<br>
0202/4 2.00+ header Magic signature "HdrS"<br>
0206/2 2.00+ version Boot protocol version supported<br>
0208/4 2.00+ realmode_swtch Boot loader hook<br>
020C/4 2.00+ start_sys_seg Points to kernel version string<br>
0210/1 2.00+ type_of_loader Boot loader identifier<br>
0211/1 2.00+ loadflags Boot protocol option flags<br>
0212/2 2.00+ setup_move_size Move to high memory size (used with hooks)<br>
0214/4 2.00+ code32_start Boot loader hook<br>
0218/4 2.00+ ramdisk_image initrd load address (set by boot loader)<br>
021C/4 2.00+ ramdisk_size initrd size (set by boot loader)<br>
0220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only<br>
0224/4 2.01+ heap_end_ptr Free memory after setup end<br>
0226/2 N/A pad1 Unused<br>
0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line<br>
*/<br>
.ascii "HdrS"<br>
.word 0x0201<br>
realmode_swtch: // boot loader hook<br>
.word 0, 0<br>
start_sys_seg: // pointer to kernel version string<br>
.word SYSSEG<br>
.word kernel_version<br>
type_of_loader:<br>
.byte 0<br>
loadflags:<br>
#ifndef __BIG_KERNEL__<br>
.byte 0x00<br>
#else<br>
.byte LOADED_HIGH = 1<br>
#endif<br>
setup_move_size:<br>
.word 0x8000<br>
code32_start: // boot loader hook<br>
#ifndef __BIG_KERNEL__<br>
.long 0x1000<br>
#else<br>
.long 0x100000<br>
#endif<br>
ramdisk_image: // initrd load address (set by boot loader)<br>
.long 0<br>
ramdisk_size: // initrd size (set by boot loader)<br>
.long 0<br>
bootsect_kludge: // DO NOT USE - for bootsect.S use only<br>
.word bootsect_helper(), SETUPSEG<br>
heap_end_ptr: // free memory after setup end<br>
.word modelist+1024<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// check signature to see if all code loaded<br>
start_of_setup()<br>
{<br>
// get disk type, bootlin depends on this<br>
// http://www.ctyme.com/intr/rb-0639.htm<br>
int13h/AH=15h(AL=0, DL=0x81);<br>
<br>
#ifdef SAFE_RESET_DISK_CONTROLLER<br>
int13h/AH=0(AL=0, DL=0x80); // reset hd0<br>
#endif<br>
<br>
// check signature at the end of setup code<br>
if (setup_sig1!=SIG1 || setup_sig2!=SIG2) {<br>
// since size of setup may > 4 sectors,<br>
// the rest code may be loaded at SYSSEG<br>
goto bad_sig;<br>
}<br>
goto goodsig1;<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// some small functions<br>
prtstr() { /* ... print ASCIIz string at DS:SI */}<br>
prtsp2() { /* ... print double space */ }<br>
prtspc() { /* ... print single space */ }<br>
prtchr() { /* ... print ASCII AL */ }<br>
beep() { /* ... beep */ }<br>
<br>
////////////////////////////////////////////////////////////////////<br>
goodsig1() { goto goodsig; } // making near jumps<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// move rest setup code from SYSSEG:0 to CS:0800<br>
// TODO: it won't work if image loaded at 0x100000?<br>
bad_sig()<br>
DELTA_INITSEG = 0x0020 (= SETUPSEG - INITSEG)<br>
SYSSEG = 0x1000<br>
{<br>
BX = (CS-DELTA_INITSEG):[497]; // i.e. setup_sects<br>
// first 4 sectors have been loaded<br>
CX = (BX - 4) << 8; // rest code in words<br>
start_sys_seg = (CX >> 3) + SYSSEG; // real system code start<br>
<br>
move SYSSEG:0 to CS:0800 (CX*2 bytes);<br>
<br>
if (setup_sig1!=SIG1 || setup_sig2!=SIG2) {<br>
prtstr("No setup signature found ...");<br>
halt;<br>
}<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// check if loader compatible with image<br>
good_sig()<br>
LOADHIGH = 1<br>
{<br>
if ((loadflags & LOADHIGH) && (!type_of_loader)) {<br>
// Nope, old loader want to load big kernel<br>
prtstr("Wrong loader: giving up.");<br>
halt;<br>
}<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// get memory size<br>
// set the keyboard repeat rate to max<br>
// check video adapter<br>
// get hd0 & hd1 data<br>
// check for Micro Channel (MCA) bus<br>
// check for PS/2 pointing device<br>
// check for APM BIOS<br>
// move code to INITSEG/SETUPSEG<br>
// load IDT and GDT<br>
// enable and test A20<br>
// reset coprocessor<br>
// reprogram the interrupts<br>
// switch to protected mode<br>
// goto KERNEL<br>
loader_ok()<br>
SETUPSET = 0x9020<br>
INITSEG = 0x9000<br>
DELTA_INITSEG = 0x20<br>
{<br>
// DS = CS - DELTA_INITSEG when entering this function<br>
<br>
// get memory size<br>
#ifndef STANDARD_MEMORY_BIOS_CALL<br>
(double word)DS:[0x1E0] = 0;<br>
try {<br>
// get memory size for >64M configurations<br>
// http://www.ctyme.com/intr/rb-1739.htm<br>
int15h/AX=E801h;<br>
// AX = extended memory between 1M and 16M, in KB<br>
// BX = extended memory above 16M, in 64K blocks<br>
(double word)DS:[0x1E0] = ((EBX & 0xFFFF) << 6)<br>
+ (EAX & 0xFFFF);<br>
}<br>
#else<br>
(double word)DS:[0x1E0] = 0;<br>
#endif<br>
<br>
// get extended memory size<br>
// http://www.ctyme.com/intr/rb-1529.htm<br>
int15h/AH=88h;<br>
DS:[2] = AX; // KB of contiguous memory from 100000h<br>
<br>
// set the keyboard repeat rate to max<br>
// http://www.ctyme.com/intr/rb-1757.htm<br>
int16h/AX=0305h(BX=0);<br>
<br>
// check video adapter and its parameters, see video.S<br>
video();<br>
<br>
// get hd0 & hd1 data<br>
// http://www.ctyme.com/intr/rb-6135.htm<br>
// http://www.ctyme.com/intr/rb-6184.htm<br>
// pointers in 0:0104 & 0:0118 respectively<br>
move hd0 data to CS-DELTA_INITSEG:0080 (16 bytes);<br>
move hd1 data to CS-DELTA_INITSEG:0090 (16 bytes);<br>
<br>
// get disk type, check if hd1 exists<br>
// http://www.ctyme.com/intr/rb-0639.htm<br>
int13h/AH=15h(AL=0, DL=0x81);<br>
if (failed || AH!=03h) { // AH=03h if is a hard disk<br>
clear CS-DELTA_INITSEG:0090 (16 bytes);<br>
}<br>
<br>
// check for Micro Channel (MCA) bus<br>
DS:[0xA0] = 0; // set table length to 0<br>
try {<br>
// get system configuration<br>
// http://www.ctyme.com/intr/rb-1594.htm<br>
int15h/AH=C0h; // ES:BX = ROM configuration table<br>
move ROM configuration table to CS-DELTA_INITSEG:00A0;<br>
// first 16 bytes only<br>
}<br>
<br>
// check PS/2 pointing device<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -