| 凡东 さんのプロフィール凡东的共享空间フォトブログつながり | ヘルプ |
|
|
10月21日 Java中的观察者模式(Observer)观察者模式理解为就是一个对象发生某种变化时,它的观察者做出相应的动作。观察者和被观察的对象之前建立关系。
Java作为一种面向对象的开发语言,对实现设计模式提供了良好的支持,并且提供了许多默认的实现,比如:通过Java中的Observable类和Observer接口可以方便的实现观察者模式。 下面我们就用一个实际的例子来说明:日常生活中说起观察者,最常见的例子可能就是天气预报,在这里我们的观察对象是地球,而我们是通过发射气象卫星这个观察者来检测地球气象变化的。 所以这个例子中涉及三个对象: 地球 (Earth): 被观察对象 气象卫星(Satellite): 观察者 气象局(WeatherService): 客户端调用 被观察对象:地球 (Earth) import java.util.Observable; /** */ /** * 被观察对象:地球 * * @author zjun * @version 1.0 create on 2006-5-18 9:42:45 */ public class Earth extends Observable { private String weather = " 晴朗 " ; /** */ /** * @return Returns the weather. */ public String getWeather() { return weather; } /** */ /** * @param weather * The weather to set. */ public void setWeather(String weather) { this .weather = weather; // 设置变化点 setChanged(); notifyObservers(weather); } } [注意] 在需检测的对象前需要设置变化点setChanged()和通知观察者notifyObservers(),这两个函数是由Observable类实现的,封装了观察者模式实现的细节。 观察者:气象卫星(Satellite) import java.util.Observable; import java.util.Observer; /** */ /** * 观察对象:气象卫星 * * @author zjun * @version 1.0 create on 2006-5-18 9:46:30 */ public class Satellite implements Observer { private String weather; public void update(Observable obj, Object arg) { weather = (String) arg; // 捕获天气变化情况,反馈给检测者 System.out.println( " 近期天气变化: " + weather); } } 客户端调用:气象局(WeatherService) /** */ /** * 客户端调用:天气预报 * * @author zjun * @version 1.0 create on 2006-5-18 9:57:19 */ public class WeatherService { /** */ /** * @param args */ public static void main(String[] args) { Earth earth = new Earth(); Satellite satellite = new Satellite(); // 发射气象卫星 earth.addObserver(satellite); System.out.println( " 天气预报: " ); System.out.println( " ------------ " ); earth.setWeather( " 台风‘珍珠’逼近 " ); earth.setWeather( " 大到暴雨 " ); earth.setWeather( " 天气炎热 " ); } } [运行结果] 天气预报: ------------ 近期天气变化:台风‘珍珠’逼近 近期天气变化:大到暴雨 近期天气变化:天气炎热 10月20日 使用Ubuntu搭建Web服务器(PHP)
http://www.linuxidc.com/Linux/2008-07/14178p2.htm(zhuanzai) Apache 是一种功能强大的Web服务器。如今,Internet上无数运行在Linux上的Apache服务器正为Web世界的日益繁荣提供着有力的支撑。本文将向读者介绍如何在Ubuntu Linux系统迅速搭建Apache Web服务器。 尽管Ubuntu 是一种新兴的Linux分支,但Ubuntu 组织却为Apache提供了丰富的支持软件,这些软件都可以从发行版的光盘获取,也可以从官方站点轻松下载。所以,Ubuntu非常适合作为Web服务器的平台。 一、 安装Apache 下面,我们首先介绍如何安装Apache。具体安装命令如下所示: $ sudo apt-get install apache2 然后运行Apache,命令如下所示: $ sudo /etc/init.d/apache2 restart Apache在安装期间将会新建一个目录:/var/www,该目录是该服务器中存放文档的根目录。只要在浏览器的地址栏输入 http://localhost/ 或机器的IP地址就能访问放置在此目录中的所有文档。 二、 安装PHP PHP是一种流行的服务器端脚本语言,一般与MySQL或 Postgres结合起来用于管理Web内容、blog和论坛。下面介绍其安装方法,其实它的安装也很简单,命令如下所示: $ sudo apt-get install libapache2-mod-php5 重新启动 Apache 以加载上面安装的模块: $ sudo /etc/init.d/apache2 restart 为了验证PHP模块是否正确加载,我们可以建立一个PHP文件,然后尝试通过Web服务器访问该文件。此外,我们知道PHP内建了一个phpinfo函数,该函数能够给出它的环境的详细信息。所以我们还可以利用下面的命令来检查PHP的工作情况: sudo sh -c "echo '' > /var/www/info.php" 之后,在浏览器地址栏键入http://localhost/info.php,然后回车,这时应该能看到一个颜面,给出刚才安装的PHP的详细信息。需要注意的是,如果在此过程中浏览器不显示页面,而是提示你下载文件,这就说明 Apache没有正确加载PHP模块。解决问题的办法是,在/etc/apache2/apache2.conf 或 /etc/apache2/mods-enabled/php5.conf文件中加入下面一行命令: AddType application/x-httpd-php .php .phtml .php3 加入上面的命令行后,为了保证Apache重新读取配置文件关闭,我们可以通过下面的命令将其关闭,然后再加以启动: $ sudo /etc/init.d/apache2 stop $ sudo /etc/init.d/apache2 start 三、配置动态虚拟主机 一般情况下,我们会在Web服务器上寄放多个Web站点,并且每个站点都有它自己的虚拟服务器。对于Apache来说,它同时支持基于名称的虚拟服务器和基于IP的服务器。 对于基于IP的虚拟服务器,每个站点都具有一个单独的IP地址,这样的缺点是使用太多的IP地址,但如今IPv4的地址已有枯竭的迹象,所以不提倡使用,通常在要求使用SSL 时才使用。 对于基于名称的虚拟服务器,多个Web站点共享一个IP地址。在这种情况下,通常根据HTTP请求头部来决定将其发给哪一个站点。为此,我们需要为每个虚拟服务器分别建立一个配置,给作为Web站点的根的目录以及主机命名。但是,如果这样的话我们每当添加一个新的虚拟服务器时,就要修改 Apache的配置并重新启动,这的确很烦人呢! 值得高兴的是,如果使用动态虚拟主机技术的话,可以随时加入虚拟主机时而不必重新配置或启动Apache。该技术要用到一个模块,称为vhost_alias。我们可以通过在Apache2已启用的模块目录中建立一个符号链接来启用该模块,命令如下所示: $ sudo ln -s /etc/apache2/mods-available/vhost_alias.load /etc/apache2/mods-enabled/vhost_alias.load 要想使vhost_alias正常工作,我们还需要修改/etc/apache2/apache2.conf 来关闭常规名称(canonical names),修改日志文件的配置,并为我们的虚拟主机规定存放位置。下面是一个实例: #从"Host:"头中取得主机名 UseCanonicalName Off # 这种日志格式可以从第一个字段中提取出主机名 LogFormat "%V %h %l %u %t "%r" %s %b" vcommon CustomLog /var/log/apache2/access_log vcommon # 在返回请求的文件名路径中包含主机名 VirtualDocumentRoot /var/www/vhosts/%0/web VirtualScriptAlias /var/www/vhosts/%0/cgi-bin 接下来,创建存放虚拟主机的目录,命令如下: $ sudo mkdir /var/www/vhosts 新建一个基干虚拟服务器,命令如下所示: $ sudo mkdir -p /var/www/vhosts/skeleton/cgi-bin $ sudo cp -a /var/www/apache2-default /var/www/vhosts/skeleton/web 重新启动apache2,使得上面的配置生效,方法如下所示: $ sudo /etc/init.d/apache2 restart 好了,现在我们可以建立基于名称的虚拟主机了。方法是将基干拷贝到要响应的主机名。举例来说,要想为www.Linuxidc.com新建一个虚拟服务器的话,只要运行下面的命令就行了: $ sudo cp -a /var/www/vhosts/skeleton /var/www/vhosts/ www. Linuxidc.com 现在,所有到达你的Apache服务器的HTTP连接中,只要其“Host:”头部被设成 www. Linuxidc.com,那么将由对应的虚拟服务器来响应。 为了早些看到我们的劳动成果,可以在本地进行测试。为此编辑/etc/hosts,加入下面一项: 127.0.0.1 www. Linuxidc.com 这样,在本机上就能访问该站点了。但是,为了让所有用户都能访问虚拟主机,还需申请域名,并且我们还需要在公共DNS服务器上进行设置。 web服务器WEB服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务。
Web服务器是指驻留于因特网上某种类型计算机的程序。当Web浏览器(客户端)连到服务器上并请求文件时,服务器将处理该请求并将文件发送到该浏览器上,附带的信息会告诉浏览器如何查看该文件(即文件类型)。服务器使用HTTP(超文本传输协议)进行信息交流,这就是人们常把它们称为HTTPD服务器的原因。
APACHE
apache仍然是世界上用的最多的Web服务器,市场占有率达60%左右。它源于 NCSAhttpd服务器,当NCSA WWW服务器项目停止后,那些使用NCSA WWW服务器的人们开始交换用于此服务器的补丁,这也是apache名称的由来(pache 补丁)。世界上很多著名的网站都是Apache的产物,它的成功之处主要在于它的源代码开放、有一支开放的开发队伍、支持跨平台的应用(可以运行在几乎所有的Unix、Windows、Linux系统平台上)以及它的可移植性等方面。 Tomcat Tomcat是一个开放源代码、运行servlet和JSP Web应用软件的基于Java的Web应用软件容器。Tomcat Server是根据servlet和JSP规范进行执行的,因此我们就可以说Tomcat Server也实行了Apache-Jakarta规范且比绝大多数商业应用软件服务器要好。 Tomcat是Java Servlet 2.2和JavaServer Pages 1.1技术的标准实现,是基于Apache许可证下开发的自由软件。Tomcat是完全重写的Servlet API 2.2和JSP 1.1兼容的Servlet/JSP容器。Tomcat使用了JServ的一些代码,特别是Apache服务适配器。随着Catalina Servlet引擎的出现,Tomcat第四版号的性能得到提升,使得它成为一个值得考虑的Servlet/JSP容器,因此目前许多WEB服务器都是采用Tomcat。 10月18日 制作交叉编译链 前段时间研究uboot的修改,只是关注了大概框架的修改,当时下载的uboot1.2.0,交叉编译链也是下载的现成的,cross-2.95.3,当时就是编译不过去。这种标准的文件没有进行修改过编译出问题很奇怪,在网上找到了一些信息,这个交叉编译链只支持到uboot1.1.4。于是又下载了uboot1.1.4,编译成功,很兴奋阿。
交叉工具链下载地址: ftp://ftp.arm.linux.org.uk/pub/linux/arm/toolchain/ 后来在移植内核时发现高版本的内核中已经加入了对s3c2440的支持,所以决定采用高版本的内核2.6,同时uboot决定采用1.2.0。按照上次的思路下载了最新的cross-3.2,居然编译不了,连1.1.4都编译不了。这种情况只能归咎于版本问题。这种现成的交叉编译链有一定的局限性,比如它采用的gcc是哪个版本, 是否能编译我需要的内核和uboot? 交叉编译链是需要根据自己的情况制作的。 幸好有crosstool这个工具。省去了一步一步制作的麻烦。 http://kegel.com/crosstool/ 下载crosstool-0.43.tar.gz,解压。 我的linux为redhat 9。 硬件平台为arm9,s3c2440 首先下载制作交叉编译链所需的文件,地址:ftp.gnu.org binutils-2.15.tar.bz2 gdb-6.5.tar.bz2 gcc-4.1.0.tar.bz2 gcc-3.3.6.tar.gz glibc-linuxthreads-2.3.2.tar.gz glibc-2.3.2.tar.gz linux-libc-headers-2.6.12.0.tar.bz2 linux-2.6.10.tar.gz 将这些文件存放在$HOME的downloads目录下,不用解压。 进入crosstool-0.43目录中,执行cp demo-arm.sh arm.sh 复制一个模板进行修改。 执行vi arm.sh进行编辑 #!/bin/sh
# This script has one line for each known working toolchain # for this architecture. Uncomment the one you want. # Generated by generate-demo.pl from buildlogs/all.dats.txt set -ex
TARBALLS_DIR=$HOME/downloads //制作交叉编译所需文件的存放位置! RESULT_TOP=/opt/crosstool //生成的交叉编译链的存放地址,注意你是否对该文件有写权限 export TARBALLS_DIR RESULT_TOP GCC_LANGUAGES="c,c++" //生成的工具链支持的语言的种类! export GCC_LANGUAGES # Really, you should do the mkdir before running this,
# and chown /opt/crosstool to yourself so you don't need to run as root. mkdir -p $RESULT_TOP #eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.2.5.dat` sh all.sh --notest
#eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.3.2.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.3.2-tls.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.3.6-glibc-2.2.5.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.3.6-glibc-2.3.2.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.3.6-glibc-2.3.2-tls.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.2.5.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.2.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.2-tls.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.5.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.5-tls.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.6-tls.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.2.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.2-tls.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.5.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.5-tls.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.6.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.6-tls.dat` sh all.sh --notest #eval `cat arm9tdmi.dat gcc-4.1.0-glibc-2.3.2.dat` sh all.sh --notest eval `cat arm9tdmi.dat gcc-4.1.0-glibc-2.3.2-tls.dat` sh all.sh --notest//这块根据需要我选择了高版本的gcc-4.1.0 echo Done. //上面表示你要选工具链的版本号!"#"起注释功能!我们可以选择一行!
打开crosstool-0.43目录下的arm.dat文件,内容如下:
KERNELCONFIG=`pwd`/arm.config
TARGET=arm-linux-gnu TARGET_CFLAGS="-O" 这里TARGET=需要根据自己的情况修改一下,比如目前为arm-linux-gnu那么最终编译完成后我的gcc为
arm-linux-gnu-gcc。 打开crosstool-0.43目录下的gcc-4.1.0-glibc-2.3.2-tls.dat文件,内容如下:
BINUTILS_DIR=binutils-2.15
GCC_COR_DIR=gcc-3.3.6 GCC_DIR=gcc-4.1.0 GLIBC_DIR=glibc-2.3.2 LINUX_DIR=linux-2.6.10 LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0 GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2 GDB_DIR=gdb-6.5 GLIBC_EXTRA_CONFIG="$GLIBC_EXTRA_CONFIG --with-tls --with-__thread --enable-kernel=2.4.18" 注意:这里边的几个版本的文件必须在$HOME/downloads文件夹下有。
到这里就设置完了。
到crosstool-0.43目录下执行./arm.sh经过大概1小时就OK了,然后设置环境变量。 PATH=/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-linux-gnu/bin:$PATH 具体设置方法可参考linux应用中的环境变量及设置。 9月27日 nand flash nor flash (转载)
8月21日 Linux操作系统下硬盘挂载方法新手学堂:Linux操作系统下硬盘挂载方法挂载Windows分区
A盘: mount /dev/fd0 /mnt/floppy
7月18日 关于服务器 (转载)在这个全民上网的时代,对于个人电脑的了解与使用,大多数的人都能够说出个大致,但是对于处于网络应用核心的服务器,大部分人的第一感觉还是比较神秘。那么到底什么是服务器呢? 什么是服务器? 从理论定义来看,服务器是网络环境中的高性能计算机,它侦听网络上其它计算机(客户机)提交的服务请求,并提供相应的服务。为此,服务器必须具有承担服务并且保障服务质量的能力。 但是这样来解释仍然显得较为深奥模糊,其实服务器与个人电脑的功能相类似,均是帮助人类处理信息的工具,只是二者的定位不同,个人电脑(简称为 Personal Computer,PC)是为满足个人的多功能需要而设计的,而服务器是为满足众多用户同时在其上处理数据而设计的。而多人如何同时使用同一台服务器呢? 这只能通过网络互联,来帮助达到这一共同使用的目的。 我们再来看服务器的功能,服务器可以用来搭建网页服务(我们平常上网所看到的网页页面的数据就是存储在服务器上供人访问的)、邮件服务(我们发 的所有电子邮件都需要经过服务器的处理、发送与接收)、文件共享&打印共享服务、数据库服务等。而这所有的应用都有一个共同的特点,他们面向的都 不是一个人,而是众多的人,同时处理的是众多的数据。所以服务器与网络是密不可分的,可以说离开了网络,就没有服务器;服务器是为提供服务而生,只有在网 络环境下它才有存在的价值。而个人电脑完全可以在单机的情况下完成主人的数据处理任务。
图1.网络应用中的服务器 服务器的硬件构成: 其实说起来服务器系统的硬件构成与我们平常所接触的电脑有众多的相似之处,主要的硬件构成仍然包含如下几个主要部分:中央处理器、内存、芯片组、I/O总线、I/O设备、电源、机箱和相关软件。这也成了我们选购一台服务器时所主要关注的指标。 整个服务器系统就像一个人,处理器就是服务器的大脑,而各种总线就像是分布与全身肌肉中的神经,芯片组就像是脊髓,而I/O设备就像是通过神经系统支配的人的手、眼睛、耳朵和嘴;而电源系统就像是血液循环系统,它将能量输送到身体的所有地方。
图2.服务器硬件组成直观图 对于一台服务器来讲,服务器的性能设计目标是如何平衡各部分的性能,使整个系统的性能达到最优。如果一台服务器有每秒处理1000个服务请求的能力,但网卡只能接受200个请求,而硬盘只能负担150个,而各种总线的负载能力仅能承担100个请求的话,那这台服务器得处理能力只能是100个请求/秒,有超过80%的处理器计算能力浪费了。 所以设计一个好服务器的最终目的就是通过平衡各方面的性能,使得各部分配合得当,并能够充分发挥能力。我们可以从这几个方面来衡量服务器是否达到了其设计 目的:R:Reliability——可靠性;A:Availability——可用性;S:Scalability——可扩展性;U: Usability——易用性; M:Manageability——可管理性,即服务器的RASUM衡量标准。 由于服务器在网络中提供服务,那么这个服务的质量对承担多种应用的网络计算环境是非常重要的,承担这个服务的计算机硬件必须有能力保障服务质 量。这个服务首先要有一定的容量,能响应单位时间内合理数量的服务器请求,同时这个服务对单个服务请求的响应时间要尽量快,还有这个服务要在要求的时间范 围内一直存在。 如果一个WEB服务器只能在1分钟里处理1个主页请求,1个以外的其他请求必须排队等待,而这一个请求必须要3分钟才能处理完,同时这个WEB服务器在1 个小时以前可以访问到,但一个小时以后却连接不上了,这种WEB服务器在现在的Internet计算环境里是无法想象的。 现在的WEB服务器必须能够同时处理上千个访问,同时每个访问的响应时间要短,而且这个WEB服务器不能停机,否则这个WEB服务器就会造成访问用户的流失。 为达到上面的要求,作为服务器硬件必须具备如下的特点:性能,使服务器能够在单位时间内处理相当数量的服务器请求并保证每个服务的响应时间;可 靠性,使得服务器能够不停机;可扩展性,使服务器能够随着用户数量的增加不断提升性能。因此我们说不能把一台普通的PC作为服务器来使用,因为,PC远远 达不到上面的要求。这样我们在服务器的概念上又加上一点就是服务器必须具有承担服务并保障服务质量的能力。这也是区别低价服务器和PC的差异的主要方面。 在信息系统中,服务器主要应用于数据库和Web服务,而PC主要应用于桌面计算和网络终端,设计根本出发点的差异决定了服务器应该具备比PC更可靠的持续 运行能力、更强大的存储能力和网络通信能力、更快捷的故障恢复功能和更广阔的扩展空间,同时,对数据相当敏感的应用还要求服务器提供数据备份功能。而PC 机在设计上则更加重视人机接口的易用性、图像和3D处理能力及其他多媒体性能。
图3.服务器系统架构图 7月13日 转载 什么是堆栈溢出堆栈这个问题是这么引出的。 在农业信息监控那个项目中,采用了stc89c58rd+这个芯片,片外没有ram,当我定义了uchar xdata a[3000],程序不正常执行,后来修改了内存模式改为compact模式,可以了,在网上查了下,说是堆栈溢出的问题。为什么在large模式下会产生了堆栈溢出呢? 从物理上讲,堆栈是就是一段连续分配的内存空间。在一个程序中,会声明各种变量。静态全局变量是位于数据段并且在程序开始运行的时候被加载。而程序的动态的局部变量则分配在堆栈里面。 从操作上来讲,堆栈是一个先入后出的队列。他的生长方向与内存的生长方向正好相反。我们规定内存的生长方向为向上,则栈的生长方向为向下。压栈的操作push=ESP-4,出栈的操作是pop=ESP+4.换句话说,堆栈中老的值,其内存地址,反而比新的值要大。请牢牢记住这一点,因为这是堆栈溢出的基本理论依据。 在一次函数调用中,堆栈中将被依次压入:参数,返回地址,EBP。如果函数有局部变量,接下来,就在堆栈中开辟相应的空间以构造变量。函数执行结束,这些局部变量的内容将被丢失。但是不被清除。在函数返回的时候,弹出EBP,恢复堆栈到函数调用的地址,弹出返回地址到EIP以继续执行程序。 在C语言程序中,参数的压栈顺序是反向的。比如func(a,b,c)。在参数入栈的时候,是:先压c,再压b,最后压a.在取参数的时候,由于栈的先入后出,先取栈顶的a,再取b,最后取c。(PS:如果你看不懂上面这段概述,请你去看以看关于堆栈的书籍,一般的汇编语言书籍都会详细的讨论堆栈,必须弄懂它,你才能进行下面的学习) 好了,继续,让我们来看一看什么是堆栈溢出。 运行时的堆栈分配 堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界。结果覆盖了老的堆栈数据。 比如有下面一段程序: 编译并且执行,我们输入ipxodi,就会输出Hello,ipxodi!。程序运行中,堆栈是怎么操作的呢?在main函数开始运行的时候,堆栈里面将被依次放入返回地址,EBP。我们用gcc -S 来获得汇编语言输出,可以看到main函数的开头部分对应如下语句: pushl %ebp 首先他把EBP保存下来,,然后EBP等于现在的ESP,这样EBP就可以用来访问本函数的局部变量。之后ESP减8,就是堆栈向上增长8个字节,用来存放name[]数组。现在堆栈的布局如下: 内存底部 内存顶部 执行完gets(name)之后,堆栈如下: 内存底部 内存顶部 最后,main返回,弹出ret里的地址,赋值给EIP,CPU继续执行EIP所指向的指令。 堆栈溢出 好,看起来一切顺利。我们再执行一次,输入ipxodiAAAAAAAAAAAAAAA,执行完 内存底部 内存顶部 由于我们输入的name字符串太长,name数组容纳不下,只好向内存顶部继续写‘A’。由于堆栈的生长方向与内存的生长方向相反,这些‘A’覆盖了堆栈的老的元素。如图我们可以发现,EBP,ret都已经被‘A’覆盖了。在main返回的时候,就会把‘AAAA’的ASCII码:0x41414141作为返回地址,CPU会试图执行0x41414141处的指令,结果出现错误。这就是一次堆栈溢出。 在上面的例子中,这导致CPU去访问一个不存在的指令,结果出错。事实上,当堆栈溢出的时候,我们已经完全的控制了这个程序下一步的动作。如果我们用一个实际存在指令地址来覆盖这个返回地址,CPU就会转而执行我们的指令。 在UINX系统中,我们的指令可以执行一个shell,这个shell将获得和被我们堆栈溢出的程序相同的权限。如果这个程序是setuid的,那么我们就可以获得root shell。 7月11日 BSP 概念解析 (转载)
有的文章中把对各种处理器寄存器的操作和器件的驱动统称为bsp,所以很多提到与处理器有关。
下面是转载
Drew在这里按照自己的理解来解释一下BSP( Board Support Package),仅供参考: BSP是板级支持包,是介于主板硬件和操作系统之间的一层,应该说是属于操作系统的一部分,主要目的是为了支持操作系统,使之能够更好的运行于硬件主板。 BSP是相对于操作系统而言的,不同的操作系统对应于不同定义形式的BSP,例如VxWorks的BSP和Linux的BSP相对于某一CPU来说尽管实现的功能一样,可是写法和接口定义是完全不同的,所以写BSP一定要按照该系统BSP的定义形式来写(BSP的编程过程大多数是在某一个成型的BSP模板上进行修改)。这样才能与上层OS保持正确的接口,良好的支持上层OS。 例如:
纯粹的BSP所包含的内容一般说来是和系统有关的驱动和程序,如网络驱动和系统中网络协议有关,串口驱动和系统下载调试有关等等。离开这些驱动系统就不能正常工作。 Tornado中BSP的编译和上层应用程序不同,用命令行或直接在Tornado环境下Build,在Tornado下不能跟踪调试。 用户也可以添加自己的程序到BSP中,但严格来说不应该算BSP.一般来说这种做法不建议。因为一旦操作系统能良好运行于最终的主板硬件后,BSP也就固定了,不需要做任何改动。而用户自己在BSP中的程序还会不断的升级更新,这样势必对BSP有不好的影响,对系统造成影响,同时由于BSP调试编译环境较差,也不利于程序的编译调试。
BSP在嵌入式系统和Windows系统中的不同
BSP和PC机主板上的BIOS区别很大,BIOS主要是负责在电脑开启时检测、初始化系统设备(设置栈指针,中断分配,内存初始化..)、装入操作系统并调度操作系统向硬件发出的指令,它的Firmware代码是在芯片生产过程中固化的,一般来说用户是无法修改。其实是为下载运行操作系统做准备,把操作系统由硬盘加载到内存,并传递一些硬件接口设置给系统。在OS正常运行后,BIOS的作用基本上也就完成了,这就是为什么更改BIOS一定要从新关机开机。 而BIOS程序是用户不能更改,编译编程的,只能对参数进行修改设置。更不会包含一些基本的硬件驱动。
BSP开发处于整个嵌入式开发的前期,是后面系统上应用程序能够正常运行的保证。 大概步骤如下: 1.硬件主板研制,测试。 2.操作系统的选定,BSP编程。 3.上层应用程序的开发。 BSP部分在硬件和操作系统,上层应用程序之间。所以这就要求BSP程序员对硬件,软件和操作系统都要有一定的了解。这样才能做好BSP编程。 熟悉工具方面:电表,示波器,逻辑分析仪。硬件仿真器,仿真调试环境。 语言方面:汇编语言,C语言。 7月1日 DRAM的理解内存RAM的理解
无论是SRAM还是DRAM都是一个矩阵式的存储结构,有行地址和列地址。
SRAM的存储容量小,采用的是触发器的结构,所以掉电不丢失,但价钱昂贵,行线和
列线在地址线上是分开的。如A0~Ai为行地址,Ai~Aj为列地址。这和容量小是有必然关系的。
DRAM容量大,为什么?采用的是mos管储能的方式,结构简单,所以可以做到大容量,
但是漏电现象是不可避免的,所以需要定时刷新控制电路辅助。
采用的仍然是行列地址共同作用的方式,但容量大了,地址线势必变大,所以在DRAM中
,行线列线是复用的,通过RAS和CAS两个管脚信号决定是行地址还是列地址,
WE用来决定是读操作还是写操作。为1时进行读操作,为0时进行写操作。
采用这种DRAM进行设计时,处理器内部一般具有相应的电路与之配套,否则使用起来是很困难的。
在arm9上一般都会用到,在arm9处理器上有相应的管脚与之相连,所以连线非常简单。
上面这篇文章以实例介绍了DRAM的电路设计方法。不错。
而这个地址中的文章详细的介绍了内存的读写过程,很不错,虽然没看太明白。 arm 2440 学习笔记三星2440开发板核心板主要包括 :
一个2440芯片,一个12M晶振,一个32.768KHZ的晶振。
12M的晶振用来给arm内部所需的各种电路提供时钟,倍频到几百兆的频率。
两种方式为arm内部提供所需的时钟,一种是通过晶振,第二种是通过外部时钟 EXECLK,选用一种时另一种接高电平。
OM[0,1]管脚复位时的高低电平决定了芯片的工作模式。
一个MIC5219,电源芯片提供了1.3v的电压。
两片HY57V561620 SDRAM,组成了64Mram。
一片nandflash K9F1208 ,64M。nandflash 均为串行flash。容量大。
以上这些就是核心板,3.3V电源是从主板引过来。
这个核心板子上要学习的就是ram和flash的引线。地址线,数据线的连接。 6月22日 项目经理(转)1.政治素质。具有高度责任心和事业心,坚韧不拔,勇于进取的精神.
2.能力素质.能力素质是项目经理整体素质体系中的核心素质。它表现为项目经理把知识和经验有机结合起来运用于项目管理的过程,对于现代项目经理来说,知识和经验固然十分重要,但是归根结底要落实在能力上。能力是直接影响和决定项目经理成败的关键,概括起来,包括五个方面: (1)决策能力。决策能力集中体现在项目经理的战略战术决策能力上。工程项目大都面临错综复杂、竞争激烈的外部环境,要使项目管理成功,经理人员应了解和研究环境,对与项目管理有关的技术、设备、材料等商情进行分析预测,制定出战略决策,并付诸实现。从决策程度来看,经理人员的决策能力可分解为如下三种:收集与筛选信息的能力、确定多种可行方案的能力、择优决策的能力。 (2)组织能力。项目经理的组织能力是指设计组织结构,配备组织成员以及确定组织规范的能力。显然,拥有较高组织能力的经理人员能够运用组织理论原理,建立科学的、分工合理的、配套成龙的高效精干的组织机构,合理配备组织成员,确定一整套保证组织有效运转的规范。能够做到知人善用。 项目经理的激励能力与经理人员对人的认识有关。现代人不单纯是“经济人”,而且是“社会人”,不仅有经济上的需求,而且有社会和心理上的要求。经理人员应更加注意运用各种社会和心理刺激手段,通过丰富工作内容、民主管理等措施来激励和调动员工的士气。 3.知识素质。项目管理者的知识素质以及对项目管理活动的影响作用,构成项目领导人的专门能力有技术能力、商业能力、财务能力、管理能力、安全能力等。每一种能力都是以知识为基础的.因此.理想的项目经理应该有解决问题所必要的知识。根据理论探讨和项目经理实践经验的分析,项目经理应具备两大类知识,即基础知识与业务知识. (1)基础知识。基础知识包括社会科学和自然科学。在社会科学方面,应掌握经济学、管理学、心理学、法律和伦理学等方面的知识。在自然科学方而,应学好数学、物理学、化学和电子计算机使用等知识。 (2)业务知识。项目经理应掌握投资学、投资项目管理学、技术经济学、企业领导学以及本行业的专业知识等。 由此可知,项目经理应该是具有一定知识广度的“杂家”,他应在实践中不断深化和完善自己的知识结构. 4.体格素质。身体健康,精力充沛. 项目经理应具备的素质有六条: (1)具有本专业技术知识; (2)有工作干劲,主动承担责任; (3)具有成熟而客观的判断能力,成熟是指有经验,能够看出问题,客观是指他能看到最终目标,而不是只顾眼前; (4)具有管理能力; (5)诚实可靠与言行一致,答应的事就一定做到; (6)机警、精力充沛,能够吃苦耐劳,随时都准备着管理可能发生的事情. 项目监控(转载) 1Critical Chain 对于软件项目来说,关键是能否在规定的时间之内,预定的资金内,有质量的交付客户要求的产品。我们这里关注的是如何准时的完成项目,预算和质量都有其特定的系统去监控。能否按时完成项目就取决于我们的网络图中最长的那条chain,所以我们说一个项目网络图中最长的那条chain我们就称之为Critical Chain, 简称为cc。 在一个项目的pert char未定之前,我们要做的就是反复分析最终得到cc,具体就是先找出最长的chain,然后分析每个task的duration是否都是不可再缩减的,若可以就进行优化,再看这条chain还是不是最长的chain,如果不是则找出新的最长的chain,依次类推,最终得到最优的网络图,得到cc。当然在项目的执行过程中,可能最初的cc慢慢的不再是最长的chain了,但是由于buffer机制管理的问题,cc一旦确立,在项目的执行过程将不再改变。有关buffer的问题在后面解释。 cc确立后,就是整个项目的constraint,对于cc就要更多的关注与控制,也就一个项目的主要矛盾。非cc的task就是次要矛盾,但是不意味着就不重要,只是相对而言要更关注cc而已。 2 Buffer 人在做事情的时候,当需要预估这件事情完成所需的周期时,会有两种方式在脑中思考:50%confidence and 90%confidence, 50% confidence是指在最好的情况下,我尽最大的努力完成这个任务所需要的时间;90% confidence是指我有相当大的把握完成这个任务所需要的时间。出于人的惰性以及害怕一旦无法如期完成所带来的后果,大多数的人在预估完成任务所需要的时间的时候,倾向于使用90%confidence。而实际是90%confidence的时间偏长,往往造成项目周期的加长;50%confidence则由于过于不给自己留有余地,往往在意外情况发生的时候造成任务超时。所以我们引入buffer的概念来平衡,既有一定的把握完成,同时又避免50%所带来的高风险,又不像90%那样延长了工期。 Buffer是指在某条链上所有的tasks最后加上一个task,给予一定的duration用于保护项目,避免突发事件造成的项目延期。例如一条链上有4个tasks,每个task 10days,则在最后一个task后再加上一个task,给上一定的时间,比如10days。如果有一个task在预计的10天内没有完成,而是用了12天,那么这个task就吃掉了2天的buffer,这时候buffer的 consumption就是2/10=20%. 在这里每个task的时间都是采用的50%confidence标准定的,而buffer就起到了降低了50%所带来的高风险。同时由于只有一个buffer,所以buffer是团队共享的buffer,这个时候个人消耗buffer就是消耗整个团队的buffer,即使PM不看着,team的其他成员也会注意的,而吃buffer的这个人所得到的压力就不只是来自PM了。:) 3 Buffer management Buffer的另外一个重要的作用就是显示整个项目的状态。buffer如果没有被吃,那么整个项目的risk相对就低,如果buffer面临被吃完的局面,则说明buffer的保护作用已经慢慢消失,risk慢慢的在上涨。如果我们依照buffer consumption的比率设定一些值,如30%以下为绿色,30%~70%为黄色,70%~80%为红色。那么我们就可以依照这些颜色来简单的确定项目的状态,从而制定相应的对策。 4 As late as possible 大家有没有这种感觉,毕业前要交一个论文,你提前一个月写往往是在期限的前一天刚刚搞定;而如 late as possible 大家有没有这种感觉,毕业前要交一个论文,你提前一个月写往往是在期限的前一天刚刚搞定;而如果你提前2周写,往往又是也很可能刚刚在期限的前一天搞定。这也是人的惰性的因素所致。所以有一种叫as late as possible的方法,不管这个项目什么时候开始,我们只是考虑在最好情况下,当所有的tasks的duration定下来了,buffer的大小定下来了,我们依据项目结束的日期从后往前推,从而得到项目开始的日期,如果这个日期晚于今天,那么可以考虑将resource放到别的项目中去。这种方法最早主要用于物流方面,因为仓库的占用是要花费相当的成本的,如果能很好的利用ALAP,则可以更有效率的利用仓库,降低成本。如今用于软件领域也可以使用。 |
||||||||||||||||||||||||||
|
|