⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stage2.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  GRUB  --  GRand Unified Bootloader *  Copyright (C) 2000,2001,2002,2004  Free Software Foundation, Inc. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <shared.h>#include <term.h>grub_jmp_buf restart_env;#if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)# if defined(PRESET_MENU_STRING)static const char *preset_menu = PRESET_MENU_STRING;# elif defined(SUPPORT_DISKLESS)/* Execute the command "bootp" automatically.  */static const char *preset_menu = "bootp\n";# endif /* SUPPORT_DISKLESS */static int preset_menu_offset;static intopen_preset_menu (void){#ifdef GRUB_UTIL  /* Unless the user explicitly requests to use the preset menu,     always opening the preset menu fails in the grub shell.  */  if (! use_preset_menu)    return 0;#endif /* GRUB_UTIL */    preset_menu_offset = 0;  return preset_menu != 0;}static intread_from_preset_menu (char *buf, int maxlen){  int len = grub_strlen (preset_menu + preset_menu_offset);  if (len > maxlen)    len = maxlen;  grub_memmove (buf, preset_menu + preset_menu_offset, len);  preset_menu_offset += len;  return len;}static voidclose_preset_menu (void){  /* Disable the preset menu.  */  preset_menu = 0;}#else /* ! PRESET_MENU_STRING && ! SUPPORT_DISKLESS */#define open_preset_menu()	0#define read_from_preset_menu(buf, maxlen)	0#define close_preset_menu()#endif /* ! PRESET_MENU_STRING && ! SUPPORT_DISKLESS */static char *get_entry (char *list, int num, int nested){  int i;  for (i = 0; i < num; i++)    {      do	{	  while (*(list++));	}      while (nested && *(list++));    }  return list;}/* Print an entry in a line of the menu box.  */static voidprint_entry (int y, int highlight, char *entry){  int x;  if (current_term->setcolorstate)    current_term->setcolorstate (COLOR_STATE_NORMAL);    if (highlight && current_term->setcolorstate)    current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);  gotoxy (2, y);  grub_putchar (' ');  for (x = 3; x < 75; x++)    {      if (*entry && x <= 72)	{	  if (x == 72)	    grub_putchar (DISP_RIGHT);	  else	    grub_putchar (*entry++);	}      else	grub_putchar (' ');    }  gotoxy (74, y);  if (current_term->setcolorstate)    current_term->setcolorstate (COLOR_STATE_STANDARD);}/* Print entries in the menu box.  */static voidprint_entries (int y, int size, int first, int entryno, char *menu_entries){  int i;    gotoxy (77, y + 1);  if (first)    grub_putchar (DISP_UP);  else    grub_putchar (' ');  menu_entries = get_entry (menu_entries, first, 0);  for (i = 0; i < size; i++)    {      print_entry (y + i + 1, entryno == i, menu_entries);      while (*menu_entries)	menu_entries++;      if (*(menu_entries - 1))	menu_entries++;    }  gotoxy (77, y + size);  if (*menu_entries)    grub_putchar (DISP_DOWN);  else    grub_putchar (' ');  gotoxy (74, y + entryno + 1);}static voidprint_entries_raw (int size, int first, char *menu_entries){  int i;#define LINE_LENGTH 67  for (i = 0; i < LINE_LENGTH; i++)    grub_putchar ('-');  grub_putchar ('\n');  for (i = first; i < size; i++)    {      /* grub's printf can't %02d so ... */      if (i < 10)	grub_putchar (' ');      grub_printf ("%d: %s\n", i, get_entry (menu_entries, i, 0));    }  for (i = 0; i < LINE_LENGTH; i++)    grub_putchar ('-');  grub_putchar ('\n');#undef LINE_LENGTH}static voidprint_border (int y, int size){  int i;  if (current_term->setcolorstate)    current_term->setcolorstate (COLOR_STATE_NORMAL);    gotoxy (1, y);  grub_putchar (DISP_UL);  for (i = 0; i < 73; i++)    grub_putchar (DISP_HORIZ);  grub_putchar (DISP_UR);  i = 1;  while (1)    {      gotoxy (1, y + i);      if (i > size)	break;            grub_putchar (DISP_VERT);      gotoxy (75, y + i);      grub_putchar (DISP_VERT);      i++;    }  grub_putchar (DISP_LL);  for (i = 0; i < 73; i++)    grub_putchar (DISP_HORIZ);  grub_putchar (DISP_LR);  if (current_term->setcolorstate)    current_term->setcolorstate (COLOR_STATE_STANDARD);}static voidrun_menu (char *menu_entries, char *config_entries, int num_entries,	  char *heap, int entryno){  int c, time1, time2 = -1, first_entry = 0;  char *cur_entry = 0;  /*   *  Main loop for menu UI.   */restart:  /* Dumb terminal always use all entries for display      invariant for TERM_DUMB: first_entry == 0  */  if (! (current_term->flags & TERM_DUMB))    {      while (entryno > 11)	{	  first_entry++;	  entryno--;	}    }  /* If the timeout was expired or wasn't set, force to show the menu     interface. */  if (grub_timeout < 0)    show_menu = 1;    /* If SHOW_MENU is false, don't display the menu until ESC is pressed.  */  if (! show_menu)    {      /* Get current time.  */      while ((time1 = getrtsecs ()) == 0xFF)	;      while (1)	{	  /* Check if ESC is pressed.  */	  if (checkkey () != -1 && ASCII_CHAR (getkey ()) == '\e')	    {	      grub_timeout = -1;	      show_menu = 1;	      break;	    }	  /* If GRUB_TIMEOUT is expired, boot the default entry.  */	  if (grub_timeout >=0	      && (time1 = getrtsecs ()) != time2	      && time1 != 0xFF)	    {	      if (grub_timeout <= 0)		{		  grub_timeout = -1;		  goto boot_entry;		}	      	      time2 = time1;	      grub_timeout--;	      	      /* Print a message.  */	      grub_printf ("\rPress `ESC' to enter the menu... %d   ",			   grub_timeout);	    }	}    }  /* Only display the menu if the user wants to see it. */  if (show_menu)    {      init_page ();      setcursor (0);      if (current_term->flags & TERM_DUMB)	print_entries_raw (num_entries, first_entry, menu_entries);      else	print_border (3, 12);      grub_printf ("\n\      Use the %c and %c keys to select which entry is highlighted.\n",		   DISP_UP, DISP_DOWN);            if (! auth && password)	{	  printf ("\      Press enter to boot the selected OS or \'p\' to enter a\n\      password to unlock the next set of features.");	}      else	{	  if (config_entries)	    printf ("\      Press enter to boot the selected OS, \'e\' to edit the\n\      commands before booting, or \'c\' for a command-line.");	  else	    printf ("\      Press \'b\' to boot, \'e\' to edit the selected command in the\n\      boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\      after (\'O\' for before) the selected line, \'d\' to remove the\n\      selected line, or escape to go back to the main menu.");	}      if (current_term->flags & TERM_DUMB)	grub_printf ("\n\nThe selected entry is %d ", entryno);      else	print_entries (3, 12, first_entry, entryno, menu_entries);    }  /* XX using RT clock now, need to initialize value */  while ((time1 = getrtsecs()) == 0xFF);  while (1)    {      /* Initialize to NULL just in case...  */      cur_entry = NULL;      if (grub_timeout >= 0 && (time1 = getrtsecs()) != time2 && time1 != 0xFF)	{	  if (grub_timeout <= 0)	    {	      grub_timeout = -1;	      break;	    }	  /* else not booting yet! */	  time2 = time1;	  if (current_term->flags & TERM_DUMB)	      grub_printf ("\r    Entry %d will be booted automatically in %d seconds.   ", 			   entryno, grub_timeout);	  else	    {	      gotoxy (3, 22);	      grub_printf ("The highlighted entry will be booted automatically in %d seconds.    ",			   grub_timeout);	      gotoxy (74, 4 + entryno);	  }	  	  grub_timeout--;	}      /* Check for a keypress, however if TIMEOUT has been expired	 (GRUB_TIMEOUT == -1) relax in GETKEY even if no key has been	 pressed.  	 This avoids polling (relevant in the grub-shell and later on	 in grub if interrupt driven I/O is done).  */      if (checkkey () >= 0 || grub_timeout < 0)	{	  /* Key was pressed, show which entry is selected before GETKEY,	     since we're comming in here also on GRUB_TIMEOUT == -1 and	     hang in GETKEY */	  if (current_term->flags & TERM_DUMB)	    grub_printf ("\r    Highlighted entry is %d: ", entryno);	  c = ASCII_CHAR (getkey ());	  if (grub_timeout >= 0)	    {	      if (current_term->flags & TERM_DUMB)		grub_putchar ('\r');	      else		gotoxy (3, 22);	      printf ("                                                                    ");	      grub_timeout = -1;	      fallback_entry = -1;	      if (! (current_term->flags & TERM_DUMB))		gotoxy (74, 4 + entryno);	    }	  /* We told them above (at least in SUPPORT_SERIAL) to use	     '^' or 'v' so accept these keys.  */	  if (c == 16 || c == '^')	    {	      if (current_term->flags & TERM_DUMB)		{		  if (entryno > 0)		    entryno--;		}	      else		{		  if (entryno > 0)		    {		      print_entry (4 + entryno, 0,				   get_entry (menu_entries,					      first_entry + entryno,					      0));		      entryno--;		      print_entry (4 + entryno, 1,				   get_entry (menu_entries,					      first_entry + entryno,					      0));		    }		  else if (first_entry > 0)		    {		      first_entry--;		      print_entries (3, 12, first_entry, entryno,				     menu_entries);		    }		}	    }	  else if ((c == 14 || c == 'v')		   && first_entry + entryno + 1 < num_entries)	    {	      if (current_term->flags & TERM_DUMB)		entryno++;	      else		{		  if (entryno < 11)		    {		      print_entry (4 + entryno, 0,				   get_entry (menu_entries,					      first_entry + entryno,					      0));		      entryno++;		      print_entry (4 + entryno, 1,				   get_entry (menu_entries,					      first_entry + entryno,					      0));		  }		else if (num_entries > 12 + first_entry)		  {		    first_entry++;		    print_entries (3, 12, first_entry, entryno, menu_entries);		  }		}	    }	  else if (c == 7)	    {	      /* Page Up */	      first_entry -= 12;	      if (first_entry < 0)		{		  entryno += first_entry;		  first_entry = 0;		  if (entryno < 0)		    entryno = 0;		}	      print_entries (3, 12, first_entry, entryno, menu_entries);	    }	  else if (c == 3)	    {	      /* Page Down */	      first_entry += 12;	      if (first_entry + entryno + 1 >= num_entries)		{		  first_entry = num_entries - 12;		  if (first_entry < 0)		    first_entry = 0;		  entryno = num_entries - first_entry - 1;		}	      print_entries (3, 12, first_entry, entryno, menu_entries);	    }	  if (config_entries)	    {	      if ((c == '\n') || (c == '\r') || (c == 6))		break;	    }	  else	    {	      if ((c == 'd') || (c == 'o') || (c == 'O'))		{		  if (! (current_term->flags & TERM_DUMB))		    print_entry (4 + entryno, 0,				 get_entry (menu_entries,					    first_entry + entryno,					    0));		  /* insert after is almost exactly like insert before */		  if (c == 'o')		    {		      /* But `o' differs from `O', since it may causes			 the menu screen to scroll up.  */		      if (entryno < 11 || (current_term->flags & TERM_DUMB))			entryno++;		      else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -