欢迎来到【64读写驱动源码】【spring实现事物源码】【nginx源码怎么读】源码编译squash-皮皮网网站!!!

皮皮网

【64读写驱动源码】【spring实现事物源码】【nginx源码怎么读】源码编译squash-皮皮网 扫描左侧二维码访问本站手机端

【64读写驱动源码】【spring实现事物源码】【nginx源码怎么读】源码编译squash

2024-11-24 17:07:57 来源:{typename type="name"/} 分类:{typename type="name"/}

1.Github上如何合并多个Commit
2.animation和animator的区别
3.linux 服务器 如何进行安全检查?
4.android之animator 和animation 的区别
5.如何从NFS启动Linux及原理
6.如何组建一个无盘工作站,源码具体步骤

源码编译squash

Github上如何合并多个Commit

       åœ¨ä½¿ç”¨ Git 作为版本控制的时候,可能会由于各种各样的原因提交了许多临时的 commit,所以需要把多个Commit合并到一起,具体做法如下:

       1、首先假设已经有3个 commit

       2、需要将 2dfbc7e8 å’Œ c4eb5 åˆå¹¶æˆä¸€ä¸ª commit,那么只要输入如下命令:

       å…¶ä¸­ï¼Œ-i çš„参数是不需要合并的 commit 的 hash 值,这里指的是第一条 commit, 接着就进入到 vi çš„编辑模式

       3、可以看到其中分为两个部分,上方未注释的部分是填写要执行的指令,而下方注释的部分则是指令的提示说明。指令部分中由前方的命令名称、commit hash 和 commit message 组成。

       å½“前只要知道 pick å’Œ squash è¿™ä¸¤ä¸ªå‘½ä»¤å³å¯ã€‚

       pick çš„意思是要会执行这个 commit

       squash çš„意思是这个 commit 会被合并到前一个commit

       å°† c4eb5 è¿™ä¸ª commit 前方的命令改成 squash æˆ– s,然后输入:wq以保存并退出。

       4、这时会看到 commit message 的编辑界面

       å…¶ä¸­,编译 非注释部分就是两次的 commit message, 你要做的就是将这两个修改成新的 commit message。

       5、输入wq保存并推出, 再次输入git log查看 commit 历史信息,就会发现这两个 commit 已经合并了。

animation和animator的区别

       ä¸€ã€ 前言

       Animator框架是Android 4.0中新添加的一个动画框架,和之前的Animation框架相比,Animator可以进行更多和更精细化的动画控制,而且比之前更简单和更高效。在4.0源码中随处都可以看到Animator的使用。

       äºŒã€ Animation和Animator比较

       å¦‚下图,是Animation和Animator两个类继承图的对比。

       C:Object C:Object

        C:Animation C:Animator

        C:AlphaAnimation C:AnimatorSet

        C:AnimationSet C:ValueAnimator

        C:DummyAnimation C:ObjectAnimator

        C:Rotate3dAnimation C:TimeAnbimator

        C:RotateAniamtion

        C:ScaleAnimation

        C:TranslateAnimation

       Animation框架定义了透明度,旋转,缩放和位移几种常见的动画,而且控制的是一个整个View动画,实现原理是每次绘制视图时View所在的ViewGroup中的drawChild函数获取该View的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算完成动画帧,如果动画没有完成,继续调用invalidate()函数,启动下次绘制来驱动动画,动画过程中的帧之间间隙时间是绘制函数所消耗的时间,可能会导致动画消耗比较多的CPU资源。

       åœ¨Animator框架中使用最多的是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更精细化控制,只控制一个对象的一个属性值,多个ObjectAnimator组合到AnimatorSet形成一个动画。而且ObjectAnimator能够自动驱动,可以调用setFrameDelay(longframeDelay)设置动画帧之间的间隙时间,调整帧率,减少动画过程中频繁绘制界面,而在不影响动画效果的前提下减少CPU资源消耗。

       ä¸‰ã€ 关键接口介绍

       1. ObjectAnimator介绍

       Animator框架封装得比较完美,对外提供的接口非常简单,创建一个ObjectAnimator只需通过如下图所示的静态工厂类直接返回一个ObjectAnimator对象。传的参数包括一个对象和对象的属性名字,但这个属性必须有get和set函数,内部会通过java反射机制来调用set函数修改对象属性值。还包括属性的初始值,最终值,还可以调用setInterpolator设置曲线函数。

       2. AnimatorSet介绍

       AnimatorSet主要是组合多个AnimatorSet和ObjectAnimator形成一个动画,并可以控制动画的播放顺序,其中还有个辅助类通过调用play函数获得。

       3. AnimatorUpdateListner介绍

       é€šè¿‡å®žçŽ°AnimatorUpdateListner,来获得属性值发生变化时的事件,在这个回调中发起重绘屏幕事件。

       å››ã€ 使用实例

       åœ¨Android4.0中的ApiDemo中有个BouncingBalls实例,描述了Animator框架的使用,当点击屏幕时,绘制一个球从点击位置掉到屏幕底部,碰到底部时球有压扁的效果,然后回弹到点击位置再消失。

       ä»£ç å¦‚下:

       ShapeHolder newBall =addBall(event.getX(), event.getY());

        // Bouncing animation with squash and stretch

        float startY = newBall.getY();

        float endY = getHeight() - f;

        float h = (float)getHeight();

        float eventY = event.getY();

        int duration = (int)( * ((h - eventY)/h));

        ValueAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY);

        bounceAnim.setDuration(duration);

        bounceAnim.setInterpolator(new AccelerateInterpolator());

        ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x", newBall.getX(),

        newBall.getX() - f);

        squashAnim1.setDuration(duration/4);

        squashAnim1.setRepeatCount(1);

        squashAnim1.setRepeatMode(ValueAnimator.REVERSE);

        squashAnim1.setInterpolator(new DecelerateInterpolator());

        ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall, "width", newBall.getWidth(),

        newBall.getWidth() + );

        squashAnim2.setDuration(duration/4);

        squashAnim2.setRepeatCount(1);

        squashAnim2.setRepeatMode(ValueAnimator.REVERSE);

        squashAnim2.setInterpolator(new DecelerateInterpolator());

        ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(newBall, "y", endY,

        endY + f);

        stretchAnim1.setDuration(duration/4);

        stretchAnim1.setRepeatCount(1);

        stretchAnim1.setInterpolator(new DecelerateInterpolator());

        stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);

        ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(newBall, "height",

        newBall.getHeight(),newBall.getHeight() - );

        stretchAnim2.setDuration(duration/4);

        stretchAnim2.setRepeatCount(1);

        stretchAnim2.setInterpolator(new DecelerateInterpolator());

        stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);

        ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", endY,

        startY);

        bounceBackAnim.setDuration(duration);

        bounceBackAnim.setInterpolator(newDecelerateInterpolator());

        // Sequence the down/squash&stretch/upanimations

        AnimatorSet bouncer = new AnimatorSet();

        bouncer.play(bounceAnim).before(squashAnim1);

        bouncer.play(squashAnim1).with(squashAnim2);

        bouncer.play(squashAnim1).with(stretchAnim1);

        bouncer.play(squashAnim1).with(stretchAnim2);

        bouncer.play(bounceBackAnim).after(stretchAnim2);

        // Fading animation - remove the ball when theanimation is done

        ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);

        fadeAnim.setDuration();

        fadeAnim.addListener(new AnimatorListenerAdapter() {

        @Override

        public void onAnimationEnd(Animatoranimation) {

        balls.remove(((ObjectAnimator)animation).getTarget());

        }

        });

        // Sequence the two animations to play oneafter the other

        AnimatorSet animatorSet = new AnimatorSet();

        animatorSet.play(bouncer).before(fadeAnim);

        // Start the animation

        animatorSet.start();

linux 服务器 如何进行安全检查?

       众所周知,网络安全是源码一个非常重要的课题,而服务器是编译网络安全中最关键的环节。linux被认为是源码一个比较安全的Internet服务器,作为一种开放源代码操作系统,编译64读写驱动源码一旦linux系统中发现有安全漏洞,源码Internet上来自世界各地的编译志愿者会踊跃修补它。然而,源码系统管理员往往不能及时地得到信息并进行更正,编译这就给黑客以可乘之机。源码相对于这些系统本身的编译安全漏洞,更多的源码安全问题是由不当的配置造成的,可以通过适当的编译配置来防止。服务器上运行的源码服务越多,不当的配置出现的机会也就越多,出现安全问题的可能性就越大。对此,下面将介绍一些增强linux/Unix服务器系统安全性的知识。一、系统安全记录文件操作系统内部的记录文件是检测是否有网络入侵的重要线索。如果您的系统是直接连到Internet,您发现有很多人对您的系统做Telnet/FTP登录尝试,可以运行"#more/var/log/secure greprefused"来检查系统所受到的攻击,以便采取相应的对策,如使用SSH来替换Telnet/rlogin等。二、启动和登录安全性1#echo》/etc/issue然后,进行如下操作:#rm-f/etc/issue#rm-f/etc/issue三、限制网络访问1(ro,root_squash)/dir/to/exporthost2(ro,root_squash)/dir/to/export是您想输出的目录,host是spring实现事物源码登录这个目录的机器名,ro意味着mount成只读系统,root_squash禁止root写入该目录。为了使改动生效,运行如下命令。#/usr/sbin/exportfs-a2"表示允许IP地址允许通过SSH连接。配置完成后,可以用tcpdchk检查:#tcpdchktcpchk是TCP_Wrapper配置检查工具,它检查您的tcpwrapper配置并报告所有发现的潜在/存在的问题。3.登录终端设置/etc/securetty文件指定了允许root登录的tty设备,由/bin/login程序读取,其格式是一个被允许的名字列表,您可以编辑/etc/securetty且注释掉如下的行。#tty1#tty2#tty3#tty4#tty5#tty6这时,root仅可在tty1终端登录。4.避免显示系统和版本信息。如果您希望远程登录用户看不到系统和版本信息,可以通过一下操作改变/etc/inetd.conf文件:telnetstreamtcpnowaitroot/usr/sbin/tcpdin.telnetd-h加-h表示telnet不显示系统信息,而仅仅显示"login:"四、防止攻击1.阻止ping如果没人能ping通您的系统,安全性自然增加了。为此,可以在/etc/rc.d/rc.local文件中增加如下一行:

android之animator 和animation 的区别

       ä¸€ã€ 前言

       Animator框架是Android 4.0中新添加的一个动画框架,和之前的Animation框架相比,Animator可以进行更多和更精细化的动画控制,而且比之前更简单和更高效。在4.0源码中随处都可以看到Animator的使用。

       äºŒã€ Animation和Animator比较

       å¦‚下图,是Animation和Animator两个类继承图的对比。

       C:Object C:Object

        C:Animation C:Animator

        C:AlphaAnimation C:AnimatorSet

        C:AnimationSet C:ValueAnimator

        C:DummyAnimation C:ObjectAnimator

        C:Rotate3dAnimation C:TimeAnbimator

        C:RotateAniamtion

        C:ScaleAnimation

        C:TranslateAnimation

       Animation框架定义了透明度,旋转,缩放和位移几种常见的动画,而且控制的是一个整个View动画,实现原理是每次绘制视图时View所在的ViewGroup中的drawChild函数获取该View的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算完成动画帧,如果动画没有完成,继续调用invalidate()函数,启动下次绘制来驱动动画,动画过程中的帧之间间隙时间是绘制函数所消耗的时间,可能会导致动画消耗比较多的CPU资源。

       åœ¨Animator框架中使用最多的是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更精细化控制,只控制一个对象的一个属性值,多个ObjectAnimator组合到AnimatorSet形成一个动画。而且ObjectAnimator能够自动驱动,可以调用setFrameDelay(longframeDelay)设置动画帧之间的间隙时间,调整帧率,减少动画过程中频繁绘制界面,而在不影响动画效果的前提下减少CPU资源消耗。

       ä¸‰ã€ 关键接口介绍

       1. ObjectAnimator介绍

       Animator框架封装得比较完美,对外提供的接口非常简单,创建一个ObjectAnimator只需通过如下图所示的静态工厂类直接返回一个ObjectAnimator对象。传的参数包括一个对象和对象的属性名字,但这个属性必须有get和set函数,内部会通过java反射机制来调用set函数修改对象属性值。还包括属性的初始值,最终值,还可以调用setInterpolator设置曲线函数。

       2. AnimatorSet介绍

       AnimatorSet主要是组合多个AnimatorSet和ObjectAnimator形成一个动画,并可以控制动画的播放顺序,其中还有个辅助类通过调用play函数获得。

       3. AnimatorUpdateListner介绍

       é€šè¿‡å®žçŽ°AnimatorUpdateListner,来获得属性值发生变化时的事件,在这个回调中发起重绘屏幕事件。

       å››ã€ 使用实例

       åœ¨Android4.0中的ApiDemo中有个BouncingBalls实例,描述了Animator框架的使用,当点击屏幕时,绘制一个球从点击位置掉到屏幕底部,碰到底部时球有压扁的效果,然后回弹到点击位置再消失。

       ä»£ç å¦‚下:

       ShapeHolder newBall =addBall(event.getX(), event.getY());

        // Bouncing animation with squash and stretch

        float startY = newBall.getY();

        float endY = getHeight() - f;

        float h = (float)getHeight();

        float eventY = event.getY();

        int duration = (int)( * ((h - eventY)/h));

        ValueAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY);

        bounceAnim.setDuration(duration);

        bounceAnim.setInterpolator(new AccelerateInterpolator());

        ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x", newBall.getX(),

        newBall.getX() - f);

        squashAnim1.setDuration(duration/4);

        squashAnim1.setRepeatCount(1);

        squashAnim1.setRepeatMode(ValueAnimator.REVERSE);

        squashAnim1.setInterpolator(new DecelerateInterpolator());

        ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall, "width", newBall.getWidth(),

        newBall.getWidth() + );

        squashAnim2.setDuration(duration/4);

        squashAnim2.setRepeatCount(1);

        squashAnim2.setRepeatMode(ValueAnimator.REVERSE);

        squashAnim2.setInterpolator(new DecelerateInterpolator());

        ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(newBall, "y", endY,

        endY + f);

        stretchAnim1.setDuration(duration/4);

        stretchAnim1.setRepeatCount(1);

        stretchAnim1.setInterpolator(new DecelerateInterpolator());

        stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);

        ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(newBall, "height",

        newBall.getHeight(),newBall.getHeight() - );

        stretchAnim2.setDuration(duration/4);

        stretchAnim2.setRepeatCount(1);

        stretchAnim2.setInterpolator(new DecelerateInterpolator());

        stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);

        ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", endY,

        startY);

        bounceBackAnim.setDuration(duration);

        bounceBackAnim.setInterpolator(newDecelerateInterpolator());

        // Sequence the down/squash&stretch/upanimations

        AnimatorSet bouncer = new AnimatorSet();

        bouncer.play(bounceAnim).before(squashAnim1);

        bouncer.play(squashAnim1).with(squashAnim2);

        bouncer.play(squashAnim1).with(stretchAnim1);

        bouncer.play(squashAnim1).with(stretchAnim2);

        bouncer.play(bounceBackAnim).after(stretchAnim2);

        // Fading animation - remove the ball when theanimation is done

        ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);

        fadeAnim.setDuration();

        fadeAnim.addListener(new AnimatorListenerAdapter() {

        @Override

        public void onAnimationEnd(Animatoranimation) {

        balls.remove(((ObjectAnimator)animation).getTarget());

        }

        });

        // Sequence the two animations to play oneafter the other

        AnimatorSet animatorSet = new AnimatorSet();

        animatorSet.play(bouncer).before(fadeAnim);

        // Start the animation

        animatorSet.start();

如何从NFS启动Linux及原理

       é¦–先我们要明确我们所指的程序,是放在有目录级结构的文件系统里,为了寻找到所需要操作系统来运行的程序,我们必须告诉它,文件在哪个文件系统。一 般来说,PC机的文件就存储在硬盘上;对于Live CD而言,文件系统就藏在光盘上面。也就是说,只要操作系统能找到并正确地认识了文件系统,就可以执行里面的程序了!

       è®¾ç½®ç›®æ ‡æœºå™¨ä¸Šçš„NFS启动

       çœ‹å®Œäº†ç¬¬ä¸€èŠ‚,明白启动的过程了吗? 简单地说,就是内核加载 ,内核找到一个文件系统 ,内 核执行文件系统里的一个程序 。无论是从NFS启动,还是从硬盘启动,都是上述过程。只是NFS启动,其文件系统是放在网络上的。只要我 们告诉内核,具体放在什么地方,在网络的另一端我们设置好共享,自然可以从NFS启动。

       è®©å†…核识别NFS并可从NFS启动

       ç¼–译内核

       åœ¨å†…核源代码目录树下,配置内核:

       $make menuconfig

       ä¾æ¬¡è¿›å…¥ File Systems -> Network File System中选择 NFS client support 以及 Root file system on NFS。如果找不到Root file system on NFS 选项,要打开第一级菜单下的Networking support -> Networking options -> TCP/IP networking -> IP: kernel level autoconfiguration。如果NFS要使用DHCP,还得选上 IP: DHCP support。

       ä¿å­˜é…ç½®å¹¶é‡æ–°ç¼–译即可。

       é…ç½®å†…核参数

       è¿›å…¥ARM开发板的设置 linux_cmd_line的地方(mini则为开机按 s,输入linux_cmd_line,并带着引号输入参数),或者进入PC的GRUB,设置类似参数

       root=/dev/nfs rw nfsroot=..1.1:/linux ip=..1.5:::...0:linux::off

       è¯¥é…ç½®ä¸ºé™æ€IP设置。各参数意义如下:

       root=/dev/nfs :指定根文件系统为 /dev/nfs,即NFS 。这与/dev这个目录并没有什么关系,在此仅为一个名字。

       rw :根文件系统挂载为可读写。还可以有 ro 即只读的选项。

       nfsroot=..1.1:/linux :指明挂载哪一个NFS上的哪一个目录。这里指的是挂载IP 为..1.1的电脑上导出的/linux目录。

       ip=..1.5:::...0:linux::off :设置本机的IP。此举是为了 连接刚才设置的IP。这里是一个静态的配置,配置的格式为 ip=本机的IP地址::网关地址:网络掩码:本机的主机名:网络接口名:off 。一般情况下网关、网络接口名都不需要设置。如果是DHCP获取IP,那很简单,直接 ip=dhcp 即可。

       è®¾ç½®NFS服务器

       Ubuntu下看链接:/User/xiaoxiaopig/article/_1.htm

       NFS服务器可以是任意操作系统,只要能提供NFS服务即可(WINDOWS可以使用 WSU —— Windows Services for Unix来实现,具体请参考接下来本站要发表的文章)。在这里以Fedora为例,希望别的发行版的用户触类旁通。

       å¯¹äºŽFedora来说,有图形界面的工具进行设置,在管理-》服务器设置-》NFS中添加一个共享即可。

       æ›´é€šç”¨çš„作法,就是修改 /etc/exports文件,之后再启动NFS服务器。

       /etc/exports文件格式如下

       å¯¼å‡ºçš„文件夹 导出的网段(对该导出的网段的选项)

       æ‰€è°“导出的网段就是只向哪个网段导出,保证安全性。一个例子为:

       /linux ..1.0/(rw,sync,no_root_squash)

       å°±æ˜¯å°† /linux 导出到网段为..1.0,子网掩码为...0 (即)的网络。其中可用的选项为(翻译自man文档):

       secure和insecure : secure选项下,所有连接的端口均小于。默认打开。

       rw和ro : Read/Write和Read Only

       async和sync async将使用异步数据存取,数据并非马上写入服务器的。sync则相反。使用async需要注意服务器不能随意不正常地关闭,否则可能导致数据丢失。

       no_wdelay :不使用延迟写入。NFS服务器会将写入写入请求缓冲起来,可以提高性能。如果async已经打开那么该选项无效。

       no_subtree_check :不进行子树检查(使用该选项易引起安全问题)

       root_squash和no_root_squash、all_squash :root_squash选项使得客户端以root权限访问 文件系统时,转换为服务器端的匿名用户。这选项打开一定要设置好服务器的权限。

       ä¹‹åŽå†é‡æ–°å¯åŠ¨NFS服务。Fedora下使用 /etc/init.d/nfs restart

       ä½¿ç”¨ exports查看导出的文件。

如何组建一个无盘工作站,具体步骤

       无盘工作站构架指南2(5-)

        5、运行Win?无盘工作站

       你想用机运行Win吗?你想不买终端卡组建无盘Win网络吗?好了,请跟我来吧。根据本人长期的组网实践经验,总结出一套完整的无盘Win方案,给大家分享!

        首先说说大致工作原理:

        主要先通过Win远程无盘引导Win工作站,再利用Win终端服务和终端连网软件从无盘win中登陆到终端服务器上。

        请看以下具体步骤:

        一、硬件配置:

        1.服务器:建议CPU PIII 以上、nginx源码怎么读M内存,硬盘G以上(经济允许的话最好用SCSI)因为服务器是整个网络核心的核心,所以配置一定要好。

        2.工作站:低配置的,即可。笔者这里是奔腾,8M内存,无硬盘。

        二、安装步骤:

        1.首先把服务器装好Win Server,并配置好所有硬件。

        2.为window安装终端服务。

        打开控制面版---添加/删除程序---添加/删除Windows组件--选中Windows终端服务确定。安装时要放入Win光盘.

        3.在服务器上安装MetaFrame。Metaframe是citrix公司在Win下的终端服务器他比Win的终端服务更加强大,提供多种客户终端接入服务。

        4.安装好Metafrmae后,开始制作终端客户安装软盘.

        开始---程序---Metaframe tools---Ica client creator----Ica Client For win3x

        5.为Win添加远程启动服务。由于Win已经不在支持远程启动服务。因此,我们考虑将NT4的远程启动服务移植到Win中。可到凌心之 家(www.lingxin-home.com)或我的主页(networld.8u8.com)去下载远程服务安装工具。

        6.在Win下依次配一台Dos、win无盘站.方法与nt下一模一样,别告诉我你不会配置.不会的,以下就不用看了。

        7.以无盘win启动工作站,把第4步制作的终端客户盘安装在无盘站上。

        8.配置客户端。双击citrix图标,建立一个新连接,这里注意:要填好主机名(服务器名称),协议选择Netbios,的机构板块指标源码其它全部用他的默认就可以了。

        9.建立连接完成后,双击刚才建立的连接,就出现梦寐以求的Win桌面了。你可以运行任何在服务器的软件了!

       6、安装Linux无盘工作站

       [文章导读]

       其实Linux 对远程引导的支持非常好,Linnx内核自身又支持网络文件系统,因此非常适合做无盘工作站,本文将以一个实例向大家详细介绍无盘Linux工作站的安装办法。

       [正文]

       当年Novell下的无盘DOS工作站很是流行,后来又流行过Win无盘工作站,只是由于问题多多,后来微软自己停止了对无盘Windows的支持。随着Linux的日益流行,使用Linux的人越来越多,其实Linux 对远程引导的支持非常好,Linnx内核自身又支持网络文件系统,因此非常适合做无盘工作站,本文将以一个实例向大家详细介绍无盘Linux工作站的安装办法。

        这个网络是一个小的局域网,有1台服务器和4台 Linux 无盘工作站,彼此之间用双绞线通过HUB连接,服务器的IP地址定为..0. ,名字是server ,5台无盘工作站的地址由服务器动态分配,地址范围从 ..0.1 到..0.4 ,名字分别是c1,c2, c3,c4,服务器和无盘工作站使用的都是NE 兼容网卡,无盘工作站使用的linux 源码分析软件网卡上都安 装了BOOTROM 启动芯片,服务器操作系统安装的是 RedHat Linux 6.0 ,安装时选用定制安装,并安装了全部软件。

        Linux的远程引导有两种方式,一是利用Bootp协议,有一个专门的项目EtherBoot 提供支持( ( or Mbit)

        Other ISA cards

        NE/NE support (NEW)

        都设置为有效

       Filesystems 该项目下面的Network File Systems子项目下面的

        NFS filesystem support

        Root file system on NFS (NEW)

        都设置为有效

       以上设置完成后,退出内核编译设置程序,会出现一个对话框:Do you wish to save your new kernel configuration?

        然后执行 make dep && make bzImage 进行内核编译,这个过程得花一点时间,特别是如果计算机的速度不快的话,花的时间会更长一些。编译内核如果没有错误,会得到内核映象文件/usr/src/linux/arch/i/boot/bzImage ,将启动软盘插入计算机,执行下面的命令 mount -t vfat /dev/fd0 /mnt/floopy cp /usr/src/linux/arch/i/boot/bzImage /mnt/floppy umount /dev/fd0

        好了,启动盘上的文件都准备齐全了,等会儿用它到Win环境下制作启动映象。

       服务器设置

       服务器端需要运行nfsd、dhcpd、mars_new等几个服务进程,这些软件在ReHat Linux 发行套件里都有,如果在安装 Linux 的时候选择全部安装,这些软件都会随着安装操作 系统而装好了,下面对这些软件进行设置,注意,下面的操作要以 root 身份进行。

       1、 NFS 守护进程nfsd

       首先要建立几个供无盘工作站使用的目录,并通过nfsd 导出,命令如下:

       mkdir /tftpboot

       然后编辑文件 /etc/hosts ,加入下面的内容

       ..0. server server.domain

       ..0.1 c1 c1.domain

       ..0.2 c2 c2.domain

       ..0.3 c3 c3.domain

       ..0.4 c4 c4.domain

       第一台工作站的工作目录设置方法如下:

       mkdir /tftpboot/..0.1

       cd /tftpboot/..0.1

       cp -a /bin .

       cp -a /dev .

       mknod dev/nd0 b 0

       chmod dev/nd0

       cp -a /etc .

       cp -a /home .

       cp -a /lib .

       rm -rf lib/modules

       cp -a /root .

       cp -a /sbin .

       cp -a /var .

       mkdir proc

       mkdir usr

       mkdir tmp

       chmod tmp

       touch fastboot

       chattr +i fastboot

       cd etc

       编辑文件 sysconfig/network-scripts/ifcfg-eth0

       保留其中的

       DEVICE=eth0

       ONBOOT=yes

       其余的行全部删除,然后增加一行

       BOOTPROTO=dhcp

       编辑文件 rc.d/rc.sysinit ,在文件最后加上两行

       mount -t nfs server:/usr /usr

       /usr/XR6/bin/xfs

       编辑文件 fstab

       保留其中的

       none /proc proc defaults 0 0

       其余的行全部删除,然后增加一行

       server:/tftpboot/..0.1 / nfs defaults 1 1

       其它工作站的工作目录设置方法就简单多了

       cd /tftpboot

       cp -a ..0.1 ..0.2

       cp -a ..0.1 ..0.3

       cp -a ..0.1 ..0.4

       编辑文件 /etc/exports ,加入以下内容

       /usr (ro,no_root_squash)

       /tftpboot/..0.1 (rw,no_root_squash)

       /tftpboot/..0.2 (rw,no_root_squash)

       /tftpboot/..0.3 (rw,no_root_squash)

       /tftpboot/..0.4 (rw,no_root_squash)

       2、动态主机配置协议服务器 dpchd

       检查一下文件/etc/dhcpd.leases是否存在,若不存在就用命令touch /etc/dhcpd.leases 创建一个,然后编辑文件 /etc/dhcpd.conf ,加入以下内容

       subnet ..0.0 netmask ...0 {

       range ..0.1 ..0.4;

       }

       3、NetWare 模拟器 marsw_nwe

       编辑文件 /etc/nwserv.conf,找到下面的行

       # 4 0x eth0 .3 1

       将该行开头的'#'去掉,再找到

       4 0x0 * .3 1

       在该行开头加上'#'

       制作启动映象

       进入Win,将Win(早期的版本,可以用服务器安装方式安装)安装光盘的admin\nettools\netsetup\rplimage.exe 复制到硬盘,将启动软盘插入软驱,然后在纯MSDOS方式下执行 rplimage a: 就会得到启动映象 net$dos.sys,再将启动映象 net$dos.sys 复制到启动盘上(如果启动盘空间不够,可以先删除启动盘上的一些文件以留出空间)。

        启动 Linux 服务器,以 root 用户登录,将启动软盘插入软驱,执行下面的命令 mount -t vfat /dev/fd0 /mnt/floppy cp /mnt/floppy/net\$dos.sys /var/mars_nwe\sys\login umount /dev/fd0 然后执行 setup ,移动光棒至 System services 选项回车,出现 Services 设置画面,将dhcpd,nfs,mars-nwe 都设为有效,退出 setup 程序,执行以下的命令以启动上述服务进程:

       /etc/rc.d/rc3.d/*mars-nwe restart

       /etc/rc.d/rc3.d/*dhcpd restart

       /etc/rc.d/rc3.d/*nfs restart

        下一次再启动服务器时,上述服务进程会自动执行。

       至此,所有的设置工作全部完成了,联好网络随便打开一台无盘工作站,稍等一下,出现远程引导的信息,接着会启动 Win,接下来很快就会装载 Linux ,在一大堆 Linux 的启动信息之后如果看到 Linux 的登录提示,就说明远程启动成功了。

        Linux 无盘工作站虽然运转起来了,但还有一个问题,就是交换的问题,因为Linux 是一个支持虚拟存储的操作系统,当机器内存不够时,Linux 就会把内存中暂时不用的数 据换出到交换设备上,等需要时再换回来,刚才我们没有设置交换区,在无盘工作站上用 free 命令就会发现交换区为零,如果无盘工作站内存较大,运行一些不大的程序,没有交换区还是可以的,但若运行大型程序就会出问题,下面介绍在服务器上设置交换区即远 程交换的方法。

       对于2.1.版以前的内核,要实现远程交换可有点费事,得从网络上下载有关的补丁来修改内核代码,然后再编译内核映象。从2.1.版后的内核支持网络块设备,这样,实现远程交换就容易了。首先编译内核时要使 Network block device support 选项有效(刚才编译内核时就是这么作的),再从boot可供选用, etherboot对网卡型号有要求,支持的网卡种类不算很多,但对最常用的网卡如3c///b、NE//PCIne、Intel eepro等基本上都能支持;Netboot可以用ndis或pktdrv,这些文件一般在随卡附带的驱动盘上都有,但这仅限于网络启动,对网卡的要求首先是Linux能识别。

        以下步骤所述适用于etherboot;

        1. 展开etherboot,进入src-,编辑Config。有许多选项可以让你做多重启动、显示信息、询问口令之类的事情,这时你需要做的是用bootp代替dhcp,即在Config中定义-DNO_DHCP_SUPPORT设置。因为我们打算在服务器端用bootp,所以这是必须的,否则在启动时会因为未能寻找到dhcp server而启动不了。如果你准备在服务器端使用dhcp,那么这一步就不需要了。

        2. make。对每种网卡都会生成两个文件 .rom和 .lzrom,后者是压缩过的。

        3. 使用软盘启动验证所作的启动ROM没问题,假设你用的网卡是ne兼容的:

        cat ../src/floppyload.bin ne.lzrom > /dev/fd0

        如用软盘启动,系统能探测到你的网卡并发出bootp请求。如果一切OK,你就可以把ROM文件刻写到EPROM里了。

        4. cd ../netboot*;make;make install。make如果出错,解决办法是把系统中的bcc改名,然后将gcc连接成bcc,再重新make。最后在系统中会增加一个程序mknbi-linux,这是用来处理linux内核的,在服务器端设置部分会讲它的用法。

        客户端的工作完成了。

       二、服务器端:

        假设你的无盘工作站ip为.0.0.1; 机器名为dc1.subnet.net,另一台无盘工作站ip为.0.0.2,机器名为dc2.subnet.net, 服务器ip为.0.0.,名为server.subnet.net。

       1. 修改/etc/hosts,增加dc1.subnet.net,dc2.subnet.net

       2. 取得bootp-2.x.x,展开后注意把带的各种patch都打上。然后make; make install

       3. 建立/etc/bootptab,如下:

       global.prof:

       :sm=...0:

       :bf=/tftpboot/vmlinuz.nb:

       dc1:tc=global.prof:ha=cd7a:ip=.0.0.1:

       dc2:tc=global.prof:ha=e1:ip=.0.0.2:

       ha用无盘工作站网卡的MAC地址代替。

       4. 修改inetd.conf,去掉bootpd和tftpd的#号,如下:

       tftp dgram udp wait root /usr/sbin/tcpd tftpd –s /tftpboot

       bootps dgram udp wait root /usr/sbin/tcpd bootpd -i

       kill –HUP `cat /var/run/inetd.pif`

       5. 建立/tftpboot/.0.0.1,cd /tftpboot/.0.0.1,

       (cd /; tar cpf – lib sbin bin var etc dev)| tar xpf –

       mkdir usr; mkdir tmp; chmod tmp; mkdir home;mkdir root; makdir

       proc; mkdir mnt

       6. touch fastboot; chattr +i fastboot

       (fstab 中 / 和 /usr 的最后一项设成0,也许不需要这一步了,但我没试过)

       以下是一个shell script,可用于自动执行以上操作。

       #!/bin/sh

       if [ $# != 1 ]

       then

       echo Usage: $0 client-IP-addr

       exit 1

       fi

       cd /

       umask

       mkdir -p /tftpboot/$1

       # just make these ones

       for d in home mnt proc tmp usr

       do

       mkdir /tftpboot/$1/$d

       done

       chmod /tftpboot/$1/tmp

       touch /tftpboot/$1/fastboot

       chattr +i /tftpboot/$1/fastboot

       # copy these ones

       (cd /; tar cpf - bin lib sbin dev etc var) | (cd /tftpboot/$1; tar xpf -)

       7. 删除var下一切不需要的东西, 减小空间。删除lib/modules下一切不需要的模块。

       8. 修改etc/sysconfig/network,etc/sysconfig/network-scripts/ifcfg-eth0,

       etc/fstab,etc/conf.module

       fstab中指明root在服务器server上,like this

       server:/tftpboot/.0.0.1 / nfs default 0 0

       server:/usr /usr nfs default 0 0

       9. 配置etc/rc.d/rc3.d,关掉一切不需要的网络服务。

       . 删除etc/rc.d/rc6.d/K?network。

       . 修改etc/rc.d/rc.sysinit,寻找“mount –a –t nonfs,smbfs…"改成

       “mount.–a –t nosmbfs…"

       . mkdir /tftpboot/.0.0.2; cd /tftpboot/.0.0.2;

       . 修改etc/sysconfig/network,etc/sysconfig/network-scripts/ifcfg-eth0,

       etc/fstab,etc/conf.module

       . cd /etc; vi exports;

       /usr dc*.subnet.net(ro)

       /tftpboot/.0.0.1 dc1.subnet.net(rw,no_root_squash)

       /tftpboot/.0.0.2 dc2.subnet.net(rw,no_root_squash)

       exportfs –a

       . 编译一个新内核,必须包含以下特性:

       NFS filesystem 支持

       Root on NFS 支持

       Bootp 支持

       无盘工作站所用的网卡型号支持

       编译出新内核之后,用mknbi-linux处理,

       mknbi-linux bzImage vmlinuz.nb

       将vmlinuz.nb放在/tftpboot下即可。

       至此,服务器端的工作就完成了。

        注意事项:

        1. 如果你打算在服务器端用dhcp,需要自己配置,参看dhcp的文档。

        2. Rh6.1自带一个bootparamd,也应该能完成同样的工作,但在manual中语焉不详,不知该如何设置。

        3. 服务器端 / 和 /usr 最好单独分区。

        4. etherboot的文档上说对有些网卡比如PCI NE兼容网卡,可能需要调整Makefile中的vendor信息和ID信息,我还未试过。

        启动你的无盘工作站,如一切操作无误的话,工作站则应该能启动起来。启动过程中如果有一些地方不顺利,可以在启动之后对无盘工作站上按一般方法进行设置。

        希望以上的讲述能给读者有所帮助和启迪!

       8、Linux无盘工作站架设实例

        后面还有实例你自己看吧!