接下来main将执行进入保护模式前最重要的一个步骤,设置视频模式,调用set_video()函数,来自linux/arch/x86/boot/video.c:
315void set_video(void) 316{ 317 u16 mode = boot_params.hdr.vid_mode; 318 319 RESET_HEAP(); 320 321 store_mode_params(); 322 save_screen(); 323 probe_cards(0); 324 325 for (;;) { 326 if (mode == ASK_VGA) 327 mode = mode_menu(); 328 329 if (!set_mode(mode)) 330 break; 331 332 printf("Undefined video mode number: %x/n", mode); 333 mode = ASK_VGA; 334 } 335 boot_params.hdr.vid_mode = mode; 336 vesa_store_edid(); 337 store_mode_params(); 338 339 if (do_restore) 340 restore_screen(); 341} |
317行,根据传过来的hdr参数得到视频模式,存储到内部变量mode中。我们看到header.S中的vid_mode值是SVGA_MODE。这时候要从新设置一下堆的位置,把它设定到_end处。
为什么要调整一下堆的位置,我也搞不清楚,也许是跟视频配置有着千丝万缕的关系吧,有兴趣的同志可以去研究一下。随后,调用store_mode_params()来设置boot_params的screen_info字段:
53/* 54 * Store the video mode parameters for later usage by the kernel. 55 * This is done by asking the BIOS except for the rows/columns 56 * parameters in the default 80x25 mode -- these are set directly, 57 * because some very obscure BIOSes supply insane values. 58 */ 59static void store_mode_params(void) 60{ 61 u16 font_size; 62 int x, y; 63 64 /* For graphics mode, it is up to the mode-setting driver 65 (currently only video-vesa.c) to store the parameters */ 66 if (graphic_mode) 67 return; 68 69 store_cursor_position(); 70 store_video_mode(); 71 72 if (boot_params.screen_info.orig_video_mode == 0x07) { 73 /* MDA, HGC, or VGA in monochrome mode */ 74 video_segment = 0xb000; 75 } else { 76 /* CGA, EGA, VGA and so forth */ 77 video_segment = 0xb800; 78 } 79 80 set_fs(0); 81 font_size = rdfs16(0x485); /* Font size, BIOS area */ 82 boot_params.screen_info.orig_video_points = font_size; 83 84 x = rdfs16(0x44a); 85 y = (adap |