qishun's profile躺在角落的孤独者PhotosBlogLists Tools Help

Blog


    November 09

    VistaPE启动原理与数据配置

     

    Windows Vista 启动过程在操作系统的定位和初始化的方式上与 Windows XP 有所不同。启动时首先是由 BIOS 加载可引导磁盘上的主引导记录 (MBR),可引导磁盘由 BIOS 中配置的引导顺序定义。MBR 接下来加载活动分区上的分区引导记录 (PBR)。在此之前的 Windows Vista 的启动过程相对于以前没有变化。
    copyright e5b

    Windows Vista 与 XP 的差别是从 PBR 代码开始的,Windows Vista 的 PBR 代码不再查找 NTLDR。Windows Vista 中新的启动加载器是 BOOTMGR。BOOTMGR 是一个用于加载启动配置数据库 (BCD) 的组件,启动配置数据库接下来将加载操作系统加载器启动应用程序 Winload.exe。最后,Winload.exe 初始化 Windows Vista 内核。

    image

    上图说明了启动过程,可以将这一更改视为对如下两个要素的更改:

    ● 由以前的 Windows 版本中的 NTLDR 执行的两个主要操作现在由两个组件分开执行:

    ○ \Bootmgr:读取启动配置,包括设备和路径位置。
    copyright e5b

    ○ \Windows\System32\Winload.exe:初始化内核。

    ● 由以前的 Windows 版本中的 Boot.ini 存储的启动配置现在存储在一个位于以下位置的、基于注册表的数据库中:

    ○ \Boot\BCD:启动配置数据库 (BCD)

    BCD 是一个由 Bootmgr 使用的数据库,该数据库包含 boot.ini 的函数并位于活动分区【被激活引导的系统C盘】的启动目录\Boot中。Windows Vista 提供了 BCDEDIT.exe 命令行工具来管理 BCD 存储中项目,该工具位于 Windows Vista 分区的 \Windows\System32 目录中。BCD 使得在 Windows Vista 中不再需要 BOOT.INI,不过 BOOT.INI 仍将会出现在双启动系统中以便向后兼容。因为 BCD 首先引导到启动环境而非 NTLDR,所以不会验证 NTLDR 和 BOOT.INI 的位置,除非选中了旧版操作系统。BCD 存储是一个注册表配置单元,在 Windows Vista 中,运行 regedit.exe 时将加载此配置单元,但会在视图中隐藏它。该存储将被加载到以下的注册表位置:HKLM\BCD00000000。也可以通过从 \Boot 文件夹中加载该配置单元,从而在 WinRE 中手动查看该存储。C:\Boot 的目录含有BCD、BCD.LOG、BCD.LOG1、fixfat.exe、fixntfs.exe、memtest.exe文件及zh-CN、en-US、Fonts语言字体文件夹。
    命令行工具 Bcdedit.exe可以对系统活动分区实现更改 Bootmgr 选项,添加启动项目,删除启动项目,编辑项目,导入/导出 BCD 存储,以及在存储严重损坏的情况下创建新的存储。Bcdedit.exe 位于 Windows Vista 分区的 \Windows\System32 目录中,也可以在 WinRE 中从命令提示符访问该工具。如果获取正在运行的系统上的配置单元的副本,请使用以下命令导出一个配置单元文件以进行脱机检查:Bcdedit /export filename。此命令将 BCD 存储导出到当前目录中一个名为“filename”的文件中。但是,不建议按照这种方式直接编辑 BCD 存储,因为这样做会产生意外的结果。

    Bcdedit操作指令,编辑BCD文件

    Bcdedit 位于X:\Windows\system32\ "X:"为安装Vista的盘符。

      储存操作指令

      ====================

      /createstore 创建一个新的空白启动配置数据文件。

      bcdedit /createstore C:\Data\BCD 创建BCD启动配置数据文件储存到“C:\DATA\”文件夹。

      /export 备份启动配置数据文件。

      bcdedit /export "C:\Data\BCD Backup" 备份BCD启动配置文件到“C:\Data\”文件夹,并以“BCD Backup”命名。

      /import 还原启动配置数据文件。

      bcdedit /import "C:\Data\BCD Backup" 从“C:\Data\”文件夹恢复BCD启动配置文件。

      储存项目操作指令

      ====================

      /copy 项目拷贝

      操作系统启动项目的拷贝:

      bcdedit /copy {cbd971bf-b7b8-4885-951a-fa03044f5d71} /d "Copy of entry"

      /create 新建项目

      创建操作系统载入程序项目的 NTLDR(Ntldr):

      bcdedit /create {ntldr} /d "Earlier Windows OS Loader"

      创建存储器磁碟另外的选择项项目:

      bcdedit /create {ramdiskoptions} /d "Ramdisk options"

      创建一个新的操作系统启动项目:

      bcdedit /create /d "Windows Vista" /application osloader

      创建一个新的调试器:

      bcdedit /create {dbgsettings} /d "Debugger Settings"

      /delete 删除项目

      删除指定的操作系统项目:

      bcdedit /delete {cbd971bf-b7b8-4885-951a-fa03044f5d71}

      删除指定的操作系统项目但启动时不显示项目(彻底删除):

      bcdedit /delete {cbd971bf-b7b8-4885-951a-fa03044f5d71} /cleanup

      删除指定的操作系统项目但启动时显示项目:

      bcdedit /delete {cbd971bf-b7b8-4885-951a-fa03044f5d71} /nocleanup

      删除操作系统载入程序项目的 NTLDR:

      bcdedit /delete {ntldr} /f

      项目选择操作指令

      ====================

      /deletevalue 删除项目选择项。

      删除启动管理的bootmgr选择项项目:

      bcdedit /deletevalue {bootmgr} bootsequence

      删除(WinPE)操作系统的数值开机项目:

      bcdedit /deletevalue winpe

      删除来自指定的操作的 Windows PE 数值系统开机项目:

      bcdedit /deletevalue {cbd971bf-b7b8-4885-951a-fa03044f5d71} winpe

      /set 设定项目选择项数值。

      设定操作系统“cbd971bf-b7b8-4885-951a-fa03044f5d71”引导分区“C”:

      bcdedit /set {cbd971bf-b7b8-4885-951a-fa03044f5d71} device partition=C:

      指定的操作系统引导文件“ windows\ system 32\ winload.exe”:

      bcdedit /set {cbd971bf-b7b8-4885-951a-fa03044f5d71} path \windows\system32\winload.exe

      设定“NX”为“OptIn”:

      bcdedit /set nx optin

      更改系统名称

      默认XP系统名称在Vista启动管理器中是"earlier version of Windows",更改:

      bcdedit /set {ntldr} Description "Windows XP Professional SP2"

      默认Vista系统名称在Vista启动管理器中是"Microsoft Windows",更改:

      bcdedit /set {current} Description "Windows Vista 5456"

      输出控制指令

      ====================

      /enum 在储存中的列表项目。

      列出所有的操作系统载入程序启动项目:

      bcdedit /enum OSLOADER

      列出所有的启动管理项目:

      bcdedit /enum BOOTMGR

      列出默认的启动项目:

      bcdedit /enum {default}

      列出指定的操作系统启动项目:

      bcdedit /enum {b38a9fc1-5690-11da-b795-e9ad3c5e0e3a}

      /v 列出所有活动的项目

      bcdedit /enum ACTIVE /v  

      启动管理控制指令

      ====================

      /bootsequence 设定启动列表顺序。

      设定二个操作系统项目和启动顺序:

      bcdedit /bootsequence {802d5e32-0784-11da-bd33-000476eba25f} {cbd971bf-b7b8-4885-951a- fa03044f5d71} {ntldr}

      加入操作系统项目为启动列表最后项:

      bcdedit /bootsequence {802d5e32-0784-11da-bd33-000476eba25f} /addlast

      /default 设定默认启动项目。

      设定默认启动项目:

      bcdedit /default {cbd971bf-b7b8-4885-951a-fa03044f5d71}

      设定默认启动操作系统程序为 NTLDR:

      bcdedit /default {ntldr}

      /displayorder 设定哪一个系统启动显示多启动画面。

      设定二个操作系统项目和在启动管理显示命令中被建立操作系统载入的程序 NTLDR:

      bcdedit /displayorder {802d5e32-0784-11da-bd33-000476eba25f}

       {cbd971bf-b7b8-4885-951a-fa03044f5d71} {ntldr}

      把指定的操作系统项目加入启动管理显示命令结束:

      bcdedit /displayorder {802d5e32-0784-11da-bd33-000476eba25f} /addlast

      /timeout 设定启动暂停数值。

      /toolsdisplayorder 设定命令在哪一个启动管理显示工具画面。

      设定二个工具项目和内存诊断在那启动管理工具显示命令:

      bcdedit /toolsdisplayorder {802d5e32-0784-11da-bd33-000476eba25f}

       {cbd971bf-b7b8-4885-951a-fa03044f5d71} {memdiag}

      把指定的工具项目加入启动的结束管理工具显示命令:

      bcdedit /toolsdisplayorder {802d5e32-0784-11da-bd33-000476eba25f} /addlast 

      为一个启动应用程序控制紧急处理服务的指令

      ====================

      /bootems

      开启启动管理紧急处理服务:

      bcdedit /bootems {bootmgr} ON

      /ems

       为目前的操作系统启动项目 EMS 开启:

      bcdedit /ems ON

      /emssettings 设定紧急处理服务参数。

      设定 EMS 参数使用基本输出入系统设定:

       bcdedit /emssettings BIOS

    November 04

    winpe操作硬盘分区

     

    1.select disk 0

    2.clean

    3.create partion primary size=10000

    4.select partion 1

    5.active

    6.format fs=ntfs

    7.assign letter=C

    8.exit 退出

    xcopy /e  目录copy

    BOOT ,bootMGR 文件到c盘;

    November 03

    石头与iphone间的事

    image

    这图左边是4万年前的石头,右边是08年出的3G iPhone,看看两者之间的比较…

    MMS = 手机彩信

    Video Recording = 视频录像

    Videocall = 视频通话

    Changeable memory cards = 可更换记忆卡

    Touchscreen = 触摸屏

    相比之后我们发现,3G iPhone只比这块石头多了个触摸屏而已。

    __attribute__ 详解

    From http://hi.baidu.com/cygnusnow/blog/item/8b82000f871fcf2f6159f3de.html

    GNU C的一大特色(却不被初学者所知)就是__attribute__机制。__attribute__可以设置函数属性(Function     Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。
    __attribute__书写特征是:__attribute__前后都有两个下划线,并切后面会紧跟一对原括弧,括弧里面是相应的__attribute__参数。
    __attribute__语法格式为:
    __attribute__ ((attribute-list))
    其位置约束为:
    放于声明的尾部“;”之前。
    函数属性(Function Attribute)
    函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。__attribute__机制也很容易同非GNU应用程序做到兼容之功效。
    GNU CC需要使用 –Wall编译器来击活该功能,这是控制警告信息的一个很好的方式。下面介绍几个常见的属性参数。

    __attribute__ format
    该__attribute__属性可以给被声明的函数加上类似printf或者scanf的特征,它可以使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。该功能十分有用,尤其是处理一些很难发现的bug。
    format的语法格式为:
    format (archetype, string-index, first-to-check)
              format属性告诉编译器,按照printf, scanf,
    strftime或strfmon的参数表格式规则对该函数的参数进行检查。“archetype”指定是哪种风格;“string-index”指定传入函数的第几个参数是格式化字符串;“first-to-check”指定从函数的第几个参数开始按上述规则进行检查。
    具体使用格式如下:
    __attribute__((format(printf,m,n)))
    __attribute__((format(scanf,m,n)))
    其中参数m与n的含义为:
    m:第几个参数为格式化字符串(format string);
    n:参数集合中的第一个,即参数“…”里的第一个参数在函数参数总数排在第几,注意,有时函数参数里还有“隐身”的呢,后面会提到;
    在使用上,__attribute__((format(printf,m,n)))是常用的,而另一种却很少见到。下面举例说明,其中myprint为自己定义的一个带有可变参数的函数,其功能类似于printf:
    //m=1;n=2
    extern void myprint(const char *format,...) __attribute__((format(printf,1,2)));
    //m=2;n=3
    extern void myprint(int l,const char *format,...)
    __attribute__((format(printf,2,3)));
    需要特别注意的是,如果myprint是一个函数的成员函数,那么m和n的值可有点“悬乎”了,例如:
    //m=3;n=4
    extern void myprint(int l,const char *format,...)
    __attribute__((format(printf,3,4)));
    其原因是,类成员函数的第一个参数实际上一个“隐身”的“this”指针。(有点C++基础的都知道点this指针,不知道你在这里还知道吗?)
    这里给出测试用例:attribute.c,代码如下:
    1:
    2:extern void myprint(const char *format,...)
    __attribute__((format(printf,1,2)));
    3:
    4:void test()
    5:{
    6:     myprint("i=%d\n",6);
    7:     myprint("i=%s\n",6);
    8:     myprint("i=%s\n","abc");
    9:     myprint("%s,%d,%d\n",1,2);
    10:}

    运行$gcc –Wall –c attribute.c attribute后,输出结果为:

    attribute.c: In function `test':
    attribute.c:7: warning: format argument is not a pointer (arg 2)
    attribute.c:9: warning: format argument is not a pointer (arg 2)
    attribute.c:9: warning: too few arguments for format

    如果在attribute.c中的函数声明去掉__attribute__((format(printf,1,2))),再重新编译,既运行$gcc –Wall –c attribute.c attribute后,则并不会输出任何警告信息。
    注意,默认情况下,编译器是能识别类似printf的“标准”库函数。

    __attribute__ noreturn
    该属性通知编译器函数从不返回值,当遇到类似函数需要返回值而却不可能运行到返回值处就已经退出来的情况,该属性可以避免出现错误信息。C库函数中的abort()和exit()的声明格式就采用了这种格式,如下所示:

    extern void exit(int)      __attribute__((noreturn));extern void abort(void) __attribute__((noreturn)); 为了方便理解,大家可以参考如下的例子:

    //name: noreturn.c     ;测试__attribute__((noreturn))
    extern void myexit();

    int test(int n)
    {
               if ( n > 0 )
              {
                       myexit();
                     /* 程序不可能到达这里*/
              }
               else
                       return 0;
    }

    编译显示的输出信息为:

    $gcc –Wall –c noreturn.c
    noreturn.c: In function `test':
    noreturn.c:12: warning: control reaches end of non-void function

    警告信息也很好理解,因为你定义了一个有返回值的函数test却有可能没有返回值,程序当然不知道怎么办了!
    加上__attribute__((noreturn))则可以很好的处理类似这种问题。把
    extern void myexit();修改为:
    extern void myexit() __attribute__((noreturn));之后,编译不会再出现警告信息。

    __attribute__ const
    该属性只能用于带有数值类型参数的函数上。当重复调用带有数值参数的函数时,由于返回值是相同的,所以此时编译器可以进行优化处理,除第一次需要运算外,其它只需要返回第一次的结果就可以了,进而可以提高效率。该属性主要适用于没有静态状态(static state)和副作用的一些函数,并且返回值仅仅依赖输入的参数。
    为了说明问题,下面举个非常“糟糕”的例子,该例子将重复调用一个带有相同参数值的函数,具体如下:

    extern int square(int n) __attribute__     ((const));...                  for (i = 0; i < 100; i++ )                  {       total += square (5) + i;             }
    通过添加__attribute__((const))声明,编译器只调用了函数一次,以后只是直接得到了相同的一个返回值。
    事实上,const参数不能用在带有指针类型参数的函数中,因为该属性不但影响函数的参数值,同样也影响到了参数指向的数据,它可能会对代码本身产生严重甚至是不可恢复的严重后果。
    并且,带有该属性的函数不能有任何副作用或者是静态的状态,所以,类似getchar()或time()的函数是不适合使用该属性的。
    -finstrument-functions
    该参数可以使程序在编译时,在函数的入口和出口处生成instrumentation调用。恰好在函数入口之后并恰好在函数出口之前,将使用当前函数的地址和调用地址来调用下面的

    profiling
    函数。(在一些平台上,__builtin_return_address不能在超过当前函数范围之外正常工作,所以调用地址信息可能对profiling函数是无效的。)

    void __cyg_profile_func_enter(void *this_fn, void *call_site);
    void __cyg_profile_func_exit(void *this_fn, void *call_site);

    其中,第一个参数this_fn是当前函数的起始地址,可在符号表中找到;第二个参数call_site是指调用处地址。

    instrumentation
    也可用于在其它函数中展开的内联函数。从概念上来说,profiling调用将指出在哪里进入和退出内联函数。这就意味着这种函数必须具有可寻址形式。如果函数包含内联,而所有使用到该函数的程序都要把该内联展开,这会额外地增加代码长度。如果要在C 代码中使用extern inline声明,必须提供这种函数的可寻址形式。
    可对函数指定no_instrument_function属性,在这种情况下不会进行 Instrumentation操作。例如,可以在以下情况下使用no_instrument_function属性:上面列出的profiling函数、高优先级的中断例程以及任何不能保证profiling正常调用的函数。
    no_instrument_function
    如果使用了-finstrument-functions
    ,将在绝大多数用户编译的函数的入口和出口点调用profiling函数。使用该属性,将不进行instrument操作。

    constructor/destructor
    若函数被设定为constructor属性,则该函数会在main()函数执行之前被自动的执行。类似的,若函数被设定为destructor属性,则该函数会在main()函数执行之后或者exit()被调用后被自动的执行。拥有此类属性的函数经常隐式的用在程序的初始化数据方面。
    这两个属性还没有在面向对象C中实现。
    同时使用多个属性
    可以在同一个函数声明里使用多个__attribute__,并且实际应用中这种情况是十分常见的。使用方式上,你可以选择两个单独的__attribute__,或者把它们写在一起,可以参考下面的例子:

    /* 把类似printf的消息传递给stderr 并退出 */extern void die(const char *format, ...)                  __attribute__((noreturn))                  __attribute__((format(printf, 1, 2))); 或者写成 extern void die(const char *format, ...)                  __attribute__((noreturn, format(printf, 1, 2))); 如果带有该属性的自定义函数追加到库的头文件里,那么所以调用该函数的程序都要做相应的检查。

    和非GNU编译器的兼容性
    庆幸的是,__attribute__设计的非常巧妙,很容易作到和其它编译器保持兼容,也就是说,如果工作在其它的非GNU编译器上,可以很容易的忽略该属性。即使__attribute__使用了多个参数,也可以很容易的使用一对圆括弧进行处理,例如:

    /* 如果使用的是非GNU C, 那么就忽略__attribute__ */#ifndef __GNUC__#     define     __attribute__(x)     /*NOTHING*/#endif
    需要说明的是,__attribute__适用于函数的声明而不是函数的定义。所以,当需要使用该属性的函数时,必须在同一个文件里进行声明,例如:

    /* 函数声明 */void die(const char *format, ...) __attribute__((noreturn))                                     __attribute__((format(printf,1,2))); void die(const char *format, ...){                  /* 函数定义 */} 更多的属性含义参考:http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html 变量属性(Variable Attributes)
    关键字__attribute__也可以对变量(variable)或结构体成员(structure
    field)进行属性设置。这里给出几个常用的参数的解释,更多的参数可参考本文给出的连接。
    在使用__attribute__参数时,你也可以在参数的前后都加上“__”(两个下划线),例如,使用__aligned__而不是aligned,这样,你就可以在相应的头文件里使用它而不用关心头文件里是否有重名的宏定义。
    aligned (alignment)
    该属性规定变量或结构体成员的最小的对齐格式,以字节为单位。例如:

    int x __attribute__ ((aligned (16))) = 0; 编译器将以16字节(注意是字节byte不是位bit)对齐的方式分配一个变量。也可以对结构体成员变量设置该属性,例如,创建一个双字对齐的int对,可以这么写:

    struct foo { int x[2] __attribute__ ((aligned (8))); }; 如上所述,你可以手动指定对齐的格式,同样,你也可以使用默认的对齐方式。如果aligned后面不紧跟一个指定的数字值,那么编译器将依据你的目标机器情况使用最大最有益的对齐方式。例如:

    short array[3] __attribute__ ((aligned)); 选择针对目标机器最大的对齐方式,可以提高拷贝操作的效率。
    aligned属性使被设置的对象占用更多的空间,相反的,使用packed可以减小对象占用的空间。
    需要注意的是,attribute属性的效力与你的连接器也有关,如果你的连接器最大只支持16字节对齐,那么你此时定义32字节对齐也是无济于事的。
    packed
    使用该属性可以使得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐。
    下面的例子中,x成员变量使用了该属性,则其值将紧放置在a的后面:

                      struct test             {               char a;               int x[2] __attribute__ ((packed));             }; 其它可选的属性值还可以是:cleanup,common,nocommon,deprecated,mode,section,shared, tls_model,transparent_union,unused,vector_size,weak,dllimport,dlexport等,
    详细信息可参考:
    http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html#Variable-Attributes
    类型属性(Type Attribute)
    关键字__attribute__也可以对结构体(struct)或共用体(union)进行属性设置。大致有六个参数值可以被设定,即:aligned,
    packed, transparent_union, unused, deprecated 和 may_alias。
    在使用__attribute__参数时,你也可以在参数的前后都加上“__”(两个下划线),例如,使用__aligned__而不是aligned,这样,你就可以在相应的头文件里使用它而不用关心头文件里是否有重名的宏定义。
    aligned (alignment)
    该属性设定一个指定大小的对齐格式(以字节为单位),例如:

    struct S { short f[3]; } __attribute__ ((aligned (8)));
    typedef int more_aligned_int __attribute__ ((aligned (8)));

    该声明将强制编译器确保(尽它所能)变量类型为struct S或者more-aligned-int的变量在分配空间时采用8字节对齐方式。
    如上所述,你可以手动指定对齐的格式,同样,你也可以使用默认的对齐方式。如果aligned后面不紧跟一个指定的数字值,那么编译器将依据你的目标机器情况使用最大最有益的对齐方式。例如:

    struct S { short f[3]; } __attribute__ ((aligned));

    这里,如果sizeof(short)的大小为2(byte),那么,S的大小就为6。取一个2的次方值,使得该值大于等于6,则该值为8,所以编译器将设置S类型的对齐方式为8字节。
    aligned属性使被设置的对象占用更多的空间,相反的,使用packed可以减小对象占用的空间。
    需要注意的是,attribute属性的效力与你的连接器也有关,如果你的连接器最大只支持16字节对齐,那么你此时定义32字节对齐也是无济于事的。
    packed
    使用该属性对struct或者union类型进行定义,设定其类型的每一个变量的内存约束。当用在enum类型定义时,暗示了应该使用最小完整的类型(it indicates that the smallest integral type should be used)。
    下面的例子中,my-packed-struct类型的变量数组中的值将会紧紧的靠在一起,但内部的成员变量s不会被“pack”,如果希望内部的成员变量也被packed的话,my-unpacked-struct也需要使用packed进行相应的约束。

    struct my_unpacked_struct
    {
             char c;
             int i;
    };
    struct my_packed_struct
    {
            char c;
            int     i;
            struct my_unpacked_struct s;
    }__attribute__ ((__packed__));

    其它属性的含义见:
    http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Type-Attributes.html#Type-Attributes
    变量属性与类型属性举例
    下面的例子中使用__attribute__属性定义了一些结构体及其变量,并给出了输出结果和对结果的分析。
    程序代码为:

    struct p
    {
    int a;
    char b;
    char c;
    }__attribute__((aligned(4))) pp;

    struct q
    {
    int a;
    char b;
    struct n qn;
    char c;
    }__attribute__((aligned(8))) qq;

    int main()
    {
    printf("sizeof(int)=%d,sizeof(short)=%d.sizeof(char)=%d\n",sizeof(int),sizeof(short),sizeof(char));
    printf("pp=%d,qq=%d \n", sizeof(pp),sizeof(qq));

    return 0;
    }

    输出结果:

    sizeof(int)=4,sizeof(short)=2.sizeof(char)=1
    pp=8,qq=24

    分析:

    sizeof(pp):
    sizeof(a)+ sizeof(b)+ sizeof(c)=4+1+1=6<23=8= sizeof(pp)
    sizeof(qq):
    sizeof(a)+ sizeof(b)=4+1=5
    sizeof(qn)=8;即qn是采用8字节对齐的,所以要在a,b后面添3个空余字节,然后才能存储qn,
    4+1+(3)+8+1=17
    因为qq采用的对齐是8字节对齐,所以qq的大小必定是8的整数倍,即qq的大小是一个比17大又是8的倍数的一个最小值,由此得到
    17<24+8=24= sizeof(qq)

    更详细的介绍见:http://gcc.gnu.org/
    下面是一些便捷的连接:GCC 4.0 Function Attributes;GCC 4.0 Variable Attributes ;GCC 4.0 Type
    Attributes ;GCC 3.2 Function Attributes ;GCC 3.2 Variable Attributes ;GCC 3.2
    Type Attributes ;GCC 3.1 Function Attributes ;GCC 3.1 Variable Attributes

    October 21

    Glibc 安装指南(适用于2.3.6/2.4/2.5/2.6)

    由于论坛排版效果不理想,而且我也只在我的个人空间对文章进行后继更新,所以建议直接到我的空间查看:
    《Glibc Binutils GCC 配置选项简介》
    http://lamp.linux.gov.cn/Linux/Glibc...s-Install.html
    -------------------------------------------------------------------------------
    版权声明
    本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布。任何人都可以自由使用、转载、复制和再分发,但必须保留作者署名,亦不得对声明中的任何条款作任何形式的修改,也不得附加任何其它条件。您可以自由链接、下载、传播此文档,但前提是必须保证全文完整转载,包括完整的版权信息和作译者声明。

    其他作品
    本文作者十分愿意与他人共享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有作品的列表:
    金步国作品列表

    BUG报告,切磋与探讨
    由于作者水平有限,因此不能保证作品内容准确无误,请在阅读中自行鉴别。如果你发现了作品中的错误,请您来信指出,哪怕是错别字也好,任何提高作品质量的建议我都将虚心接纳。如果你愿意就作品中的相关内容与我进行进一步切磋与探讨,也欢迎你与我联系。联系方式:Email: csfrank@citiz.net ; QQ: 70171448 ; MSN: csfrank122@hotmail.com

    ==============================================

    此文是我在写作《DIY一个实用的 Mini-LAPP 服务器》过程中整理的资料,考虑到Glibc的核心地位,因此特地把这部分内容抽取出来单独成文,以供 LFS 玩家参考。此部分内容来自于源码树下的 configure INSTALL FAQ 三个文件。

    编译前的预备知识与要点提示

    Glibc-2.3.6 建议使用 GCC-4.0 编译,Glibc-2.4/2.5 建议使用 GCC-4.1 编译,Glibc-2.6 建议使用 GCC-4.2 编译。所有这些版本最低要求使用 GCC-3.4 编译。

    编译 Glibc 时使用的内核头文件版本可以比实际运行 Glibc 的内核版本高。如果实际运行的内核版本比头文件版本高,那么新内核的新特性将无法使用。更多细节可以查看[八卦故事]内核头文件传奇的跟帖部分。

    不要在运行中的系统上安装 Glibc,否则将会导致系统崩溃,至少应当将新 Glibc 安装到其他的单独目录,以保证不覆盖当前正在使用的 Glibc 。

    Glibc 不能在源码目录中编译,它必须在一个额外分开的目录中编译。这样在编译发生错误的时候,就可以删除整个编译目录重新开始。

    在运行 configure 脚本时可以设置 CC CFLAGS LDFLAGS 环境变量来优化编译。语法:configure [OPTION]... [VAR=VALUE]...

    需要注意的是有些测试项目假定是以非 root 身份执行的,因此我们强烈建议你使用非 root 身份编译和测试 Glibc 。

    配置选项
    下列选项皆为非默认值[特别说明的除外]

    --exec-prefix
    --bindir
    --libdir
    --libexecdir
    --infodir
    --datadir
    --mandir
    --program-prefix
    --program-suffix
    --program-transform-name
    --host
    --build
    --target
    --srcdir
    --cache-file
    --no-create
    --silent
    --version
    这些选项的含义基本上通用于所有软件包,这里就不特别讲解了。
    --prefix=PREFIX
    安装目录,默认为 /usr/local
    Linux文件系统标准要求基本库必须位于 /lib 目录并且必须与根目录在同一个分区上,但是 /usr 可以在其他分区甚至是其他磁盘上。因此,如果指定 --prefix=/usr ,那么基本库部分将自动安装到 /lib 目录下,而非基本库部分则会自动安装到 /usr/lib 目录中。但是如果保持默认值或指定其他目录,那么所有组件都间被安装到PREFIX目录下。
    --enable-add-ons[=DIR1,DIR2,...]
    编译DIR1,DIR2,...中的附加软件包。其中的 "DIR"是附加软件包的目录名。未指定列表或指定为"yes"则编译所有源码树根目录下找到的附加软件包。Glibc-2.4/2.5/2.6默认值为 "yes",而 Glibc-2.3.6 默认为--disable-add-ons
    --enable-bind-now
    在 DSO 载入时就进行重定位,而不是在调用时重定位。
    --enable-bounded
    启用使用运行时边界检查(比如数组越界),这样会降低运行效率,但能防止某些溢出漏洞。
    --enable-check-abi
    在"make check"时执行"make check-abi"。[提示]在我的机器上 enable 之后始终导致 make check 失败。
    --disable-force-install
    不强制安装当前新编译的版本(即使已存在的文件版本更新)。
    --disable-hidden-plt
    不隐藏内部的函数调用以避免 PLT 。[建议不要明确设置此选项]
    --enable-kernel=VERSION
    VERSION 的格式是 X.Y.Z,表示编译出来的 Glibc 支持的最低内核版本。VERSION 的值越高(不能超过内核头文件的版本),加入的兼容性代码就越少,库的运行速度就越快。
    --enable-oldest-abi=ABI
    启用老版本的应用程序二进制接口支持。ABI 是老 Glibc 的版本号。默认值大部分情况下为 --disable-oldest-abi ,建议明确指定为 --disable-oldest-abi
    --enable-omitfp
    编译时忽略帧指示器(使用 -fomit-frame-pointer 编译),并采取一些其他优化措施。忽略帧指示器可以提高运行效率,但是调试将变得不可用,并且可能生成含有 bug 的代码。使用这个选项还将导致额外编译带有调试信息的非优化版本的静态库(库名称以"_g"结尾)。
    --disable-profile
    禁用 profiling 信息相关的库文件编译。Glibc-2.3.6 默认为 enable,Glibc-2.4/2.5/2.6 默认为disable 。
    --enable-stackguard-randomization
    在程序启动时使用一个随机数初始化 __stack_chk_guard ,主要用来抵抗恶意攻击。
    --disable-sanity-checks
    真正的禁用线程(仅在特殊环境下使用该选项)。
    --enable-static-nss
    编译静态版本的NSS(Name Service Switch)库。不推荐这样做,因为连接到静态NSS库的程序不能动态配置以使用不同的名字数据库。
    --disable-shared
    不编译共享库(即使平台支持)。在支持 ELF 并且使用 GNU 连接器的系统上默认为 enable 。
    --disable-versioning
    不在共享库对象中包含符号的版本信息。这样可以减小库的体积,但是将不兼容依赖于老版本 C 库的二进制程序。[提示]在我的机器上使用此选项总是导致编译失败。
    --with-binutils=DIR
    强制指定编译时使用的 Binutils(as,ld) 的位置。
    --with-cpu=CPU
    在 gcc 命令行中加入"-mcpu=CPU"。鉴于"-mcpu"已经被反对使用,所以建议不要设置该选项,或者设为 --without-cpu 。
    --without-cvs
    不访问CVS服务器。推荐使用该选项,特别对于从CVS下载的的版本。
    --with-elf
    指定使用 ELF 对象格式,建议在支持 ELF 的 Linux 平台上使用此选项明确指定。
    --with-gd=DIR
    --with-gd-include=DIR
    --with-gd-lib=DIR
    强制指定 libgd 的安装目录(DIR/include和DIR/lib)。后两个选项分别指定包含文件和库目录。
    --with-gmp=DIR
    强制指定 gmp 的安装目录。
    --without-fp
    仅在硬件没有浮点运算单元并且操作系统没有模拟的情况下使用。x86 与 x86_64 的 CPU 都有专门的浮点运算单元。而且 Linux 有 FPU 模拟。简单的说,不要 without 这个选项!因为它会导致许多问题!
    --with-headers=DIR
    指定内核头文件的所在目录。
    --without-selinux
    禁用 SELinux 支持。
    --without-tls
    禁止编译支持线程本地存储(TLS)的库。使用这个选项将导致兼容性问题,建议不要明确指定该选项。
    --without-__thread
    即使平台支持也不使用TSL特性。建议不要明确指定该选项。
    --with-xcoff
    使用XCOFF对象格式(主要用于windows)。

    编译与测试

    使用 make 命令编译,使用 make check 测试。如果 make check 没有完全成功,就千万不要使用这个编译结果。需要注意的是有些测试项目假定是以非 root 身份执行的,因此我们强烈建议你使用非 root 身份编译和测试。

    测试中需要使用一些已经存在的文件(包括随后的安装过程),比如'/etc/passwd','/etc/nsswitch.conf'之类。请确保这些文件中包含正确的内容。

    安装与配置

    使用 make install 命令安装。比如:make install LC_ALL=C

    如果你打算将此 Glibc 安装为主 C 库,那么我们强烈建议你关闭系统,重新引导到单用户模式下安装。这样可以将可能的损害减小到最低。

    安装后需要配置 GCC 以使其使用新安装的 C 库。最简单的办法是使用恰当 GCC 的编译选项(比如'-Wl,--dynamic-linker=/lib/ld-linux.so.2')重新编译 GCC 。然后还需要修改 specs 文件(通常位于'/usr/lib/gcc-lib/TARGET/VERSION/specs'),这个工作有点像巫术,调整实例请参考 LFS 中的两次工具链调整。

    可以在 make install 命令行使用'install_root'变量指定安装实际的安装目录(不同于 --prefix 指定的值)。这个在 chroot 环境下或者制作二进制包的时候通常很有用。'install_root'必须使用绝对路径。

    被'grantpt'函数调用的辅助程序'/usr/libexec/pt_chown'以 setuid 'root' 安装。这个可能成为安全隐患。如果你的 Linux 内核支持'devptsfs'或'devfs'文件系统提供的 pty slave ,那么就不需要使用 pt_chown 程序。

    安装完毕之后你还需要配置时区和 locale 。使用 localedef 来配置locale 。比如使用'localedef -i de_DE -f ISO-8859-1 de_DE'将 locale 设置为'de_DE.ISO-8859-1'。可以在编译目录中使用'make localedata/install-locales'命令配置所有可用的 locale ,但是一般不需要这么做。

    时区使用'TZ'环境变量设置。tzselect 脚本可以帮助你选择正确的值。设置系统全局范围内的时区可以将 /etc/localtime 文件连接到 /usr/share/zoneinfo 目录下的正确文件上。比如对于中国人可以'ln -s /usr/share/zoneinfo/PRC /etc/localtime'。

    编译优化提示

    由于 Glibc 是系统的两大核心之一(还有一个是内核),虽然 LFS 指导书反对优化编译,但很多玩家觉得不优化编译心有不甘。因此,下面有几个基于 gcc-4.0.4 + Binutils-2.17 + Linux-Libc-Headers-2.6.12.0 环境的实践提示。

    能够通过 make check 的优化设置:

    CPPFLAGS='-DNDEBUG'
    CFLAGS='-O3 -finline-limit=400 -fomit-frame-pointer -falign-functions=32 -pipe -fno-bounds-check -march=pentium3 -maccumulate-outgoing-args -fforce-addr -fmerge-all-constants -fgcse-sm -fgcse-las -minline-all-stringops -ftree-loop-linear -fivopts -ftree-vectorize -fprefetch-loop-arrays -fweb -frename-registers -fbranch-target-load-optimize'
    LDFLAGS='-s -Wl,-O1,--sort-common,-s,--enable-new-dtags,--as-needed'
    [提示]建议AMD64打开 -frename-registers ; -freg-struct-return 虽然能通过测试但是却会导致GCC的测试程序出现"FAIL: gcc.dg/struct-ret-libc.c execution test"因此该优化选项未包含在其中。此外, -fbranch-target-load-optimize -fbranch-target-load-optimize2 不能同时使用。

    不能通过编译或测试的 CFLAGS :-fvisibility=hidden -mfpmath=sse -malign-double -m128bit-long-double -mregparm=3 -msseregparm -ftracer --param max-gcse-passes=2 --param max-gcse-memory=100M -Wa,-R

    与 CPU L1/L2 cache 有关的提示[对于AMD,cache是L1(皆为128K)+L2(256,512,1M,2M)的大小;对于Intel,cache是L2的大小]:
    cache <= 512K 推荐使用 -finline-limit=200 -falign-functions=16
    512K < cache <= 1M 推荐使用 -finline-limit=400 -falign-functions=32
    cache > 1M 推荐使用 -finline-limit=600 -falign-functions=64

    shell保留字和特殊变量


    保留字符及其含义

      $#     传递到脚本的参数个数
      $*     以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过9个
      $$     脚本运行的当前进程ID号(Process Identifier Number, PID)
      $!     后台运行的最后一个进程的进程ID号
      $@     与$*相同,但是使用时加引号,并在引号中返回每个参数
      $-     显示shell使用的当前选项,使用set及执行时传递给shell的标志位
      $?  显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
      $0     脚本名称
      $1..$9 第N个参数

    $  shell变量名的开始,如$var
    | 管道,将标准输出转到下一个命令的标准输入
    # 注释开始
    & 在后台执行一个进程
    ? 匹配一个字符
    * 匹配0到多个字符(与DOS不同,可在文件名中间使用,并且含.)
      >file  输出重定向
    `command` 命令替换,如 filename=`basename /usr/local/bin/tcsh`
    >>file    输出重定向,append

    转义符及单引号:
    $echo "$HOME $PATH"
      /home/hbwork /opt/kde/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:
    $echo '$HOME $PATH'
      $HOME $PATH
    $echo \$HOME $PATH
      $HOME /opt/kde/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/hbwork/bin
    其他:
      dir=ls
      $dir
      alias dir ls
      dir

    ${#var} #计算变量值的长度

    -d file   #当file是一个目录时,返回True
    -f file   #当file是一个普通文件时,返回True
    -r file   #当file是一个刻读文件时,返回True
    -s file   #当file文件长度大于0时,返回True
    -w file   #当file是一个可写文件时,返回True
    -x file   #当file是一个可执行文件时,返回True

    -r file   #当file是一个可读文件时,返回True
    -w file   #当file是一个可写文件时,返回True
    -x file   #当file是一个可执行文件时,返回True
    -e file   #当file存在时,返回True
    -o file   #当file文件的所有者是当前用户时,返回True
    -z file   #当file长度为0时,返回True
    -f file   #当file是一个普通文件时,返回True
    -d file   #当file是一个目录时,返回True

    Glibc 安装指南(适用于2.3.6/2.4/2.5/2.6)

    由于论坛排版效果不理想,而且我也只在我的个人空间对文章进行后继更新,所以建议直接到我的空间查看:
    《Glibc Binutils GCC 配置选项简介》
    http://lamp.linux.gov.cn/Linux/Glibc...s-Install.html
    -------------------------------------------------------------------------------
    版权声明
    本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布。任何人都可以自由使用、转载、复制和再分发,但必须保留作者署名,亦不得对声明中的任何条款作任何形式的修改,也不得附加任何其它条件。您可以自由链接、下载、传播此文档,但前提是必须保证全文完整转载,包括完整的版权信息和作译者声明。

    其他作品
    本文作者十分愿意与他人共享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有作品的列表:
    金步国作品列表

    BUG报告,切磋与探讨
    由于作者水平有限,因此不能保证作品内容准确无误,请在阅读中自行鉴别。如果你发现了作品中的错误,请您来信指出,哪怕是错别字也好,任何提高作品质量的建议我都将虚心接纳。如果你愿意就作品中的相关内容与我进行进一步切磋与探讨,也欢迎你与我联系。联系方式:Email: csfrank@citiz.net ; QQ: 70171448 ; MSN: csfrank122@hotmail.com

    ==============================================

    此文是我在写作《DIY一个实用的 Mini-LAPP 服务器》过程中整理的资料,考虑到Glibc的核心地位,因此特地把这部分内容抽取出来单独成文,以供 LFS 玩家参考。此部分内容来自于源码树下的 configure INSTALL FAQ 三个文件。

    编译前的预备知识与要点提示

    Glibc-2.3.6 建议使用 GCC-4.0 编译,Glibc-2.4/2.5 建议使用 GCC-4.1 编译,Glibc-2.6 建议使用 GCC-4.2 编译。所有这些版本最低要求使用 GCC-3.4 编译。

    编译 Glibc 时使用的内核头文件版本可以比实际运行 Glibc 的内核版本高。如果实际运行的内核版本比头文件版本高,那么新内核的新特性将无法使用。更多细节可以查看[八卦故事]内核头文件传奇的跟帖部分。

    不要在运行中的系统上安装 Glibc,否则将会导致系统崩溃,至少应当将新 Glibc 安装到其他的单独目录,以保证不覆盖当前正在使用的 Glibc 。

    Glibc 不能在源码目录中编译,它必须在一个额外分开的目录中编译。这样在编译发生错误的时候,就可以删除整个编译目录重新开始。

    在运行 configure 脚本时可以设置 CC CFLAGS LDFLAGS 环境变量来优化编译。语法:configure [OPTION]... [VAR=VALUE]...

    需要注意的是有些测试项目假定是以非 root 身份执行的,因此我们强烈建议你使用非 root 身份编译和测试 Glibc 。

    配置选项
    下列选项皆为非默认值[特别说明的除外]

    --exec-prefix
    --bindir
    --libdir
    --libexecdir
    --infodir
    --datadir
    --mandir
    --program-prefix
    --program-suffix
    --program-transform-name
    --host
    --build
    --target
    --srcdir
    --cache-file
    --no-create
    --silent
    --version
    这些选项的含义基本上通用于所有软件包,这里就不特别讲解了。
    --prefix=PREFIX
    安装目录,默认为 /usr/local
    Linux文件系统标准要求基本库必须位于 /lib 目录并且必须与根目录在同一个分区上,但是 /usr 可以在其他分区甚至是其他磁盘上。因此,如果指定 --prefix=/usr ,那么基本库部分将自动安装到 /lib 目录下,而非基本库部分则会自动安装到 /usr/lib 目录中。但是如果保持默认值或指定其他目录,那么所有组件都间被安装到PREFIX目录下。
    --enable-add-ons[=DIR1,DIR2,...]
    编译DIR1,DIR2,...中的附加软件包。其中的 "DIR"是附加软件包的目录名。未指定列表或指定为"yes"则编译所有源码树根目录下找到的附加软件包。Glibc-2.4/2.5/2.6默认值为 "yes",而 Glibc-2.3.6 默认为--disable-add-ons
    --enable-bind-now
    在 DSO 载入时就进行重定位,而不是在调用时重定位。
    --enable-bounded
    启用使用运行时边界检查(比如数组越界),这样会降低运行效率,但能防止某些溢出漏洞。
    --enable-check-abi
    在"make check"时执行"make check-abi"。[提示]在我的机器上 enable 之后始终导致 make check 失败。
    --disable-force-install
    不强制安装当前新编译的版本(即使已存在的文件版本更新)。
    --disable-hidden-plt
    不隐藏内部的函数调用以避免 PLT 。[建议不要明确设置此选项]
    --enable-kernel=VERSION
    VERSION 的格式是 X.Y.Z,表示编译出来的 Glibc 支持的最低内核版本。VERSION 的值越高(不能超过内核头文件的版本),加入的兼容性代码就越少,库的运行速度就越快。
    --enable-oldest-abi=ABI
    启用老版本的应用程序二进制接口支持。ABI 是老 Glibc 的版本号。默认值大部分情况下为 --disable-oldest-abi ,建议明确指定为 --disable-oldest-abi
    --enable-omitfp
    编译时忽略帧指示器(使用 -fomit-frame-pointer 编译),并采取一些其他优化措施。忽略帧指示器可以提高运行效率,但是调试将变得不可用,并且可能生成含有 bug 的代码。使用这个选项还将导致额外编译带有调试信息的非优化版本的静态库(库名称以"_g"结尾)。
    --disable-profile
    禁用 profiling 信息相关的库文件编译。Glibc-2.3.6 默认为 enable,Glibc-2.4/2.5/2.6 默认为disable 。
    --enable-stackguard-randomization
    在程序启动时使用一个随机数初始化 __stack_chk_guard ,主要用来抵抗恶意攻击。
    --disable-sanity-checks
    真正的禁用线程(仅在特殊环境下使用该选项)。
    --enable-static-nss
    编译静态版本的NSS(Name Service Switch)库。不推荐这样做,因为连接到静态NSS库的程序不能动态配置以使用不同的名字数据库。
    --disable-shared
    不编译共享库(即使平台支持)。在支持 ELF 并且使用 GNU 连接器的系统上默认为 enable 。
    --disable-versioning
    不在共享库对象中包含符号的版本信息。这样可以减小库的体积,但是将不兼容依赖于老版本 C 库的二进制程序。[提示]在我的机器上使用此选项总是导致编译失败。
    --with-binutils=DIR
    强制指定编译时使用的 Binutils(as,ld) 的位置。
    --with-cpu=CPU
    在 gcc 命令行中加入"-mcpu=CPU"。鉴于"-mcpu"已经被反对使用,所以建议不要设置该选项,或者设为 --without-cpu 。
    --without-cvs
    不访问CVS服务器。推荐使用该选项,特别对于从CVS下载的的版本。
    --with-elf
    指定使用 ELF 对象格式,建议在支持 ELF 的 Linux 平台上使用此选项明确指定。
    --with-gd=DIR
    --with-gd-include=DIR
    --with-gd-lib=DIR
    强制指定 libgd 的安装目录(DIR/include和DIR/lib)。后两个选项分别指定包含文件和库目录。
    --with-gmp=DIR
    强制指定 gmp 的安装目录。
    --without-fp
    仅在硬件没有浮点运算单元并且操作系统没有模拟的情况下使用。x86 与 x86_64 的 CPU 都有专门的浮点运算单元。而且 Linux 有 FPU 模拟。简单的说,不要 without 这个选项!因为它会导致许多问题!
    --with-headers=DIR
    指定内核头文件的所在目录。
    --without-selinux
    禁用 SELinux 支持。
    --without-tls
    禁止编译支持线程本地存储(TLS)的库。使用这个选项将导致兼容性问题,建议不要明确指定该选项。
    --without-__thread
    即使平台支持也不使用TSL特性。建议不要明确指定该选项。
    --with-xcoff
    使用XCOFF对象格式(主要用于windows)。

    编译与测试

    使用 make 命令编译,使用 make check 测试。如果 make check 没有完全成功,就千万不要使用这个编译结果。需要注意的是有些测试项目假定是以非 root 身份执行的,因此我们强烈建议你使用非 root 身份编译和测试。

    测试中需要使用一些已经存在的文件(包括随后的安装过程),比如'/etc/passwd','/etc/nsswitch.conf'之类。请确保这些文件中包含正确的内容。

    安装与配置

    使用 make install 命令安装。比如:make install LC_ALL=C

    如果你打算将此 Glibc 安装为主 C 库,那么我们强烈建议你关闭系统,重新引导到单用户模式下安装。这样可以将可能的损害减小到最低。

    安装后需要配置 GCC 以使其使用新安装的 C 库。最简单的办法是使用恰当 GCC 的编译选项(比如'-Wl,--dynamic-linker=/lib/ld-linux.so.2')重新编译 GCC 。然后还需要修改 specs 文件(通常位于'/usr/lib/gcc-lib/TARGET/VERSION/specs'),这个工作有点像巫术,调整实例请参考 LFS 中的两次工具链调整。

    可以在 make install 命令行使用'install_root'变量指定安装实际的安装目录(不同于 --prefix 指定的值)。这个在 chroot 环境下或者制作二进制包的时候通常很有用。'install_root'必须使用绝对路径。

    被'grantpt'函数调用的辅助程序'/usr/libexec/pt_chown'以 setuid 'root' 安装。这个可能成为安全隐患。如果你的 Linux 内核支持'devptsfs'或'devfs'文件系统提供的 pty slave ,那么就不需要使用 pt_chown 程序。

    安装完毕之后你还需要配置时区和 locale 。使用 localedef 来配置locale 。比如使用'localedef -i de_DE -f ISO-8859-1 de_DE'将 locale 设置为'de_DE.ISO-8859-1'。可以在编译目录中使用'make localedata/install-locales'命令配置所有可用的 locale ,但是一般不需要这么做。

    时区使用'TZ'环境变量设置。tzselect 脚本可以帮助你选择正确的值。设置系统全局范围内的时区可以将 /etc/localtime 文件连接到 /usr/share/zoneinfo 目录下的正确文件上。比如对于中国人可以'ln -s /usr/share/zoneinfo/PRC /etc/localtime'。

    编译优化提示

    由于 Glibc 是系统的两大核心之一(还有一个是内核),虽然 LFS 指导书反对优化编译,但很多玩家觉得不优化编译心有不甘。因此,下面有几个基于 gcc-4.0.4 + Binutils-2.17 + Linux-Libc-Headers-2.6.12.0 环境的实践提示。

    能够通过 make check 的优化设置:

    CPPFLAGS='-DNDEBUG'
    CFLAGS='-O3 -finline-limit=400 -fomit-frame-pointer -falign-functions=32 -pipe -fno-bounds-check -march=pentium3 -maccumulate-outgoing-args -fforce-addr -fmerge-all-constants -fgcse-sm -fgcse-las -minline-all-stringops -ftree-loop-linear -fivopts -ftree-vectorize -fprefetch-loop-arrays -fweb -frename-registers -fbranch-target-load-optimize'
    LDFLAGS='-s -Wl,-O1,--sort-common,-s,--enable-new-dtags,--as-needed'
    [提示]建议AMD64打开 -frename-registers ; -freg-struct-return 虽然能通过测试但是却会导致GCC的测试程序出现"FAIL: gcc.dg/struct-ret-libc.c execution test"因此该优化选项未包含在其中。此外, -fbranch-target-load-optimize -fbranch-target-load-optimize2 不能同时使用。

    不能通过编译或测试的 CFLAGS :-fvisibility=hidden -mfpmath=sse -malign-double -m128bit-long-double -mregparm=3 -msseregparm -ftracer --param max-gcse-passes=2 --param max-gcse-memory=100M -Wa,-R

    与 CPU L1/L2 cache 有关的提示[对于AMD,cache是L1(皆为128K)+L2(256,512,1M,2M)的大小;对于Intel,cache是L2的大小]:
    cache <= 512K 推荐使用 -finline-limit=200 -falign-functions=16
    512K < cache <= 1M 推荐使用 -finline-limit=400 -falign-functions=32
    cache > 1M 推荐使用 -finline-limit=600 -falign-functions=64

    September 30

    挖个坑,自己跳进去

        百思不得其解的问题,郁闷了那么多时日。到头来,确实自己给自己挖了坑,埋葬的是自己!

       囚鸟
    我是被你囚禁的鸟,
    已经忘了天有多高,
    如果离开你给我的小小城堡,
    不知还有谁能依靠。
    我是被你囚禁的鸟,
    得到的爱越来越少,
    看着你的笑在别人眼中燃烧,
    我却要不到一个拥抱。
    我像是一个你可有可无的影子,
    冷冷地看着你说谎的样子,
    这撩乱的城市,
    容不下我的痴,
    是什么让你这样迷恋这样的放肆,
    我像是一个你可有可无的影子,
    和寂寞交换着悲伤的心事,
    对爱无计可施,
    这无味的日子,
    眼泪是唯一的奢侈。

    我是被你囚禁的鸟,
    得到的爱越来越少,
    看着你的笑在别人眼中燃烧,
    我却要不到一个拥抱。
    我像是一个你可有可无的影子,
    冷冷地看着你说谎的样子,
    这撩乱的城市,
    容不下我的痴,
    是什么让你这样迷恋这样的放肆,
    我像是一个你可有可无的影子,
    和寂寞交换着悲伤的心事,
    对爱无计可施,
    这无味的日子,
    眼泪是唯一的奢侈。

    我像是一个你可有可无的影子,
    冷冷地看着你说谎的样子,
    这撩乱的城市,
    容不下我的痴,
    是什么让你这样迷恋这样的放肆,
    我像是一个你可有可无的影子,
    和寂寞交换着悲伤的心事,
    对爱无计可施,
    这无味的日子,
    眼泪是唯一的奢侈。

    css 引入顺序

    今天同事利用CSS进行表格单元的背景切换,做个比较炫炫的结果,但是利用的CSS却不能修改。后来对css进行修改,发现了两个简单的原则:

    1:就进

      就进原则是指CSS的定义与引用元素的距离近,则引用近元素的属性。a1{ font-size:18pt;color:#00FF00} a2{font-size:24px;color:}

    <h1 class=”a1 a2”>11231</h1> 则使用了a2定义的属性。

    2:排外

        .sort .a{font-size:10px;color:red;}

        .a1{font-size;18px;}

    <div class=”sort”>

    <h1 class=”a a1”>123132</h1>则字体效果为size使用10px;color为红色。

    该处原则是指针对引用多个class时,如果存在想到的属性定义,则采取这两种原则。

    September 26

    Linux内核完全剖析--计算组成原理的介绍

    南桥芯片和北桥芯片的概念解释

    北桥芯片用于与CPU、内存和AGP视频接口,这些接口具有很高的传输速率。北桥芯片还起着存储器控制作用,因此Intel把该芯片标号为MCH(Memory Controller Hub)芯片。南桥芯片用来管理低、中速的组件,如PCI总线、IDE硬盘接口、USB端口等,因此南桥芯片的名称为ICH(I/O Controller Hub)。之所以用"南、北"桥来分别统称这两个芯片,是由于在Intel公司公布的典型PC主板上,它们分别位于主板的下端和上端(即地图上的南部和北部),并起着与CPU进行通道桥接的作用。

    image

    I/O端口寻址

    端口统一编址的原理是把I/O控制器中的端口地址归入存储器寻址地址空间范围内。因此这种编址方式也称为存储器映像编址。CPU访问一个端口的操作与访问内存的操作一样,也使用访问内存的指令。

    端口独立编址的方法是把I/O控制器和控制卡的寻址空间单独作为一个独立的地址空间对待,称为I/O地址空间。每个端口有一个I/O地址与之对应,并且使用专门的I/O指令来访问端口。

    September 21

    KVM的失败

       今天去生产线部署环境,发现原来的程序竟然连接不上了KVM。一时不知所措。后来想了想,与原来的环境有么区别呢?

    机器换了?还是同一个型号。网络环境改动了?原来是服务器和PC机直连,现在是搭建的局域网。于是用交换机重新部署了网络

    环境,竟然无果。

         于是,刷新firmware到1.0,刷新的时候是用u盘启动,在DOS下运行命令行。无论刷新到1.0.1,1.0.3,还是刷新到最新版的1.1

    ,结果还是无法连接。

         下午实在不行了,不在产线上用机器实验,于是用大库机器刷新firmware。利用web页刷新,竟然可以了。

    头疼!不知道是怎么个情况?

    去产线接着试下刚才的机器是否可以再次刷新到版本。

    而且用u盘和web各刷下一次。

    应该避免防止的几类网站攻击

    漏洞一:数据库下载漏洞

    第一步,搜索攻击目标

    打开搜索引擎,搜索“Pragram by Dlog”,可以找到许多博客页面,这些博客都是使用“Dlog破废墟修改版”建立的。我们要找的叶面是存在暴库漏洞的1.2版本。许多用户都忽视了这个版本中内嵌的eWebEditor在线编辑数据库的安全性,致使黑客可以使用默认的路径进行下载。

    第二步,获取管理员密码

    在搜索结果列表中挑一个攻击目标:(http://s*.8888.com/blog/),用浏览器打开这个地址,在后面加上eWebEditor/db/e/eWebEditor.mdb并回车,下载数据库。

    打开这个数据库,在数据库的“eWebEditor_system”列中可以看到管理员的用户名和密码。由于密码都是经过MD5加密的,因此找一个MD5密码暴力破解器计算机分钟或几天,就可得到密码。不过据经验,只要能下载这个数据库,就说明管理员极有可能没有更改默认的登陆密码,如果看到MD5密码为“7a57a5a743894a0e”,那么密码就是默认的“admin”。现在,我们可以进入eWebEditor后台在线编辑页面了。

    第三步,控制服务器

    在博客的地址后加上“eWebEditor/admin_login.asp”即可打开eWebEditor后台在线编辑页面。输入默认的用户名和密码“admin”即可顺利登陆博客的后台管理页面。

    新添加一个博客样式,返回样式管理页面。在样式列表中找到刚才添加的样式,并点击样式名后的“设置”按钮,就可使用新的博客样式。

    退出管理页面后进行注册并登陆博客,然后发一篇帖子并选择上传文件,此时我们可以上传ASP木马以便控制整个服务器。

    漏洞二:文件上传漏洞

    第一步,搜索存在漏洞的博客

    找到任意一个目标后,首先要测试博客管理员是否将上传网页程序文件删除了,如果用户有一些安全意识,有可能会将默认的上传网页文件删除掉,这时就不行了。

    我们选“http://www.88888.net/workingbird” ,在地址后添加“/upfile.asp”后回车,如果看到的提示信息为“Microsoft VBScript运行时错误 错误‘800a01b6’”之类的信息,表示该博客网站存在着文件上传漏洞,详情您可以点击数据库安全软件他可以帮你解决所有的有的安全隐患。

    第二步,展开攻击

    运行“网站上传利用工具”,在“提交地址”中输入upfile.asp上传文件的所在地址,然后在“上传路径”中指定上传木马文件后的保存路径,我们一般将它保存在网站根目录下。“路径字段”和“文件字段”使用默认的设置就可以了,在“允许类型”中输入博客系统允许上传的图片类型。在“本地文件”后点击“浏览”选择本地的一个ASP木马,可以选择海洋顶端网木马。

    现在点击“提交”按钮,即可上传木马,如果看到信息“1 file had been uploaded!”,则表示文件上传成功。接下来,我们就可以连接上传后的ASP木马进一步渗透攻击,达到控制整个网站服务器的目的。

    漏洞三:SQL注入漏洞

    第一步,扫描博客中的注入漏洞

    以博客“http://202.112.*.***/dlog/”作为目标。可以使用工具(如NBSI 2 SQL自动注入攻击器)进行SQL注入。运行程序,点击工具栏中的“网站扫描”,在“网站地址”中输入博客网址,勾选“全面扫描”项,点击“扫描”后,就可以对博客网站中存在的所有注入漏洞进行扫描。

    第二步,开始攻击

    在扫描结果列表中任意选一个目标“http://202.112.*.***/dlog/showlog.asp?log_id=402”,然后点击界面下方的“注入分析”进入“注入攻击”页面。点击“检测”按钮,结果显示“赞为监测到注入漏洞”!

    不要紧,我们用1=1检测法。在注入浏览器地址栏中的末尾分别加上“and 1=1”和“and 2=2”,查看两者返回页面的信息中有什么不同。并记下在“and 1=1”页面中出现过,但是在“and 2=2”中未出现过的字符串,并将其输入NBSI 2界面的“特征字符串”。

    现在点击“再检测”,很快就可看到注入检测的结果。由于数据库是Access数据库,所以程序会自动猜解数据库中的表名和列名,点击窗口中的“自动猜解”,即可猜测可能存在的数据库表名,默认的表名为“user_mdb”。再利用自动猜解得到表中的列名等数据信息。然后自动猜解表中的用户数据,从而得到管理员的MD5加秘密码。最后使用MD5密码破解工具暴力破解,登陆后台管理页面,成功入侵。

    漏洞四:cookies欺骗漏洞

    第一步,搜索目标

    搜索关键词“Powered by L-Blog”,选择“http://***.*****.***/blog”作为攻击目标。

    第二步,查询cookies信息

    这里要用到一款可以修改cookies信息的工具。打开程序,输入博客网站的地址并登陆,查看当前的cookies信息,其中包含了我们的登陆用户名和密码等信息。

    第三步,“欺骗”攻击

    现在要对cookies信息进行修改,欺骗博客程序,使它以为登陆用户的身份是管理员。此时可直接对cookies信息进行修改。

    我们只修改“menStatus=SupAdmin”,其它内容保留,然后继续保持工具栏中的“锁”为按下状态。现在,退出当前的用户登陆状态,重新打开该博客首页。此时会显示我们没有登陆,然而我们已经拥有了管理员的权限。

    September 11

    一首《花沙》,

    记忆里的琥珀色仲夏
    藏著你我 多少年华
    曾在屋顶结下的誓言
    被风一吹就落下

    那些不分场合的情话
    拥抱之后 生根发芽
    奋不顾身 以为能到达

    夜深人静 反复纠缠的牵掛
    空荡的心 需要解答
    随风起舞的残花 不停追逐的黄沙
    多大代价 才能挣脱 思念的篱笆
    近在咫尺的天涯 在你的脚下
    沙守着花 花开的潇洒

    第一次听着这首歌,无所谓的视听。

    昨夜再一遍的仔细的听这首歌,原来反复纠缠的牵挂,心都空荡了。

    残花,黄沙,意境到了西风,瘦马的天下。

    在这个城市里,孤独的一个人排除着自己的不甘与压抑。

    呵呵,一切都消失了

          用笑容去面对

          人生不过如此

          哪怕失去生命

         我们也要学会一脸坦然

        

     

          如果真的在惜他

         就不会做让他伤心的事情

    September 10

    基地实施

    心情的低落,永远写在自己的脸上;

    无名的伤痛,狠狠的刺在自己心里;

    嘴上的不是,可是最明白的还是我们的心;

    不经意的流露的不耐烦,谁人都能看的明白;

    什么事情都有那么多理由推搡,可是

    反问我们自己的心,真的是那样吗?

    听着讲故事,也有一种心酸;

    因为自己不在故事里;

    就像一场角逐的爱情,

    自己不能参与,

    是多么的无奈。

            什么时候可以让爱情不自私?也许真的等到我的头像永远变灰了,心里就不会心酸了,

    因为心停止了跳动,脑袋停止了跳跃,人也开始在慢慢融化,直至消失在这个世界。

    生命当珍惜,一个生命一个世界。

    当一个世界消失的时候,真的希望能有个世界还残留着自己的印迹;

    命运注定的悲苦,也许必定要经历。

    不死不休。

    September 08

    伤感语句——最伤感的爱情语句


      你可以用一分钟遇见一个人用一小时了解一个人用一天爱上一个人但是你却要用一辈子忘记一个人

      有谁不曾为那暗恋而受苦?我们总以为那份痴情很重、很重,是世上最重的重量。有一天,募然回首,我们才发现,它一直都是很轻、很轻的。

      在遇到梦中人之前,上天也许会安排我们先遇到别人;在我们终于遇见心仪的人时,便应当心存感激。

      爱是一种感受,即使痛苦也会觉得幸福;爱是一种体会,即使心碎也会觉得甜蜜;爱是一种经历,即使破碎也会觉得美丽。爱上你只是一时,忘掉你需要一生。不管你是否还记得我,在你心里,永远有一滴我为爱你而流下的泪水,永远永远在那里…

      总是需要一些温暖。哪怕是一点点自以为是的纪念。不愿放开手不愿让你走不愿眼睁睁地看你走出我的生活。。。。

      在茫茫人海中,相遇,相知,相守,无论谁都不会一帆风顺,只有一颗舍得付出,懂得感恩的心,才能拥有一生的爱和幸福。
      想要说些什么,却无从说起,想要说声爱你却被风吹散。如果大海能换回曾经的爱我用一生等待

      每一个女孩都曾经是一个无泪的天使,当她遇上心爱的男孩时便有了泪,天使落泪,坠落人间,所以每一个男孩都不能辜负他的女孩,因为她曾经为了你,放弃了整个天堂。

      看见天空云朵厚重起伏,不可限量。曰光照耀不留余地。这种力量生生不熄。这仿佛在一场长眠之后,醒来时,嗅到新生的气息,感到洁净无比。可是一切不过一时,我们暗自承受,或者一世空虚,我们义无返顾。

      如果这是一场梦,就请让我永远不要再醒来。几乎所有童话的开端,都是从王子与公主,一场美丽的邂逅开始。我们一边埋怨著故事的俗套,一边心甘情愿的跳了下去,痴迷不可自拔。。

      当昨曰的梦已无法还原,当你再扶不起一丝记忆的幼苗,当你执意的步点踩痛我离别的视线,你知道我在等你吗?等你遗忘,等你不再回首从前一声坦诚的祝福,等你在我点亮所有的灯笼、满世界寻找又一个你时,你已化成一帘幽梦,轻轻地唤我!

      珍惜身边所有的一切事物!生活不是电影,错过了就是失去了、没有了,不可能像电影里一样有重新再来一次的机会,或许一次的错过就会让我们悔恨终身……

      初恋是美丽的。。。它的味道。。甜的。。酸的。。苦的。。涩的。。。。。。但不论它的味道如何。。。永远都是幸福的。。。。你是否想起了你的初恋了呢?。。。

      偶然认识他。偶然爱丄他。偶然幻想中拥有他。偶然失去他。偶然想恨他。偶然发现该恨他的魜不属于自己。。

      不知悲伤从何而来不得不爱,否则我就失去未来好象身不由己,不能自己很失败可是每天都过的精彩~~~━☆而是用你的心温暖我的手

      再多的困惑……再复杂的结果,一切都只不过是个选择——该忘记的,就让一切随风飘散;该珍惜的,就好好把握用心铭记;对别人好一点,也对自己好一点

      爱你的时候,未曾发觉;恨你的时候,才知道原来爱你那麽多!

      想说未说的无语,山盟海誓的词句,分别之际的泪滴,你都已忘记……但请告诉我,你能否忘记——那次朦朦胧胧的相遇,那个突然开始的忧郁……

      人,总是在不断地在舍取中矛盾中生活着。或许,有些感情只有错过了,才可以刻骨铭心,那些曾经的过往,在我们心里已是永恒。。。。。。

      尘世间最遥远的距离不是我站在你面前,却不知道我爱你;而是明明知道彼此相爱,却不能在一起。

      那不是彻夜等候你为我点的烛火,当我睁开双眼每一天,都会记得大家的笑脸,明白心中勇敢又多了一点,用音符画一个圈,经过都会被纪念,我想爱永远会留在你心间

      每个人都有属于自己的一片森林,也许我们从来没走过,但它一直在那里,迷失的人迷失了,相逢的人会再相逢。我相信美好的相遇,因为我们的生命是那样美丽生动。我们拥有的每一个遇见,都是上帝的垂爱。

      如果有如果,是否能回到曾经;如果有如果,我能不能再爱你一次;如果有如果,幸福是否依旧……但,一切的一切,只是如果……

      相识是最珍贵的缘份,思念是最美丽的心情,牵挂是最真挚的心动,问候是最动听的语言,知己是最贴心的默契。

      放弃一个人比爱一个人还要难,而要想彻底的忘掉他就会更难~!!!

      爱,永远是没有永恒的定义因为每个人的体会和感悟不同,爱很美,却也有褪去的时候,就如一场烟火,只留下短暂的美丽。。。在蓦然回首的刹那,没有怨恨的青春才会了无遗憾!擦肩而过,否则爱情会因为距离而成为一种传说!!!

      分手是必然的,因为我们不在一起了。以前我都脑子里都是你,但我现在却要忘记你。我不再想你,但你真的爱过我吗?我已把你忘记,我不再恋你,我的心里现在只有他,我以爱上他````

      比别人多一点或是少一点的都是幸福。曾经我们的思维和处世方式影响了我们对幸福的感知能力。幸福经不起你刻了一把尺子去量,它有一颗比磨难更敏感的心,稍对它挑剔,它就弃你而去。要获得幸福并不难—对他人,对自己,对生活宽容些,幸福就藏在你心里。

      盼望你没有为我又暗中淌泪,我不想让你的心空虚,盼望我别去后会与你在远方相聚,我的心如水,每一天望着远方,盼望你的突然出现,是缘是情是童真还是意外,多少春秋风雨也改变不了我对你的爱恋~~~~

      走得很急的都是最美的风景,伤得最最深的总是那些最最真的感情。我一直一直以为,自己可以承受这一天的到来,可当真面对,才知道自己也不过是个需要疼爱的女人。痴心的等待能唤回一个已经背叛的心吗?我只能用面具来遮掩自己的伤痛

      对的时间,遇见对的人,是一种幸福。对的时间,遇见错的人,是一种悲哀。错的时间,遇见对的人,是一声叹息。错的时间,遇见错的人,是一种无奈。

      回忆的画面记录的语言载着我的想念飞过了地平线你温暖的笑脸还一如从前回忆的画面记录的语言眼泪试我心中另一种完美

      想与你去画画用我们的心来画一幅属于我们的画不在乎它是酸是甜是苦是辣有你的时光那就是我的黄金时光不在乎它是否一生一世是否海枯石烂是否完美无暇是否炫眼夺人有你的曰子就是我最快乐的曰子

      面对你,我总是一笑而过;面对你,我总是默默无闻;面对你,我总是晕头转向;面对你,我总是费劲心思;面对你,我总是喋喋不休;面对你,我总是察言观色;面对你……

      回忆★是一种很奇妙☆的东西,它可以↑※让我想起曾经快乐的时光§,但它也让我&◆~~想起了许多伤心的往事

      是什么淋湿了我的眼睛,看不清你远去的背影,是什么冰冷了我的心情,握不住你从前的温馨,是雨声喧哗了我的安宁,听不清自己哭泣的声音,是雨伞美丽了城市的风景留不住身边匆忙的爱情,谁能用爱烘干我这颗潮湿的心。

      她哭了,泪水一滴一滴的落下。她失去了以往的阳光,失去了以往的蓝,天空不满阴霾,灰沉沉的一片,压仰着的心就犹如天空一般。她在轻声抽泣着,用泪水将心中的不愉快释放,阳光总在风雨后,振作吧。哭泣将成历史,新一页也已翻开。

      太多的爱,淹没了所有的恨,原来重情多感,会活得很凄楚;吸食了别人的悲伤,我在静默中缓缓地流泪....

      若有一种爱是永不能相见,永不能启口,永不能在想起,就好象永不燃起的火种,孤独的凝望着黑暗的天空,但总有一颗心需要讲明,需要倾诉,需要将爱进行到最后一刻,才不枉此生

      爱情只是一种物质,想爱就爱,想恨就恨~没什么多大的区别,每个人都拥有爱情~只是看个人的想象~

      -*渐渐餦汏钌。。 丶宥些亊看懂钌′。 宥些人吔看清钌~。ˊ。但只能仿进惢裏。*|:﹏失佉菂〃吥能喠涞。''''

      有有些失去是注定的,有些缘分是永远不会有结果的,爱一个人不一定要拥有,但拥有了一个人就一定要珍惜,不要等到伤害的时候才去乞求原谅,不要等到失去的时候再去挽回。如果我不小心流下一滴泪水,那是因为我不愿意忘记你是谁

    注定我只是你生命里的印记

    如那片雪,

    从天空翻转身姿舞动着灵魂,

    翩然落缤纷  一股清凉润喉的清爽;

    如那云儿,

    在朗朗的宇宙下变幻着梦想,

    碧蓝映白帆  一阵风清云淡的飘渺;

    如那阵雨,

    在苍苍莽莽郁郁葱葱的树林,

    牵手水精灵  轻轻呢喃着美丽的传说;

    如黑暗中的光亮,如那架子鼓的韵律

    注定,一切都会被你忽视

    对你来说,一切只是过眼云烟

    变冷了?

    一份感情能经的起多久的考验

    一份心情能持续多少未知的日子

    当走过了一个个坎坷的道路时

    我们的心是否在为了坎坷而变化

    也许,变化是渐进的

    也许,感情是曲折的,就像人生的路

    可是感情是否也可以像人生一样长久呢

    心潮澎湃的时候,你会因它的一举一动而开心

    可是某一天,你看到它的时候

    心情没有变化,脸上没有笑容

    是不是感情就淡了呢

    这个时候的它不能给你带来快乐

    这个时候的它,在你眼里,好像变了

    能给你快乐的是别人

    它为你做的一百件事

    你觉着已经无所谓了

    不如一个陌生的新认识的人

    能让你开心

    也许这个时候的你

    对它已经真的冷淡了

    甚至不如一条陌生人的短信

    让你感觉莫名的激动、兴奋

    感情当没有了拥抱

    没有了语言

    还能剩下什么呢

    也许是你的心真的冷了

    在你眼里,它不在像从前那样可以让你开心

    当心潮澎湃过后,我以为感情得到是沉淀

    更加的深,更加的厚,更加的浓

    却发现像此时的天气

    变冷了

    可是天冷了,可以加件衣服

    感情呢?

    再次游泰山

    去泰山的时候,穿件长袖,坐在公交车上,感觉到还有那么点热;上午十一点左右到达岱庙北门,看着北门,心里浮想联翩,此情此景依稀在,但已物是人非。去年在岱庙门口停滞的时候,还是原来单位的一帮同事们,一群不错的同事,一群可以做哥们的人,一群让我可以永远铭记在心的人,是在他们的热心帮助下,从一个毛毛楞楞的刚出校门的青涩男孩,快速的成长,无论是技术还是做人,都得到了充分的进步;那个时侯登泰山,逛岱庙,心无旁贷,心里想的是让自己玩的开心,过的舒服。

    今年走到岱庙门口的时候,心里突然有了心酸的感觉,身旁仍然是一帮不错的同事,但是物是人非的感觉却在心里蔓延。中午十二点左右,所有同事到达岱庙门口,吃饭,虽然也是在传说的岱庙后门的美食小吃聚集处,而且美其名曰的御膳楼,不适应的饭菜口味,人民币没少用,不太实惠;饭后,逛岱庙,选择近地,直接从北门进入了岱庙。可能是阴雨天太多,此时的岱庙满处可以见青苔,地略滑。

    晚上烧烤,呵呵,泰安东的云海烧烤城,在一家东北烧烤,无烟烧烤,呵呵,看到东北烧烤想到大学时吃的烧烤,特有感觉,于是就进入了这家店,还不错,特别是他们的涮肚、五花肉、马步鱼,做的挺有味,便宜实惠,比中午节约了接近一半,呵呵,吃的全是肉食。

    宾馆住宿,为了节约费用,七个男生,两间房子,呵呵,有点挤,晚上有五个人打扑克,保皇持续到凌晨一点。周天凌晨四点起床,准备行头,走向红门,开始攀登。从红门到中天门,一路基本无景色,除了烧香的地方比较多,其他无景色。不过对我来说,逢庙需拜。

    从中天门到南天门,路途景色较多,可见毛泽东的题词,数风流人物还看今朝,看到了迎客松。十八盘是比较艰辛的一段路,呵呵,艰辛是因为其位置太高,体力消耗已经够多了,而且其台阶又窄,走起来要小心翼翼,提心吊胆的,所以特别显累。我是汗水流下估计得有一小脸盘,到升仙坊的时候,我已经感觉有缺水的滋味。恶补水啊。

    南天门,天街,大雾天气,也没看到什么景色,最终去了玉皇顶,感觉太累,偶也没上去,在五岳独尊石处做了个看报人,狂吃咸花生。

    下山比较快,呵呵,因为上次来的时候学会了如何在台阶上跑着下,呵呵,那速度简直了。

    人生也许就是这么反复的,上次泰山回去以后,没想到会再次来到泰山。不过上次泰山的景色要比这次漂亮,看到了日出,看到了云海,这次么也没看着,呼呼腾腾跑了一圈。