/* * This is set up by the setup-routine at boot-time */ #define EXT_MEM_K (*(unsigned short *)0x90002) /*扩展内存数,单位为KB*/ #define DRIVE_INFO (*(struct drive_info *)0x90080) #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
voidmain(void)/* This really IS void, no error here. */ { /* The startup routine assumes (well, ...) this */ /*hexhe * 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) { /* ...... */ 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(); }
内存初始化
1 2 3 4 5 6 7 8 9 10 11 12 13
voidmem_init(long start_mem, long end_mem) { int i;
HIGH_MEMORY = end_mem; for (i=0 ; i<PAGING_PAGES ; i++) mem_map[i] = USED; i = MAP_NR(start_mem); end_mem -= start_mem; end_mem >>= 12; while (end_mem-->0) mem_map[i++]=0; }
/* * 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; };
如果我们要访问硬盘的数据,我们需要告诉CPU我们访问硬盘的起始扇区和扇区数,是写入还是读取数据。
每一次访问都是一次请求。通过链表来维护访问。
TTY初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#define ORIG_X (*(unsigned char *)0x90000) /*光标位置*/ #define ORIG_Y (*(unsigned char *)0x90001) #define ORIG_VIDEO_PAGE (*(unsigned short *)0x90004) /*当前视频页面*/ #define ORIG_VIDEO_MODE ((*(unsigned short *)0x90006) & 0xff) /*显示模式*/ #define ORIG_VIDEO_COLS (((*(unsigned short *)0x90006) & 0xff00) >> 8) #define ORIG_VIDEO_LINES (25) #define ORIG_VIDEO_EGA_AX (*(unsigned short *)0x90008) #define ORIG_VIDEO_EGA_BX (*(unsigned short *)0x9000a) #define ORIG_VIDEO_EGA_CX (*(unsigned short *)0x9000c)
#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ #define VIDEO_TYPE_CGA 0x11 /* CGA Display */ #define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */ #define VIDEO_TYPE_EGAC 0x21 /* EGA/VGA in Color Mode */
voidtty_init(void) { rs_init(); con_init(); } voidrs_init(void) { set_intr_gate(0x24,rs1_interrupt); set_intr_gate(0x23,rs2_interrupt); init(tty_table[1].read_q.data); init(tty_table[2].read_q.data); outb(inb_p(0x21)&0xE7,0x21); } /* * 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;