Tag/tag.png

Candidate for Deletion
This article may not be appropriate for this wiki, and may be deleted. More info...

介绍

BURG是一个基于GRUB2的启动管理器。

使用二进制包安装

ubuntu karmic的用户可以直接使用PPA里面的二进制包来安装。首先,在/etc/apt/sources.list文件里加上源:

deb http://ppa.launchpad.net/bean123ch/burg/ubuntu karmic main 
deb-src http://ppa.launchpad.net/bean123ch/burg/ubuntu karmic main

用以下命令下载并安装:

sudo apt-get update
sudo apt-get install grub-pc

你还需要把新的启动管理器安装到MBR或者启动扇区里,例如:

sudo update-grub
sudo grub-install "(hd0)"

使用源代码里安装

依赖软件

在编译BURG前,系统里需要有以下的软件:

gcc gcc-multilib (用于在i386系统里编译x86_64目标,或者在x86_64系统里编译i386目标) bison autoconf GNU make ruby

Debian/Ubuntu

用apt-get可以方便地安装所需软件:

sudo apt-get install gcc gcc-multilib bison autoconf make ruby

OSX

需要安装Xcode。我在10.4 Tiger (Xcode 2.5),10.5 Leopard (Xcode 3.0)和10.6 Snow Leopard (Xcode 3.2)上成功地编译通过。

对于10.4 Tiger来所,系统自带的bison和autoconf版本太低,你需要安装macport或者fink里的版本。

Windows

在Windows下需要mingw或者cygwin。ruby没有包含在mingw里,你需要另行安装。

获得源码

需要使用bazaar来下载代码,第一次导入:

bzr branch lp:burg

以后更新可以在burg目录里运行:

bzr pull

在下载/更新代码后,需要运行以下的命令来生成makefile:

./autogen.sh

== 编译和安装(pc模式)==

在burg工作目录里运行以下命令即可编译:

mkdir bin_pc
cd bin_pc
../configure --with-platform=pc --prefix=${HOME}/burg_pc
make
make install

这里,我使用了子目录bin_pc来放置生成的目标文件,这可以避免在工作目录下生成大量文件。而且,安装时使用用户主目录下的 burg_pc,这可以避免可系统自带的GRUB2发生冲突。

然后,和二进制安装一样,需要安装到MBR:

以下命令只能在Linux下运行,在OSX/Windows下是不适用的

cd ${HOME}/burg_pc/sbin
sudo ./update-grub
sudo ./grub-install "(hd0)"

== 编译和安装(efi模式)==

编译和pc模式很相近,只需要修改--with-platform和--target参数就行了。

32位EFI:

mkdir bin_efi32
cd bin_efi32
../configure --with-platform=efi --target=i386 --prefix=${HOME}/burg_efi32
make
make install

64位EFI:

mkdir bin_efi64
cd bin_efi64
../configure --with-platform=efi --target=x86_64 --prefix=${HOME}/burg_efi64
make
make install

然后,需要用grub-mkimage命令来生成EFI启动映像,例如:

cd ${HOME}/burg_efi64/bin
./grub-mkimage -o grub64.efi minicmd part_gpt part_msdos part_apple fat ext2 hfsplus hfs ntfs reiserfs xfs iso9660 udf ls search loopback linux chain reboot halt appleldr help configfile hexdump loadbios memrw fixvideo crc sh video efi_fb gfxterm font png loadcfg normal coreui gfxrgn txtrgn nmenu emenu

把grub64.efi拷贝到rEFIt能找到的目录,并且在同样的目录下建立一个grub.cfg文件,例如:

menuentry "Boot OSX" {
  search -s -f /usr/standalone/i386/boot.efi
  chainloader /usr/standalone/i386/boot.efi
}

menuentry "Boot MBR" {
  appleloader HD
}
menuentry "Boot CD" {
  appleloader CD
}

新菜单系统

用法

要启动新菜单系统,首先需要在以下地址下载资源文件:

http://grub4dos.sourceforge.net/themes.tar.bz2

并解压到根目录:

sudo tar -xjf themes.tar.bz2 -C /

解压后相关的文件可以在/boot/grub/themes/里找到。

在pc模式下启动新图形界面,首先需要编辑/etc/default/grub文件,找到GRUB_TERMINAL所在的一行并把前面的#去掉,使得这句话生效:

GRUB_TERMINAL=console

这一步非常重要。没有GRUB_TERMINAL=console的话,grub会启动gfxterm,这个和新菜单是不兼容的,这会导致启动时出现黑屏!!

然后,编辑/etc/grub.d/40_custom,把以下内容加进去:

set gfxmode="640x480"
set gfxfont="Unifont Regular 16"
loadfont /boot/grub/themes/fonts/unifont.pf2
loadfont /boot/grub/themes/fonts/aqui.pf2
loadfont /boot/grub/themes/fonts/edges.pf2
loadfont /boot/grub/themes/fonts/lime.pf2
loadfont /boot/grub/themes/fonts/7x13B.pf2
loadfont /boot/grub/themes/fonts/smoothansi.pf2
loadfont /boot/grub/themes/fonts/Helvetica-Bold-14.pf2
insmod vbe
insmod png
insmod coreui
load_config /boot/grub/themes/proto/theme.txt

最后一句设置的是风格。目前有三种可以选择:

proto

load_config /boot/grub/themes/proto/theme.txt

ubuntu

load_config /boot/grub/themes/ubuntu/theme.txt

winter

load_config /boot/grub/themes/winter/theme.txt

还有一个示范的风格/boot/grub/themes/default.txt。这个界面比较原始,不过里面包含了基本的元素,可以作为定制风格的出发点。

最后,需要生成grub.cfg文件:

sudo update-grub

如果修改了配置,需要重新运行update-grub来更新grub.cfg。

---

在EFI模式下,grub.cfg一般都是手动编辑的。在grub.cfg的最后加上以下内容即可:

set gfxmode="0x0"
set gfxfont="Unifont Regular 16"
loadfont /boot/grub/themes/fonts/unifont.pf2
loadfont /boot/grub/themes/fonts/aqui.pf2
loadfont /boot/grub/themes/fonts/edges.pf2
loadfont /boot/grub/themes/fonts/lime.pf2
loadfont /boot/grub/themes/fonts/7x13B.pf2
loadfont /boot/grub/themes/fonts/smoothansi.pf2
loadfont /boot/grub/themes/fonts/Helvetica-Bold-14.pf2
load_config /boot/grub/themes/proto/theme.txt

风格文件里定义了以下的快捷键:

  • e - 编辑当前菜单项对应的命令
  • t - 编辑当前菜单项的标题
  • c - 打开一个终端窗口
  • 2 - 打开两个终端窗口
  • F5 - 映射为ctrl-x,用于结束编辑。在EFI下ctrl-x输入不了,可以用F5代替。
  • F6 - 切换到到下一个控件。一般用TAB也可以实现类似功能。不过在双终端模式下,TAB用于自动完成,要在两个终端间切换就需要使用F6。
  • F8 - 在文本和图形模式之间切换。
  • F9 - 关机
  • F10 - 重启
  • ESC - 在弹出窗口里返回

以下段落描述风格文件的格式。

基本结构

风格文件的格式非常简单,{}用来开始一个自结点,而 = 用于设置属性的值,例如:

screen {
  panel {
    extend = 1
    valign = center
    halign = center

    panel {
      class = frame
      id = __menu__
    }
  }
}

mapkey {
  f5 = ctrl-x
}

风格文件里最顶层的元素定义了一个段,每个段有固定的功能。比如说,screen段里定义屏幕布局,而mapkey段里定义按键映射。

有两个命令可以装载风格文件,load_config和merge_config:

load_config /boot/grub/default.txt

load_config和merge_config的区别在于,在某个段已经存在的情况下,load_config会用新的内容来覆盖,而merge_config会合并新旧内容。

数据表示

风格文件的是同时支持图形和文本模式的,因此属性通常由多个部分组成,以适应不同的环境。

大小

所有表示大小的属性都使用类似的表示方式:

10

10个字符大小,在文本和图形模式下都适用。图形模式下,字符大小是使用系统缺省字体来计算。缺省字体用变量gfxfont来指定。另外,1字符单元在横向和纵向上的大小是不一样的。

10%

大小是父控件宽/高的10%,在文本和图形模式下都适用。

10/1

图形模式下是10像素,文本模式下是1字符。另外,两个部分都可以换为百分比格式,例如:

10%/20%

图形模式下是10%,文本模式下是20%。

颜色

red

红色,在文本和图形模式下都适用。

支持的颜色名字有以下这些。在文本模式下,只有前面一组颜色可以作为背景颜色:

  • black, blue, green, cyan, red, magenta, brown, light-gray
  • dark-gray, light-blue, light-green, light-cyan, light-red, light-magenta, yellow, white

red/blue

前景颜色红色,背景颜色蓝色。在文本和图形模式下都适用。

#808080/red/blue

图形模式下,使用RGB颜色#808080。在文本模式下,前景颜色红色,背景颜色蓝色。

某个命令如果有关联的命令的话,它就可以被选择。可以在通常状态和被选择状态下使用不同的颜色值,方法是用:号把两个颜色连起来:

cyan/blue:light-gray/blue

在被选择状态下,前景白色,背景蓝色。在一般状态下,前景青色,背景蓝色。

图片

,,blue,#0

蓝色的色块。在文本和图形模式下都适用。

,,blue,c

蓝色的矩形,用c字符来填充。在文本和图形模式下都适用。

,,blue,#0x250F

蓝色的矩形,用unicode 0x250F字符来填充。在文本和图形模式下都适用。

/splash.png,,blue,#0

图形模式下,显示图像/splash.png。在文本模式下,显示蓝色色块。

/splash.png,,blue

图形模式下,显示图像/splash.png。在文本模式下,什么都不显示。

/splash.png

同上,不过使用缺省的缩放模式和填充颜色。

none,,blue,#0

在图形模式下什么都不显示,在文本模式下显示蓝色色块。

在上面的例子里,第二个参数都是空的。这个参数是用来指定缩放模式的,可以取以下的值:

  • scaling (缺省) - 缩放图像以适应控件的长和宽。
  • center - 把图像显示在正中。
  • tiling - 瓷砖模式。重复图像以至于覆盖控件。
  • minfit - 最小化等比例防缩。保证整个图像都被显示,不过在左右/上下边界可能留有空白。
  • maxfit - 最大化等比例防缩。保证没有空白,不过部分图像可能被切割。

在留有空白的情况下(center和minfit),用第三个参数的颜色来进行填充。

和颜色值类似,你可以用:来连接两个图像值,以在一般状态和被选择状态下使用不同的图像:

,,cyan/blue,#0x250F:,,light-gray/blue,#0x2554

公有属性

有一些属性是所有控件都具有的,这包括布局管理器专用的属性,command,anchor和class。

布局管理器

控件的定位有两种方式,你可以直接设定它的位置,也可以让布局管理器来自动计算。

在直接定位时,可以使用以下的属性:

  • attach_top - 到父控件上边界的距离
  • attach_bottom - 到父控件下边界的距离
  • attach_left - 到父控件左边界的距离
  • attach_right - 到父控件又边界的距离
  • attach_hcenter - 离父控件水平中心线的位移
  • attach_vcenter - 离父控件水平垂直中心线的位移

如果以上属性都没有设置时,布局管理器会试图自动计算位置,你可以用以下属性来加以控制:

  • extend - 设为1时,在父控件扩展方向上延伸。
  • valign - 垂直对齐方式,可以为 top, center, bottom 或者 extend (缺省)。
  • halign - 水平对齐方式,可以为 left, center, right 或者 extend (缺省)。

父控件则使用以下属性来控制子控件的摆放:

  • direction - 扩展方向,可以是 top_to_bottom (缺省), bottom_to_top, left_to_right 或者 right_to_left.
  • space - 两个相连子控件间保留的空间

控件大小可以用以下属性来指定:

  • width - 控件的宽
  • height - 控件的高

如果以上属性没有指定,布局管理器会试图自动计算宽/高。在一般情况下,它会取恰好能包含子控件的最小的值,不过在extend为1时,它会横向/纵向延伸。

有时,你想让布局管理器自动计算控件大小。不过不想得到过大或者过小的值,以至影响外观。在这种情况下,你可以用以下值来设置限制:

  • minimum_width - 控件的最小宽度
  • maximum_width - 控件的最大宽度
  • minimum_height - 控件的最小高度
  • maximum_height - 控件的最大高度

以上属性在直接指定width/height属性的情况下是无效的。

Command

command属性为控件增加关联的命令。一旦设置以后,控件就变为可选则的。用方向键可以在可选控件间切换。回车键则运行当前控件的命令。

用\n分割符可以在command里指定多行命令,例如:

command = "chainloader +1\nboot"

Anchor

有时你需要把可选控件分组。比如说,把同一个菜单里的菜单项为一组,则在第一个菜单项里用向前键就会跳会最后一项而不是离开菜单。这个可以通过在菜单总结点里设定属性anchor=1来实现。用TAB键可以在不同的组间切换。

Class

有许多控件共享一样的属性设置。比如说,边框的设置在很多情况下都是一样的。可以设置class,对应的属性在class段里寻找,这样可以避免大量重复的设置。

即使是没有class属性,系统也会以控件的类名来搜索class段,以找到缺省属性。

screen {
 panel { class = frame }
 panel { class = frame }
}

class {
 frame {
  top_left = ",,cyan/blue,#0x250F:,,light-gray/blue,#0x2554"
  top = ",tiling,cyan/blue,#0x2501:,,light-gray/blue,#0x2550"
  top_right = ",,cyan/blue,#0x2513:,,light-gray/blue,#0x2557"
  left = ",tiling,cyan/blue,#0x2503:,,light-gray/blue,#0x2551"
  right = ",tiling,cyan/blue,#0x2503:,,light-gray/blue,#0x2551"
  bottom_left = ",,cyan/blue,#0x2517:,,light-gray/blue,#0x255A"
  bottom = ",tiling,cyan/blue,#0x2501:,,light-gray/blue,#0x2550"
  bottom_right = ",tiling,cyan/blue,#0x251B:,,light-gray/blue,#0x255D"
 }

 screen {
  background = ":,,blue,#0"
 }
}

控件

控件是组成用户界面的基本单元。每个控件都有一定的属性值来控制其行为。

panel

panel是一个容器。你可以为panel设置边框。总共有四组边框,从外到里分别是:

  • padding_size, padding_top, padding_bottom, padding_left, padding_right - 在边框外保留的空间。padding_size 同时设置四边的值,你也可以用padding_top等来覆盖某些边。
  • border_color, border_size, border_top, border_bottom, border_left, border_right - 第二层,由单一颜色的色条组成。
  • top_left, top, top_right, left, right, bottom_left, bottom, bottom_right - 第三层,由8个边框图像组成。
  • margin_size, margin_top, margin_bottom, margin_left, margin_right - 边框里保留的空间,可以避免子控件过于接近边界。
  • background - 背景图片,覆盖控件的内部空间。

screen

screen是最顶层控件,代表整个屏幕。它的属性意义和panel相同,不过只使用了margin_*和background。

text

text是显示单行文本的控件,支持以下的属性:

  • text - 显示的文本
  • gfx_text - 在图形模式下显示的文本。如果没有设置的话,文本和图形模式显示同样的文本。
  • color - 文本颜色
  • font - 文本字体

image

image是显示单个图像的控件,支持以下的属性:

  • image - 显示的图像

edit

edit是显示编辑框的控件,支持以下的属性:

  • max_lines - 最多保存得行数。max_lines=1 指定单行编辑模式。max_lines=0 不限制最大行数。如果没有设置的话,使用缺省值100。
  • lines - 屏幕上显示得行数。这个用于计算控件的高度,不要和height一起使用。
  • columns - 屏幕上显示得列数。这个用于计算控件的宽度,不要和width一起使用。
  • text - 开始显示的文本,用\n指定多行文本。
  • color - 文本颜色。
  • font - 文本字体。

在edit控件里,使用ctrl-x键保存结果,ESC取消。

term

终端窗口,支持的属性和edit是一样。

password

密码输入框,和单行编辑框类似,不过输入时显示*而不是真正得内容。支持columns, color和font属性。

progressbar

进度条控件,支持以下属性:

  • color - 进度条颜色。可以用:来指定两种颜色。第一个对应已经度过的时间,而第二个对应剩余的时间。

模板

模板用于定义组合控件,例如:

dialog_hello {
  panel {
    parameters = "text=text.text"
    class = frame
    text {}
  }
}

parameters属性定义模板的输入参数和内部控件的属性的映射。有些模板是在系统内部使用,它们必须要在风格文件里定义。

  • dialog_message - 显示一个信息窗口,text参数里指定显示的内容。
  • dialog_password - 显示密码输入框。username参数指定用户名,password参数指定密码。
  • template_submenu - 生成子菜单的模板。
  • template_menuite - 生成菜单项的模板。title参数指定标题文本,class参数指定类型。

以下是缺省风格文件里的定义:

dialog_message {
  panel {
    parameters = "text=text.text"
    class = frame
    margin_size = 1
    margin_bottom = 0
    space = 1
    attach_hcenter = 0
    attach_vcenter = 0
    text {}
    panel {
      class = frame
      command = true
      halign = center
      margin_left = 1
      margin_right = 1
      text { text = OK }
    }
  }
}

dialog_password {
  panel {
    parameters = "username=__user__.text:password=__pass__.text"
    class = frame
    margin_size = 1
    margin_bottom = 0
    attach_hcenter = 0
    attach_vcenter = 0

    panel {
      direction = left_to_right
      space = 1
      text {
        extend = 1
        valign = center
        text = Username
      }
      panel {
        class = frame
        margin_left = 1
        margin_right = 1
        edit {
          id = __user__
          max_lines = 1
        }
      }
    }

    panel {
      direction = left_to_right
      space = 1
      text {
        extend = 1
        valign = center
        text = Password
      }
      panel {
        class = frame
        margin_left = 1
        margin_right = 1
        password {
          id = __pass__
        }
      }
    }

    panel {
      class = frame
      command = true
      halign = center
      margin_left = 1
      margin_right = 1
      text {
        text = OK
      }
    }
  }
}

template_submenu {
  panel {
    class = frame
  }
}

template_menuitem {
  panel {
    parameters = "class=image.class:title=text.text"
    class = select
    direction = left_to_right
    image {}
    text { valign = center }
  }
}

这个风格把字菜单显示在父菜单的旁边,如果要全屏显示子菜单,可以用以下的模板。

template_submenu {
  panel {
    absolute = 1
    width = 100%
    height = 100%

    panel {
      id = __child__
      class = frame
      valign = center
      halign = center
      extend = 1
    }
  }
}

这里,absolute=1 指定不要以父菜单为基础调整子菜单的位置,而id为child的控件标明菜单项插入的位置。

使用模板后,屏幕的设置非常简单:

screen {
  panel {
    extend = 1
    valign = center
    halign = center

    panel {
      class = frame
      id = __menu__
    }
  }
}

id为menu的控件是主菜单插入的地方。

你可以用menu_popup命令来使用模板建立对话框。比如,要弹出hello world的信息框,可以使用dialog_message模板:

menu_popup dialog_message "text=Hello, World"

menu_edit和menu_popup很类似,不过它使用双向的参数传递,可以用来在线编辑控件的属性值。首先,定义模板dialog_edit:

dialog_edit {
  panel {
    parameters = "text=edit.text"
    class = frame
    width = 80%
    attach_hcenter = 0
    attach_vcenter = 0

    edit {
      lines = 10
    }
  }
}

然后,用以下命令弹出编辑框:

menu_edit dialog_edit text=command

进入时,编辑框内容设为当前控件的command属性值。在编辑完成后,把编辑框的内容设置回command属性里。

定义热键

用 keymap 段可以映射按键,主要用于某些系统如EFI下ctrl组合无法输入的情形。

用 onkey 段可以把某些键关联到grub命令。如果该键已经被当前控件使用,则onkey里的定义被忽略。比如说,在终端窗口中,c表示一般的字符输入,打开终端窗口的命令被忽略。以下是风格文件里热键的定义:

onkey {
  e = "*menu_edit dialog_edit text=command"
  t = "if menu_edit dialog_line text=title; then menu_refresh; fi"
  c = "*menu_popup term_window"
  2 = "*menu_popup two_term"
  f6 = ui_next_anchor
  f8 = menu_toggle_mode
  f9 = halt
  f10 = reboot
}

mapkey {
  f5 = ctrl-x
}

命令前的*字符表示该命令是受密码保护的,具体的在下一节介绍。

密码

要启动密码保护,需要在grub.cfg前加上以下的命令:

set superusers=admin
password --md5 admin '$1$A1tpOB3$bTHEMeIVvBbQsLZIWmJp/.'
password user1 user1

superusers变量设置超级用户。password命令为个别用户设置密码。带--md5参数时使用md5密码。

要生成md5密码,可以用grub-mkpasswd命令,例如:

grub-mkpasswd admin

输出:

$1$A1tpOB3$bTHEMeIVvBbQsLZIWmJp/.

也可以用openssl命令来生成:

openssl passwd -1 -salt 1234567 admin

输出:

$1$1234567$ergpnZu0mLdD77Dbmwjpb1

要保护某个启动项,在menuentry里加上--users选项:

menuentry Item1 --users user1 {
  true
}

只有user1和超级用户可以使用这一项。

在热键定义中,如果某个命令前加上*,则只有超级用户可以运行该命令。

保存缺省启动项

要保存缺省启动项,首先需要用grub-editenv生成环境文件:

sudo grub-editenv /boot/grub/grubenv create

环境文件的缺省位置是grub目录下的grubenv,你也可以用 变量envfile来覆盖。命令load_env用于导入环境文件。

要在所有菜单项里使用保存功能,只需要在grub.cfg里设置savedefault=1就行了。要跳过某些项,可以在menuentry里加上--nosave。也可以用相反的方式。不设置savedefault的值,而在需要保存的项里加上--save。例如:

set envfile=/boot/grub/grubenv
set savedefault=1
load_env

menuentry Item1 --nosave {
  true
}

menuentry Item2 --save {
  true
}

自动启动

用timeout变量可以让系统自动启动如果在N秒内没有按键。

set timeout=5

如果timeout为0,则马上启动。但你也可以在启动前按下任何键来中断。在timeout=0时,不会显示菜单,除非是自动启动被中断。

菜单图标

在菜单项里加上图标,可以使用--class选项,例如:

menuentry Item1 --class image_ubuntu {
  true
}

在风格文件里,还要定义对应的图标:

class {
  image_ubuntu {
    image = "/boot/grub/ubuntu.png"
  }
}

缺省菜单

你可以把一个缺省菜单添加到menuentry定义的启动项后。缺省菜单在风格文件里定义,使用menu段:

menu {
  Tools {
    class = image_dir
    users = user
    save = 0

    "Toggle Mode" {
      class = image_tools
      command = menu_toggle_mode
    }

    "Terminal" {
      class = image_term
      command = "menu_popup term_window"
    }

    "Two Term" {
      class = image_term
      command = "menu_popup two_term"
    }

    "About" {
      class = image_about
      command = "menu_popup dialog_message \"text=This is GNU GRUB\""
    }
  }

  Shutdown {
    class = image_shutdown
    command = "halt"
  }

  Restart {
    class = image_restart
    command = "reboot"
  }
}

这里,class属性对应于menuentry里的--class选项,users对应于--users选项,而save=1/save=0对应于--save和--nosave。


CategoryBootAndPartition

Burg/zh_CN (last edited 2017-09-02 16:18:36 by ckimes)