页面

2011年6月8日

教您如何认识植柔皮,头层皮革,修面皮革,油蜡皮、水染皮、摔纹皮、纳帕皮、打蜡皮、压花皮、修面皮、漆光皮、磨砂皮、贴膜皮

#wiki

植柔皮:皮质的术语。

  从皮革的档次来分:全粒面皮>半粒面皮>轻修面皮>重修面皮

  从皮革的软硬来分:铬鞣皮>半植鞣皮>全植鞣皮(烤皮)

  从皮革的风格做法来分:油蜡皮、水染皮、摔纹皮、纳帕皮、打蜡皮、压花皮、修面皮、漆光皮、磨砂皮、贴膜皮、印花皮、裂纹皮、反绒皮等。
真皮:真皮又有头层皮和二层皮区分。
头层皮是指带有粒面(真皮层)的牛、羊、猪皮等,皮面有自然特殊的纹路效果。二层皮没有真皮层,是纤维组织(网状层),经化学材料喷涂或覆上 PVC 、 PU 薄膜加工而成,因此,区分头层皮和二层皮的有效方法,是观察皮的纵切面纤维密度。头层皮由又密又薄的真皮层及与其紧密连在一起的稍疏松的网状层共同组成,具有良好的强度、弹性和工艺可塑性等特点。
再生皮:国外又名皮糠纸。将各种动物的费皮及真皮下脚料粉碎后,调配化工原料加工制作而成。其表面加工工艺同真皮的修面皮、压花皮一样,其特点是皮张边缘较整齐、利用率高、价格便宜;但皮身一般较厚,强度较差,只适宜制作平价公文箱、拉杆袋、球杆套等定型工艺产品和平价皮带,其纵切面纤维组织均匀一致,可辨认出流质物混合纤维的凝固效果。
人造革:也叫仿皮或胶料,是PVC和 PU 等人造材料的总称。它是在纺织布基或无纺布基上,由各种不同配方的 PVC 和 PU 等发泡或覆膜加工制作而成,可以根据不同强度、耐磨度、耐寒度和色彩、光泽、花纹图案等要求加工制成,具有花色品种繁多、防水性能好、边幅整齐、利用率高和价格相对真皮便宜的特点,但绝大部分的人造革,其手感和弹性无法达到真皮的效果;它的纵切面,可看到细微的气泡孔、布基或表层的薄膜和干干巴巴的人造纤维。
购买皮货防骗绝招,消费者须知

一 认准皮层:好多商家都理直气壮的对您承诺:“不是真皮的皮货,假一赔十”。这句话确实是真的,因为确实是真皮的,但不是头层皮的,所以他不敢说:“不是头层真皮的皮货,假一赔十”。因为市场上为了竞争,90%是二层皮,因为头层皮原料价格要贵的多,利润空间太小,所以利益驱使,都卖二层皮皮货。
 
   小知识:一张原皮,可以剖若干层来用,不过,高贵、美观、耐用只属于头层皮,其它层皮无法比拟。国外市场高价大量收购头层皮,二层皮因为价格低廉,所有盛销国内

二 认轻修饰皮:皮革需要上浆,在浆的下面,就大有文章了。残皮修补术揭露,大家都知道,十皮九残,残皮的价格和无残皮的价格相差甚大,以次冲好为了扩大利润空间,暴利驱使,残次皮货大量覆盖国内市场。
    
  小知识:残皮经过“补残”、“磨面”、“印花”、“滚涂”等工序,使残次消失的无影无踪,骗你没商量,确实是头层皮,但你还是上当了,因为它不是好的头层皮(荔枝纹皮是我们最常见的一种)。

三 辨别皮种:有的皮货确实是头层皮,也无残皮修饰,但它不是应该适用的皮种。大家都知道,什么皮都有他的适用范围。以低档皮种冒充高档皮种,利润空间更是巨大,暴利驱使,骗你没商量,好多自称“行家”的也难免上当。
无论在哪买皮货,都要找一个真正的内行,起码要有几年的制革经验的人,做您的皮货购买鉴定向导才安全。据众多人上当者反映:自己看些有关皮货的文章做资本,凭感觉进一些大的商场去购买皮货,最终以上当告终。等内行人讲给他上当的理由时,才后悔没请个内行去当参谋,本身经营者就是皮盲,购买皮货上当挡也挡不住,钱没少花,真正的高档皮货确没买到,遗憾不已。皮货诱人,购前三思,认准再买,避免上当。看货论价,不要一味的相信品牌,更多的我们要相信专业。

2011年6月2日

JavaScript判断浏览器类型及版本

#wiki

   你知道世界上有多少种浏览器吗?除了我们熟知的IE, Firefox, Opera, Safari四大浏览器之外,世界上还有近百种浏览器。

       几天前,浏览器家族有刚诞生了一位小王子,就是Google推出的Chrome浏览器。由于Chrome出生名门,尽管他还是个小家伙,没有人敢小看他。以后,咱们常说浏览器的“四大才子”就得改称为“五朵金花”了。

       在网站前端开发中,浏览器兼容性问题本已让我们手忙脚乱,Chrome的出世不知道又要给我们添多少乱子。浏览器兼容性是前端开发框架要解决的第一个问题,要解决兼容性问题就得首先准确判断出浏览器的类型及其版本。

       JavaScript是前端开发的主要语言,我们可以通过编写JavaScript程序来判断浏览器的类型及版本。JavaScript判断浏览器类型一般有两种办法,一种是根据各种浏览器独有的属性来分辨,另一种是通过分析浏览器的userAgent属性来判断的。在许多情况下,值判断出浏览器类型之后,还需判断浏览器版本才能处理兼容性问题,而判断浏览器的版本一般只能通过分析浏览器的userAgent才能知道。

       我们先来分析一下各种浏览器的特征及其userAgent。

       IE

      只有IE支持创建ActiveX控件,因此她有一个其他浏览器没有的东西,就是ActiveXObject函数。只要判断window对象存在ActiveXObject函数,就可以明确判断出当前浏览器是IE。而IE各个版本典型的userAgent如下:

        Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)
        Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)
        Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
        Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)

      其中,版本号是MSIE之后的数字。

       Firefox

       Firefox中的DOM元素都有一个getBoxObjectFor函数,用来获取该DOM元素的位置和大小(IE对应的中是getBoundingClientRect函数)。这是Firefox独有的,判断它即可知道是当前浏览器是Firefox。Firefox几个版本的userAgent大致如下:

        Mozilla/5.0 (Windows; U; Windows NT 5.2) Gecko/2008070208 Firefox/3.0.1
        Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070309 Firefox/2.0.0.3
        Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070803 Firefox/1.5.0.12
      其中,版本号是Firefox之后的数字。

       Opera

       Opera提供了专门的浏览器标志,就是window.opera属性。Opera典型的userAgent如下:

        Opera/9.27 (Windows NT 5.2; U; zh-cn)
        Opera/8.0 (Macintosh; PPC Mac OS X; U; en)
        Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.0

      其中,版本号是靠近Opera的数字。

       Safari

       Safari浏览器中有一个其他浏览器没有的openDatabase函数,可做为判断Safari的标志。Safari典型的userAgent如下:

        Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13
        Mozilla/5.0 (iPhone; U; CPU like Mac OS X) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A93 Safari/419.3

      其版本号是Version之后的数字。

      Chrome

      Chrome有一个MessageEvent函数,但Firefox也有。不过,好在Chrome并没有Firefox的getBoxObjectFor函数,根据这个条件还是可以准确判断出Chrome浏览器的。目前,Chrome的userAgent是:

        Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13

      其中,版本号在Chrome只后的数字。

      有趣的是,Chrome的userAgent还包含了Safari的特征,也许这就是Chrome可以运行所有Apple浏览器应用的基础吧。

      只要了解了以上信息,我们就可以根基这些特征来判断浏览器类型及其版本了。我们会将判断的结果保存在Sys名字空间中,成为前端框架的基本标志信息,供今后的程序来读取。如果判断出谋种浏览器,Sys名字空间将有一个该浏览器名称的属性,其值为该浏览器的版本号。例如,如果判断出IE 7.0,则Sys.ie的值为7.0;如果判断出Firefox 3.0,则Sys.firefox的值为3.0。下面是判断浏览器的代码:

    <script type="text/javascript">
        
var Sys = {};
        
var ua = navigator.userAgent.toLowerCase();
        
if (window.ActiveXObject)
            Sys.ie 
= ua.match(/msie ([\d.]+)/)[1]
        
else if (document.getBoxObjectFor)
            Sys.firefox 
= ua.match(/firefox\/([\d.]+)/)[1]
        else if (window.MessageEvent && !document.getBoxObjectFor)
            Sys.chrome 
= ua.match(/chrome\/([\d.]+)/)[1]
        else if (window.opera)
            Sys.opera 
= ua.match(/opera.([\d.]+)/)[1]
        
else if (window.openDatabase)
            Sys.safari 
= ua.match(/version\/([\d.]+)/)[1];
        
        
//以下进行测试
        if(Sys.ie) document.write('IE: '+Sys.ie);
        
if(Sys.firefox) document.write('Firefox: '+Sys.firefox);
        
if(Sys.chrome) document.write('Chrome: '+Sys.chrome);
        
if(Sys.opera) document.write('Opera: '+Sys.opera);
        
if(Sys.safari) document.write('Safari: '+Sys.safari);

    </script>

      我们把对IE的判断放在第一,因为IE的用户最多,其次是判断Firefox。按使用者多少的顺序来判断浏览器类型,可以提高判断效率,少做无用功。之所以将Chrome放在第三判断,是因为我们预测Chrome很快会成为市场占有率第三的浏览器。其中,在分析浏览器版本时,用到了正则表达式来析取其中的版本信息。

      如果你的JavaScript玩得很高,你还可以将前面的判断代码写成这样:

    <script type="text/javascript">
        
var Sys = {};
        
var ua = navigator.userAgent.toLowerCase();
        window.ActiveXObject 
? Sys.ie = ua.match(/msie ([\d.]+)/)[1] :
        document.getBoxObjectFor 
? Sys.firefox = ua.match(/firefox\/([\d.]+)/)[1] :
        window.MessageEvent && !document.getBoxObjectFor ? Sys.chrome = ua.match(/chrome\/([\d.]+)/)[1] :
        window.opera ? Sys.opera = ua.match(/opera.([\d.]+)/)[1] :
        window.openDatabase 
? Sys.safari = ua.match(/version\/([\d.]+)/)[1] : 0;
        
        
//以下进行测试
        if(Sys.ie) document.write('IE: '+Sys.ie);
        
if(Sys.firefox) document.write('Firefox: '+Sys.firefox);
        
if(Sys.chrome) document.write('Chrome: '+Sys.chrome);
        
if(Sys.opera) document.write('Opera: '+Sys.opera);
        
if(Sys.safari) document.write('Safari: '+Sys.safari);
    
</script>

      这样可以使JavaScript代码更精简些。当然,可读性稍差一些,就看你是重视效率还是重视可维护性了。

      使用不同特征来判断浏览器的方法,虽然在速度上比用正则表达式分析userAgent要来的快,不过这些特征可能会随浏览器版本而变化。比如,一种浏览器本来独有的特性取得了市场上的成功,其他浏览器也就可能跟着加入该特性,从而使该浏览器的独有特征消失,导致我们的判断失败。因此,相对比较保险的做法是通过解析userAgent中的特征来判断浏览器类型。何况,反正判断版本信息也需要解析浏览器的userAgent的。

      通过分析各类浏览器的userAgent信息,不难得出分辨各类浏览器及其版本的正则表达式。而且,对浏览器类型的判断和版本的判断完全可以合为一体地进行。于是,我们可以写出下面的代码:

    <script type="text/javascript">
        
var Sys = {};
        
var ua = navigator.userAgent.toLowerCase();
        
var s;
        (s 
= ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
        (s 
= ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
        (s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
        (s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
        (s 
= ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;

        
//以下进行测试
        if (Sys.ie) document.write('IE: ' + Sys.ie);
        
if (Sys.firefox) document.write('Firefox: ' + Sys.firefox);
        
if (Sys.chrome) document.write('Chrome: ' + Sys.chrome);
        
if (Sys.opera) document.write('Opera: ' + Sys.opera);
        
if (Sys.safari) document.write('Safari: ' + Sys.safari);
    
</script>

      其中,采用了“... ? ... : ...”这样的判断表达式来精简代码。判断条件是一条赋值语句,既完成正则表达式的匹配及结果复制,又直接作为条件判断。而随后的版本信息只需从前面的匹配结果中提取即可,这是非常高效的代码。

       以上的代码都是为了打造前端框架所做的预研,并在五大浏览器上测试通过。今后,判断某种浏览器只需用if(Sys.ie)或if(Sys.firefox)等形式,而判断浏览器版本只需用if(Sys.ie == '8.0')或if(Sys.firefox == '3.0')等形式,表达起来还是非常优雅的。

2011年5月22日

PHP分页列表类,函数

#wiki 一直都在用框架开发很少写这样的代码了,因为项目需要写了个分页 顺便发上来保存下。

class PageClass{
  
   public $PageSize;   //每页显示多少条,默认10条
   private $PageCount;   //统计页数
   private $DataCount;   //统计所有的记录
   private $Page;    //返回当前页数
   private $SqlStr;   //返回SQL代码,以便调试
  
   function __get($key){
    if(isset($this->$key)){
     return $this->$key;
    }
   } 
   function __construct($pagesize = 10){
    $this->PageSize = $pagesize;
   }
  
   #返回数据列表(2维数组),Sql:输入的查询语句,Page:获取page参数的值
   function ListData($Sql,$Page){
    $Count = mysql_query($Sql);
    $this->DataCount = mysql_num_rows($Count);
    //$mod = ($this->DataCount)%($this->PageSize);
    //$this->PageCount = (($mod==0)?(($this->DataCount)/($this->PageSize)):(($this->DataCount-$mod)/($this->PageSize)+1));
    $this->PageCount = ceil($this->DataCount/$this->PageSize);
    if($this->PageCount==0)return 0;
    $this->Page = $Page;
    if($this->Page>$this->PageCount)$this->Page = $this->PageCount;
    if($this->Page<1)$this->Page = 1;

    $this->SqlStr=$Sql." limit ".($this->PageSize*$this->Page-$this->PageSize).",".$this->PageSize;
    $Query = mysql_query($this->SqlStr);
    if($Query==Null){
     die(mysql_error());
    }else{
     while($tmp = mysql_fetch_array($Query)){
      $Data[] = $tmp;
     }
     return $Data;
    }
   }
  
   #输出{ 第一页 | 上一页 | 下一页 | 最后一页 },Parameters:url传递的参数
   function PrintPage($Parameters){
    if($this->PageCount<=1){
     echo('{ 第一页 | 上一页 | 下一页 | 最后一页 }');
    }else{
     if($this->Page>=2 && $this->Page<$this->PageCount){
      echo("{ <a href=?$Parameters&page=1>第一页<a> | <a href=?$Parameters&page=".($this->Page-1).">上一页</a> | <a href=?$Parameters&page=".($this->Page+1).">下一页</a> | <a href=?$Parameters&page=".$this->PageCount.">最后一页</a> }");
     }else{
      if($this->Page<2 && $this->Page<$this->PageCount){
       echo("{ 第一页 | 上一页 | <a href=?$Parameters&page=".($this->Page+1).">下一页</a> | <a href=?$Parameters&page=".$this->PageCount.">最后一页</a> }");
      }else{
       echo("{ <a href=?$Parameters&page=1>第一页<a> | <a href=?$Parameters&page=".($this->Page-1).">上一页</a> | 下一页 | 最后一页 }");
      }
     }
    }
    echo '<span style="margin:0 15px;"></span>共<span>'.$this->PageCount.'</span>页 | 每页显示<span>'.$this->PageSize.'</span>条 | 当前第<span>'.$this->Page.'</span>页';
   }

}

DEMO:

$P = new PageClass(10) //创建个对象,初始化PageSIze=10
//也可 $P->PageSize=10 设置显示条数
$Data = $P->ListDate("Select * From News",$_REQUEST['page']); //返回列表数据

//循环输出记录
$i=0;
while($i<count($Data)){
       echo $Data[i]['title']; //输出标题
}

$P->PrintPage("pid=1&cid=1"); //输出上页下也代码

//也自己写成其他样式的。。。
echo $P->PageSIze;
echo $P->Pagecount;
echo $P->DataCount;

2011年5月16日

你的妈妈已经等了二十几年

那天是周末,早就说好了要和朋友们去逛夜市,母亲却在下班时打来电话:"明天我们公司去踏青,你下班时帮我到面包店买一袋椰蓉面包,我带着中午吃。"

"踏青?"我发吃一惊,"啊,你们还去踏青?"想都不想,我一口回绝:"妈,我跟朋友约好了要出去,我没时间。"跟母亲讨价还价了半天。她一直说:"只是买一袋面包,快得很,不会耽误你……"最后她都有点生气了,我才不情愿地答应下来。

一心想着速战速决,刚下班我就飞奔前往,但是到了面包店一看竟是人山人海。想起朋友们肯定都在等我,我更是急得跺脚。真不知道母亲是怎么想的,周末不在家休息,还要去春游?春游,根本就是小孩子的事情嘛!

售货员统计了每个人买的数量,算起来我是第三炉的最后一个。这时,背后有人轻轻叫一声:"小姐。"我转过头去,是个不认识的中年妇人,我问:"怎么了?"她说:"小姐,我们打个商量好吗?你看,我只在你后面一个人,就得再等一炉。我这是给儿子买,他明天远足,我一会儿还得做饭送他去补习班。如果你不急的话,我想,嗯……"

"请问你是帮谁买?"她轻声问。"给我妈买,她明天也要踏青。"当回答完时,我发现整个店突然有一种奇异的寂静,所有的眼光同时投向我。"哇,今天卖了好几百袋,你可是第一个买给妈妈的。"售货小姐笑着说。我一惊,环顾四周才发现,队伍里几乎全是女人,从白发苍苍到绮年少妇,每个人的大包小包,都注解着她们主妇和母亲的身份。

"那你们呢?""当然是给我们小皇帝的。"不知是谁接了口,大家都笑了。我身后那位妇女连声说:"对不起!我真没想到,这家店人这么多,你都肯等。我本来都不想来的,是儿子一定要,我也希望让他吃好、玩好。我们小时候远足,还不就是想着要吃零食?"

她脸上忽然浮现出神往的表情,我问:"您现在还记得小时候远足的事啊?"她笑了:"怎么不记得?现在也想去啊,哪怕只在草坪上坐一坐晒晒太阳也好!可是总没时间。"

她轻轻叹口气,"大概,我之后等孩子长到你这么大的时候,才有机会吧!"原来是这样,踏青并不是母亲一时心血来潮,而是内心深处一个已经埋藏了几十年的心愿。而我怎么会一直不知道呢,我是母亲的女儿啊。

她手里的塑胶袋里,全是小孩子爱吃的东西。沉甸甸地,坠得身子微微倾斜,她也不肯放下来歇一歇,"都是不能碰、不能压的。"她就这样背负着她那不能碰、不能压的责任,吃力地、坚持地等待着。

她的笑容平静:"谁叫我是当妈

2011年4月20日

grub4dos初级教程-入门篇


#wiki

0 为何写此初级教程?

假如你是第一次听说grub,你可能说我不需要grub。那么,你是否用过“一键ghost”,“超级急救盘”,或者“矮人DOS工具箱”?如果你用过的话,那么你实际上已经在用grub了。

grub4dos 相关的资料互联网上并不少,grub4dos软件包里也有说明文件,可是绝大多数资料并不适合刚接触grub的人。初学者下载了grub4dos软件包后,面对一大堆(约40个)的文件,即使大概看了readme.txt文件后,也很可能仍然是一团雾水,不知从何处入手。出现这种状况的一个主要原因是,此软件是作者利用业余时间开发的,开发者在有限的时间里集中精力于排除软件bug,从而无过多剩余精力撰写文档。

其实,初步使用这个软件并不难,可以说非常简单。下面的内容参考了有关资料,并结合自己的使用经验,供初学者参考,希望能对你入门grub有所帮助。我自身也是接触grub不久,对grub的了解还很肤浅,错误之处,在所难免,还望不吝指出。


1 grub4dos初级教程-入门篇

1.1 grub简介

GRUB 是一个遵从Multiboot(多重启动)规范的启动管理程序。现在接触到的有3种,即GNU Grub Lagecy , GNU Grub2 和 Grub for dos(grub4dos)。

GNU GRUB Lagecy其实就是原来的 GNU GRUB 0.xx ,最新版是2005年发布的GNU GRUB 0.97。 目前已停止开发,并改名为 GNU GRUB Lagecy。

GNU GRUB2是第二代GRUB,它将取代原来的GNU GRUB(例如0.9x版),但目前还处于开发阶段,尚未发布正式版。

GNU GRUB Lagecy和GNU GRUB2都是 GNU 组织的项目。

GRUB for DOS(GRUB4DOS)是一个以 GNU GRUB 为基础的功能强大的引导器。它可以在 DOS 和 LINUX下运行,也可以通过其他引导器来运行,还可以作为MBR运行。GRUB4DOS内置了功能完善的 BIOS 级磁盘仿真。

下面以比较广泛使用的GRUB4DOS为基础进行说明。GNU GRUB与GRUB4DOS的不同之处,可参看相关说明文件。 

1.2 如何获得grub4dos最新版

可从以下网址下载GRUB4DOS最新版及较早版本。
http://download.gna.org/grub4dos/ 
http://download.gna.org/grubutil/ 
http://grub4dos.jot.com/WikiHome 
https://gna.org/projects/grub4dos/ 
http://grub4dos.sourceforge.net/wiki (官方说明文档)

1.3 如何安装grub4dos?

下载grub4dos后,解压缩后就可以了。核心文件有下面这几个:grldr和grub.exe,及menu.lst(此为样本,需修改)。如果你需要中文支持,就用chinese子目录中的文件。

安装方法常见的有下面3种。

1.3.1 通过Windows NT的启动菜单进入grub4dos 

将grldr文件复制到c:\,去掉boot.ini的只读属性,然后修改c:\boot.ini文件,在boot.ini的最后面加一行:
c:\grldr="Start GRUB4DOS"
并将boot.ini中的timeout值设置为大于0的数字,如:timeout=5,然后保存boot.ini,改回只读属性。
编辑boot.ini前,可在cmd下输入:
attrib -s -r -h c:\boot.ini 
解除boot.ini的只读属性,编辑完后输入:
attrib +s +r +h c:\boot.ini 
恢复boot.ini的原有属性。

这样,编辑完重新启动计算机,在NT的启动菜单就会出现“Start GRUB4DOS”这一项,选择该项即可进入grub4dos的环境。

此方法的优点是:不需要修改MBR。

初学者使用grub一般都需要grub菜单,把准备好的menu.lst文件放到C:\下(也可放到其它分区根目录或其它指定目录)。menu.lst的编写方法可参考readme.txt或者别人提供的menu.lst。在下面的“1.4 如何使用grub4dos”中将作简单介绍。

1.3.2 通过DOS启动grub

将机器通过任何可能的方式(软盘,U盘,光盘等)启动到DOS环境(最好是纯DOS环境,即不加载任何驱动程序和TSR程序的DOS环境),然后在DOS下或者AUTOEXEC.BAT中运行grub.exe,即可进入grub4dos。
也可在DOS/Windows9x的CONFIG.SYS中使用下列任一方式启动grub。
DEVICE=GRUB.EXE
INSTALL=GRUB.EXE
SHELL=GRUB.EXE

此方法的优点是:不需要修改MBR;可根据需要在脚本或者其它DOS程序中启动GRUB4DOS。 

菜单文件menu.lst可保存在grub文件所在目录或其它指定路径。

1.3.3 通过mbr启动grub

通过软件包里的bootlace.com(可运行于DOS/Win9x)安装GRLDR引导记录到硬盘或者硬盘映像文件的主引导记录,或者安装到软盘或者软盘映像的引导扇区。电脑启动时,通过击热键(默认为空格键,可自定义)来启动grub。

比如:
在DOS下安装GRLDR代码到主引导记录:
bootlace.com 0x80

在DOS下安装GRLDR代码到软盘:
bootlace.com --floppy --chs 0x00

在DOS下安装GRLDR代码到软盘映像:
bootlace.com --floppy --chs floppy.img

我所使用的命令为:
bootlace --force-backup-mbr --boot-prevmbr-first --time-out=3 --hot-key=0x3920 --mbr-disable-floppy 0x80 
表示安装GRLDR代码到MBR时,备份原MBR(--force-backup-mbr),默认启动原MBR,即启动原windows xp系统(--boot-prevmbr-first),等待时间3秒(--time-out=3),热键为空格键(--hot- key=0x3920), 不搜索软盘上的GRLDR(--mbr-disable-floppy)。

也就是说启动时等待3秒,3秒内不击热键的话,启动windows xp;3秒内击热键则启动grub4dos。 

bootlace的其它参数及自定义热键用法可参看readme.txt文件。

装入mbr后,再将grldr和menu.lst文件复制到某分区的根目录(现在支持的文件系统是FAT12,FAT16, FAT32, NTFS,EXT2 or EXT3 的分区。对于Windows用户,最好是fat分区),menu.lst也可保存到其它指定位置。

此方法的优点是:不依赖于操作系统;能够自动搜索硬盘上各个分区的grldr文件。 

另外,2000/xp/2003/vista环境下可用另一软件grubinst来把GRLDR引导记录安装到硬盘的MBR。grubinst具有图形界面和命令行两种工作模式供选用,并附有比较详细的使用说明,很易于使用。【参看附录 4.1 如何使用grubinst_gui

1.3.4 通过Windows NT的启动菜单进入grub4dos NEW!

用批处理自动把grub4dos装入Vista启动项(非MBR)。

把grub4dos装入Vista启动项,比装入MBR相对来说要安全。
【对于vista系统,不能通过fdisk /mbr来恢复mbr,这样会造成vista无法启动。】


关于手动把grub4dos装入Vista的启动项的方法,网上有一些介绍。比起winxp修改Boot.ini来,操作要麻烦不少。

主要就是操作过程中要产生一个ID号【如:b88a2da4-0a4e-11dc-813a-00e04c75ef59】,需要手动输入3次,实在是麻烦。 

下面的批处理自动完成整个装入操作。


-------------------------------
@echo off
rem by lianjiang
cls
echo.
echo 请以管理员身份运行。
echo.
pause
set gname=Grub 4 dos
set vid=
set timeout=5
bcdedit /export "Bcd_Backup" >nul
bcdedit /create /d "%gname%" /application bootsector >vid.ini
for,/f,"tokens=2",%%i,In (vid.ini) Do (
                set vid=%%i
)
del vid.ini >nul
bcdedit /set %vid% device boot >nul
bcdedit /set %vid% path \grldr.mbr >nul
bcdedit /displayorder %vid% /addlast >nul
bcdedit /timeout   %timeout% >nul
if exist grldr.mbr copy grldr.mbr c:\ /y && goto exit
echo.
echo 稍后请自行把grldr.mbr拷贝到C:\根目录
echo.
pause
:exit
-------------------------------
下载批处理附件to_bcd.rar
此方法的优点是:不需要修改MBR。

grub菜单文件的准备同“1.3.1 通过Windows NT的启动菜单进入grub4dos”。

1.4 如何使用grub4dos

对于多数没有或很少接触过linux的windows用户来说,刚开始使用grub时离不开菜单。也就是说,使用grub前,我们要准备menu.lst文件。

下面是一个menu.lst的例子。(以#开始的行,表示注释,不执行)

# 默认延迟时间(秒)
timeout 30

# 第一项为默认值
default 0

# 设置图形背景文件
splashimage (hd0,0)/boot/grub/xp2008.gz

# 设置中文支持的字体文件
fontfile (hd0,0)/boot/grub/fonts

title 使用map启动本地硬盘上的瑞星杀毒软盘镜像文件
map (hd0,0)/boot/grub/rav.img (fd0)
map --hook
chainloader (fd0)+1
rootnoverify (fd0)

title 使用memdisk启动本地 Win98 软盘镜像文件
kernel (hd0,0)/boot/grub/memdisk.gz
initrd (hd0,0)/boot/grub/win98.img

title 使用memdisk启动本地硬盘上的瑞星杀毒软盘压缩镜像文件
root (hd0,0)
kernel /boot/grub/memdisk.gz c=80 h=12 s=36 floppy
initrd /boot/rav.zip

title 启动第一主分区(hd0,0)上的操作系统
rootnoverify (hd0,0)
makeactive
chainloader +1

title 启动第二主分区(hd0,1)上的操作系统
rootnoverify (hd0,1)
makeactive
chainloader +1

title 重启
reboot

title 关机
halt 
参考这个例子,我们就可以根据自己需要对菜单进行修改。

比如从网上下载了效率源的镜像文件,文件名为XLY.IMG。我们只需把
title 使用memdisk启动本地 Win98 软盘镜像文件
kernel (hd0,0)/boot/grub/memdisk.gz
initrd (hd0,0)/boot/grub/win98.img

改成
title 硬盘检测修复工具 效率源 (memdisk)
kernel (hd0,0)/boot/grub/memdisk.gz
initrd (hd0,0)/boot/grub/xly.img

或者改成
title 硬盘检测修复工具 效率源 (map)
map (hd0,0)/boot/grub/xly.img (fd0)
map --hook
chainloader (fd0)+1
rootnoverify (fd0)

同时把xly.img文件保存到第一主分区(一般是C:)的boot\grub目录下。
当然也可以保存到其它路径。

比如xly.img文件保存到C:\boot下,则menu.lst文件相应改为:
map (hd0,0)/boot/xly.img (fd0)

又如xly.img文件保存到D:\test下,则menu.lst文件相应改为:
map (hd0,4)/test/xly.img (fd0)
(参看下面的注意d) 

从上面的例子可以看出,启动软盘镜象,有两种方式,即用memdisk或用map。

用memdisk时,img文件可压缩;在img文件大小为非1.44MB或2.88MB标准镜像时,需要指定CHS参数。img文件的CHS参数可用winimage获得。

即例子中的:
title 使用memdisk启动本地硬盘上的瑞星杀毒软盘压缩镜像文件
root (hd0,0)
kernel /boot/grub/memdisk.gz c=80 h=12 s=36 floppy
initrd /boot/rav.zip

另外,菜单文件中的文件路径可用相对路径(如:/boot/rav.zip)或绝对路径(如:(hd0,0)/boot/grub/xly.img)表示。

map方式对软盘映像大小没有限制,但要求必须连续存放。改进的map --mem则无此限制。

比如:
map --mem /boot/xxx.ima (fd0)
map --hook
chainloader (fd0)+1
rootnoverify (fd0)

注意:
a, 菜单文件中所用的memdisk.gz文件,不包括在grub4dos的发行包里,需自行准备。可从gnu grub软件包或从其它基于grub的工具(如一键ghost,本人的gghost)中获得。

b, 菜单中所用的其它文件如xp2008.gz(背景文件)、fonts(中文字体文件)及各种镜像文件等,均需拷贝到文件中指定路径。 fontfile命令不可单独使用,需与splashimage一起使用。

c, 菜单文件中的命令全部使用小写。

d,
 初学者使用绝对路径时要注意GRUB对设备的命名方法。系统的第一个硬盘驱动器表示成(hd0),其上的第一个分区表示为(hd0,0),也就是说对于硬盘,采用(hdx,y)的形式来表示,x、y都是从0开始计数的,x表示硬盘号,y表示分区号。
由于主分区只能有四个,所以第一硬盘的四个主分区分别用(hd0,0)~(hd0,3)来表示;逻辑分区则从(hd0,4)开始算,即第一逻辑分区用(hd0,4),第二逻辑分区用(hd0,5)来表示,依次类推。
一般机子的硬盘都是一个主分区,其余是逻辑分区。因此C盘用(hd0,0),D盘用(hd0,4)来表示。 光盘用(cd)表示,第一软驱用(fd0)表示。


下面是我现在使用的菜单效果图及menu.lst文件,供参考。

color white/green yellow/green
default 1
timeout 3
#fontfile /boot/grub/fonts
#splashimage /boot/grub/bg.xpm.gz
#password --md5 $1$8$D0mfzTIQXv2Ma2b5bWH0b.
title 0, Boot from Hard Drive (hd0,0)
root (hd0,0)
chainloader +1

title 1, GreenGhost [Ghost v8.3/v11] (MAP-HOOK)
map --mem /boot/grub/gghost.img (fd0)
map --hook
chainloader (fd0)+1
rootnoverify (fd0)

title 2, GreenGhost [Ghost v8.3/v11] (MEMDISK)
kernel /boot/grub/memdisk.gz c=200 h=2 s=36 floppy
initrd /boot/grub/gghost.img 

title 3, GreenGhost [Ghost v8.3/v11] (MAP-HOOK) [disable a20]
map --mem /boot/grub/gghost.img (fd0)
map --hook
chainloader --disable-a20 (fd0)+1
rootnoverify (fd0)

title 4, Microsoft Windows NT/2K/XP
find --set-root /ntldr
chainloader /ntldr

title 5, Microsoft Windows Vista
find --set-root /bootmgr
chainloader /bootmgr

title 6, Boot from Hard Drive (hd0,1)
root (hd0,1)
chainloader +1

title 7, Reboot
reboot

title 8, Shutdown
halt

1.5 结言

Grub4dos具有强大的功能,上面介绍的只是grub4dos的一些最基本用法,更多的用法可在掌握基本用法的基础上,自己查阅资料了解。