I want to be a complete engineer - technical genius and sensitive humanist all in one!

Saturday, September 27, 2008

zImage内核镜像解压过程详解

本文以linux-2.6.14内核在S3C2410平台上运行为例,讲解内核的解压过程。内核编译完成后会生成zImage内核镜像文件。关于bootloader加载zImage到内核,并且跳转到zImage开始地址运行zImage的过 程,相信大家都很容易理解。但对于zImage是如何解压的过程,就不是那么好理解了。本文将结合部分关键代码,讲解zImage的解压过程。

先看看zImage的组成吧。在内核编译完成后会在arch/arm/boot/下生成zImage。

在arch/armboot/Makefile中:

$(obj)/zImage: $(obj)/compressed/vmlinux FORCE

$(call if_changed,objcopy)

由此可见,zImage的是elf格式的arch/arm/boot/compressed/vmlinux二进制化得到的

在arch/armboot/compressed/Makefile中:

$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \

$(addprefix $(obj)/, $(OBJS)) FORCE

$(call if_changed,ld)

$(obj)/piggy.gz: $(obj)/../Image FORCE

$(call if_changed,gzip)

$(obj)/piggy.o: $(obj)/piggy.gz FORCE

其中Image是由内核顶层目录下的vmlinux二进制化后得到的。注意:arch/arm/boot/compressed/vmlinux是位置无关的,这个有助于理解后面的代码。,链接选项中有个 –fpic参数:

EXTRA_CFLAGS := -fpic

总结一下zImage的组成,它是由一个压缩后的内核piggy.o,连接上一段初始化及解压功能的代码(head.o misc.o),组成的。

下面就要看内核的启动了,那么内核是从什么地方开始运行的呢?这个当然要看lds文件啦。zImage的生成经历了两次大的链接过程:一次是顶层 vmlinux的生成,由arch/arm/boot/vmlinux.lds(这个lds文件是由arch/arm/kernel /vmlinux.lds.S生成的)决定;另一次是arch/arm/boot/compressed/vmlinux的生成,是由arch/arm /boot/compressed/vmlinux.lds(这个lds文件是由arch/arm/boot/compressed /vmlinux.lds.in生成的)决定。zImage的入口点应该由arch/arm/boot/compressed/vmlinux.lds决 定。从中可以看出入口点为‘_start’

OUTPUT_ARCH(arm)

ENTRY(_start)

SECTIONS

{

. = 0;

_text = .;

.text : {

_start = .;

*(.start)

*(.text)

……

}

在arch/arm/boot/compressed/head.S中找到入口点。

看看head.S会做些什么样的工作:

• 对于各种Arm CPU的DEBUG输出设定,通过定义宏来统一操作;

•设置kernel开始和结束地址,保存architecture ID;

• 如果在ARM2以上的CPU中,用的是普通用户模式,则升到超级用户模式,然后关中断

• 分析LC0结构delta offset,判断是否需要重载内核地址(r0存入偏移量,判断r0是否为零)。

•需要重载内核地址,将r0的偏移量加到BSS region和GOT table中的每一项。

对于位置无关的代码,程序是通过GOT表访问全局数据目标的,也就是说GOT表中中记录的是全局数据目标的绝对地址,所以其中的每一项也需要重载。

• 清空bss堆栈空间r2-r3

•建立C程序运行需要的缓存

•这时r2是缓存的结束地址,r4是kernel的最后执行地址,r5是kernel境象文件的开始地址

•用文件misc.c的函数decompress_kernel(),解压内核于缓存结束的地方(r2地址之后)。

可能大家看了上面的文字描述还是不清楚解压的动态过程。还是先用图表的方式描述下代码的搬运解压过程。然后再针对中间的一些关键过程阐述。

假定zImage在内存中的初始地址为0x30008000(这个地址由bootloader决定,位置不固定)

1、初始状态

.text

0x30008000开始,包含piggydata段(即压缩的内核段)

. got

?

. data

?

.bss

?

.stack

4K大小

2、head.S调用misc.c中的decompress_kernel刚解压完内核后

.text

0x30008000开始,包含piggydata段(即压缩的内核段)

. got

?

. data

?

.bss

?

.stack

4K大小

解压函数所需缓冲区

64K大小

解压后的内核代码

小于4M

3、此时会将head.S中的部分代码重定位

.text

0x30008000开始,包含piggydata段(即压缩的内核段)

. got

?

. data

?

.bss

?

.stack

4K大小

解压函数所需缓冲区

64K大小

解压后的内核代码

小于4M

head.S中的部分重定位代码代码

reloc_startreloc_end

4、跳转到重定位后的reloc_start处,由reloc_start至reloc_end的代码复制解压后的内核代码到0x30008000处,并调用call_kernel跳转到0x30008000处执行。

解压后的内核

0x30008000开始

在通过head.S了解了动态过程后,大家可能会有几个问题:

问题1:zImage是如何知道自己最后的运行地址是0x30008000的?

问题2:调用decompress_kernel函数时,其4个参数是什么值及物理含义?

问题3:解压函数是如何确定代码中压缩内核位置的?

先回答第1个问题

这个地址的确定和Makefile和链接脚本有关,在arch/arm/Makefile文件中的

textaddr-y := 0xC0008000 这个是内核启动的虚拟地址

TEXTADDR := $(textaddr-y)

在arch/arm/mach-s3c2410/Makefile.boot中

zreladdr-y := 0x30008000 这个就是zImage的运行地址了

在arch/arm/boot/Makefile文件中

ZRELADDR := $(zreladdr-y)

在arch/arm/boot/compressed/Makefile文件中

zreladdr=$(ZRELADDR)

在arch/arm/boot/compressed/Makefile中有

.word zreladdr @ r4

内核就是用这种方式让代码知道最终运行的位置的

接下来再回答第2个问题

decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,

int arch_id)

l output_start:指解压后内核输出的起始位置,此时它的值参考上面的图表,紧接在解压缓冲区后;

l free_mem_ptr_p:解压函数需要的内存缓冲开始地址;

l ulg free_mem_ptr_end_p:解压函数需要的内存缓冲结束地址,共64K;

l arch_id :architecture ID,对于SMDK2410这个值为193;

最后回答第3个问题

首先看看piggy.o是如何生成的,在arch/arm/boot/compressed/Makefie中

$(obj)/piggy.o: $(obj)/piggy.gz FORCE

Piggy.o是由piggy.S生成的,咱们看看piggy.S的内容:

.section .piggydata,#alloc

.globl input_data

input_data:

.incbin "arch/arm/boot/compressed/piggy.gz"

.globl input_data_end

input_data_end:

再看看misc.c中decompress_kernel函数吧,它将调用gunzip()解压内核。gunzip()在lib/inflate.c中定义,它将调用NEXTBYTE(),进而调用get_byte()来获取压缩内核代码。

在misc.c中

#define get_byte() (inptr <>

查看fill_inbuf函数

int fill_inbuf(void)

{

if (insize != 0)

error("ran out of input data");

inbuf = input_data;

insize = &input_data_end[0] - &input_data[0];

inptr = 1;

return inbuf[0];

}

发现什么没?这里的input_data不正是piggy.S里的input_data吗?这个时候应该明白内核是怎样确定piggy.gz在zImage中的位置了吧。

利用udev、sys动态创建linux设备结点

在Linux2.6内核中,devfs被认为是过时的方法,并最终被抛弃,udev取代了它。Devfs的一个很重要的特点就是可以动态创建设备结点。那我们现在如何通过udev和sys文件系统动态创建设备结点呢?

下面通过一个实例,说明udev、sys动态创建设备结点的方法。注意代码中红色的部分是为了实现动态创建设备结点添加的。


#include linux/module.h/

#include /linux/kernel.h

#include /linux/init.h/
#include /
linux/fs.h/
#include /
linux/cdev.h/
#include /
asm/uaccess.h/
#include /
linux/device.h/


MODULE_LICENSE ("GPL");

int hello_major = 252;
int hello_minor = 0;
int number_of_devices = 1;
char data[50]="foobar not equal to barfoo";
struct cdev cdev;
dev_t dev = 0;
static int hello_open (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hey! device opened\n");
return 0;
}
static int hello_release (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hmmm... device closed\n");
return 0;
}
ssize_t hello_read (struct file *filp, char *buff, size_t count, loff_t *offp)
{
ssize_t result = 0;
if (copy_to_user (buff, data, sizeof(data)-1))
result = -EFAULT;
else
printk (KERN_INFO "wrote %d bytes\n", count);

return result;
}
ssize_t hello_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
ssize_t ret = 0;
printk (KERN_INFO "Writing %d bytes\n", count);
if (count>127)

return -ENOMEM;
if (count<0)>

return -EINVAL;

if (copy_from_user (data, buf, count))

{

ret = -EFAULT;

}

else

{

data[127]='\0';

printk (KERN_INFO"Received: %s\n", data);

ret = count;

}

return ret;

}

struct file_operations hello_fops = {

.owner = THIS_MODULE,

.open = hello_open,

.release = hello_release,

.read = hello_read,

.write = hello_write

}; struct class *my_class;

static void char_reg_setup_cdev (void)
{
int error, devno = MKDEV (hello_major, hello_minor);
cdev_init (&cdev, &hello_fops);
cdev.owner = THIS_MODULE;
cdev.ops = &hello_fops;
error = cdev_add (&cdev, devno , 1);
if (error)
printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev", error);
/* creating your own class */
my_class =class_create(THIS_MODULE, "farsight_class");
if(IS_ERR(my_class))

{
printk("Err: failed in creating class.\n");
return ;
}
/* register your own device in sysfs, and this will cause udevd to create corresponding device node */
class_device_create(my_class,NULL, devno, NULL,"farsight_dev");
// device_create(my_class,NULL, devno,"farsight_dev");
}

static int __init hello_2_init (void)
{
int result;
dev = MKDEV (hello_major, hello_minor);
result = register_chrdev_region (dev, number_of_devices, "test");
if (result<0)>

{

printk (KERN_WARNING "hello: can't get major number %d\n", hello_major);

return result;

}

char_reg_setup_cdev ();

printk (KERN_INFO "char device registered\n");

return 0;

}

static void __exit hello_2_exit (void)

{

dev_t devno = MKDEV (hello_major, hello_minor);

cdev_del (&cdev);

unregister_chrdev_region (devno,number_of_devices);

class_device_destroy(my_class, devno);

class_destroy(my_class);

}

module_init (hello_2_init); module_exit (hello_2_exit);

在编译了驱动后,可以查看/dev/farsight_dev设备结点,和 /sys/class/farsight_class/farsight_dev/ 本代码的测试环境是Ubantu7.04,内核版本是2.6.20-15-generi。在不同版本的内核中,有些系统函数的参数可能不太一样。

Thursday, September 25, 2008

故地、故事

难得的假期,我回到曾经呆过的地方!
云淡风轻的日子,顺其自然的岁月,我们那些曾一起的故事,似水流年,流年似水,随青春都以渐渐淡去,唯独我还站在波涛汹涌的人流,昂着头,回忆属于我们的记忆.
当风轻轻掠过耳畔,云淡淡地挂在天边,眼前的一切仿佛离得那么高那么远。树依然葱绿,花依旧鲜艳,稻田里的谷穗却随时准备和阳光灿烂成一片…
季节在悄悄地改变,它将时间分割成一段一段,我们踩着四季在岁月里慢慢改变:年龄在增长,容颜在暗淡;经验在增加,精力却在褪减。

快刀杨佳大侠列传

杨大侠佳今已驾鹤西区,后偶尔在网上看到如此文,遂转之!以祭杨大侠在天之灵!

大侠杨君者,讳佳,国朝京畿人氏。起于贫寒,性情温良,邻人皆曰善。其尤善刀术,抽刀断敌首而不染滴血,人称“柳叶快刀杨佳”。

幼,父母离异,孤苦伶仃,苦不堪言。

初,闯荡浦江繁都上海府,欲侍平身气力而谋生。然国朝之“编户保甲之制”极苛,公四处讨活不得安生,更有酷卒——联防队、城管日夜侵扰,乃至于拳脚相加者,杨公避之唯恐不及。

堂堂八尺男儿,欲为贩夫走卒而不能。食不果腹、衣不遮体,英雄末路,前景凄凉,纵铁骨之人皆为之涕泪涔涔。

一日,公赁人力车行,卒为锦衣卫番役所获,番役谓车为盗赃,捕公入上海锦衣卫镇抚使司衙,百般栲掠,遍及惨毒,伤及命根,而公犹不屈,不肯自污为盗。后出赁者为证,车非盗也,锦衣卫方纵公归。公以国有明宪,冤人为盗须偿付之,诉于上海锦衣卫镇抚使司,竟不理。

一日,杨公偶获《贺元帅洪湖起兵纪实》一书,阅罢不禁掩卷长叹曰:“嗟夫!大丈夫生当若贺帅,两把菜刀斩尽天下不平事,固因杀豪强而死,熟与忍辱偷生,亦死得其所。余奋起市井,若能一怒而天下惊,不亦快哉!”。

遂奔东市买快刀,西市买汽油。事毕,东北向三拜以敬爹娘,思及哺育之恩,英雄泪潸然而下,天地亦为之动容焉!

翌日,杨公走上海锦衣卫镇抚使司衙,猝入门,一门卒喝曰:“咄!民工何为?众大人忙于政事,无暇顾汝,汝速去,不然断汝筋骨”!杨公冷笑一声,一道寒光划过,门卒闷声倒地,即刻血溅三尺。一刀而封喉之功,盖举世独杨公无有也!

践门卒之污血,杨公拖刀直入司衙议事大堂,怒发上冲冠,目尽裂。一路披靡如入无人之境,扑腾砍杀宛若饿虎屠羊。遇着锦衣飞鱼服之男子,公皆斩而杀之,腥血横飞,鬼神为之色变,一众锦衣卫士,竟无人可当公一合,虽携火铳,然公出刀,如飙发而电举,火铳竟无余暇可施为者也。昔者不可一世于十里洋场之豪强,顿作兽奔鸟散状悲鸣呼号,情形甚是惨烈!唯独妇人幸免,盖因杨公怜恤妇孺,不忍伤之,其仁侠之心,可以见矣!

此一役,力歼锦衣番役,力士等共六人,重伤者无算。杨公威名,海内为之信服!

杨公卒因力尽受缚,然其仍不失英雄本色,狼顾左右而目叱之,众皆肝胆崩裂悚然不敢近焉。镇抚使司遂诬其为盗车小贼,强使英雄蒙羞。朝野为之哗然,中原豪杰无不为之悲愤痛惜!

壮士成名身将死,长使英雄泪满袖。

武松血溅鸳鸯楼,杨公一怒鬼神愁。

太史公曰:天下有道,圣人成焉;天下无道,圣人生焉;方今之事,仅免刑焉。

夫以杨公之力,若为民国诸侯争霸初年,必若贺帅封侯拜将,何愁青史无名。方今霉世,英雄仅免刑焉,豪杰寂寞不闻诸侯,乃至于引颈待戮、悲愤赴死者!不亦悲哉?不亦哀哉?

Wednesday, September 24, 2008

Linux驱动程序开发学习步骤

1. 学会写简单的makefile

2. 编一应用程序,可以用makefile跑起来

3. 学会写驱动的makefile

4. 写一简单char驱动,makefile编译通过,可以insmod, lsmod, rmmod. 在驱动的init函数里打印hello world, insmod后应该能够通过dmesg看到输出。

5. 写一完整驱动, 加上read, write, ioctl, polling等各种函数的驱动实现。 在ioctl里完成从用户空间向内核空间传递结构体的实现。

6. 写一block驱动, 加上read,write,ioctl,poll等各种函数实现。

7. 简单学习下内存管理, 这个是最难的,明白各种memory alloc的函数实现细节。这是linux开发的基本功。

8. 学习锁机制的应用,这个不是最难的但是最容易犯错的,涉及到很多同步和并发的问题。

9. 看内核中实际应用的驱动代码。 你会发现最基本的你已经知道了, 大的框架都是一样的, 无非是read, write, ioctl等函数的实现, 但里面包含了很多很多细小的实现细节是之前不知道的。 这时候就要考虑到很多别的问题而不仅仅是基本功能的实现。

推荐您看2.6.20中integrated的一个驱动 kvm,记得是在driver/lguest下,很好玩的, 就是linux下的虚拟机驱动,代码不长,但功能强大。有能力的可以自己写一操作系统按照要求做成磁盘镜像加载到虚拟机中, 然后客户机可以有自己的4G虚拟地址空间。

10. 看完驱动欢迎您进入Linux kernel学习中来。

最简单的方法,跟着ldd(linux devive driver)做一遍。

Wednesday, September 17, 2008

关于民族产业还有属于民族的我们

这几天,“民族产业”这几个字恶心的我要吐,三鹿的鹿托们到处叫嚣着“死扛民族产业”云云,还死硬把爱国和支持“国人杀手”联系起来,说“不挺三鹿就是不爱国”云云!去你妈的吧,民族产业专门毒杀民族未来?
我自始自终都很爱国,我高中就给国务院写信,畅谈自己对收复台湾的想法和意志,表达自己富国强兵的愿望!也得到他们热情的回信和邮寄给我的书籍资料。我是爱国的,我自始自终都热爱着我的国家!
国家爱我吗?
垃圾联想,那产品......,都那样了,还摇着一副讨好洋人的丑恶嘴脸却压榨着国人并不多的财富!
三鹿,提供给洋人的东西都没有问题,自己用的全部有毒,民族企业嘛,毒的就是你中国人!
汶川地震倒塌的学校,死的就是你中国的学生!
新闻媒体的歌功颂德,国家权威机构的信誓旦旦,民族企业的万丈豪言---原来都是骗人的!
骗谁?人民!人民最傻,人家说什么就是什么!到最后连自己的命都丢了!
如果说以前对民族产业是哀其不幸,怒其不争,那么,这次,我彻底死心了!
去他妈的民族产业,去他妈的国货!
谁爱用谁用去!
这些事件的背后有多少黑幕我们不知道,有多少利益集团千丝万缕的关系我们也不知道!
这个时代是个竞争的时代,所有人都在最大限度的捞钱,不惜一切代价的捞钱!越多越好,越快越好!极好,不惜一切代价的捞钱!
所有人都毒死了那也无所谓,只要我不死就好!
别人的孩子都被砸死了无所谓,我的孩子没有事!
每次国内重大事件倒霉的都是草根阶层!
我想那些沦为国内和国际各种利益代言人的中国精英们是论不到他们的孩子死的!
我想那些有毒的奶粉他们是不会吃的!
改革开发砸碎了我们固有的价值观念,物质因素被推举到无比崇高的位置!
我们就有的价值观荡然无存,信的价值观尚处于混乱状态!
中国是一个没有宗教信仰的国家,时值今天我们的脑袋里面出了充斥着物质以外我想没有其他的东西了,尽管我个人也是排斥宗教的,但宗教积极的一面亦不能视而不见.在一个无神论、唯物主义盛行的社会我是在找不到让卑劣的心灵可以去放松的地方。
于是大家相互伤害相互折磨,还自以为得了好处。
那么社会的总管---政府呢?
政府或者在睡觉---真睡!所以没有发觉。
或者在假寐---发觉了就当作没有发觉。
或者与坏人沆瀣一气,狼狈为奸,有财大家发!
或者发现了,发现了又怎样?
八十七年前,本着为穷人争权益,我们的党成立,毛主席正是本着为穷人打天下的理念,经过艰苦卓绝的奋斗创建了新中国!
今天,......哎!我们的政府已经沦落为既得利益集团和有钱人的看门X和帮凶!
我不再信任他们了,别想着他们会真的帮你!
我生平第一次有了恶心的感觉,对这个国家,这个政府!对这个一直蒙骗、欺诈我们的恶心......
洋人是灭不了中国的,灭中国者,中国人也!
这是个神奇的国度!

三鹿-灭亡之前的疯狂

三鹿充满戏剧性的高潮后面还有多少见不得人的东西?天知道。
因为如我所料,某某部显然已经开始下封令了——如此震惊世界的大事件在网站上的位置都比不上残奥女乒夺金和钱塘大潮,连个专题都没有!
我曾非常侥幸地希望如政府希望让我们明白的那样,三鹿事件只是个别非法奶农利欲熏心所为。非常不幸的是,我错了。
让我们算一下吧:两个被抓的黑心奶农共提供了3吨毒奶液,那么700吨毒奶粉(10-13吨奶液可制1吨奶粉)需要有多少黑心奶农?全国22家企业又该抓多少奶农呢?
上帝说,要让一个人灭亡,必先使其疯狂。三鹿在不经意间,揭开了一个行业的疯狂——
仅仅是一种婴儿奶的抽查,便有20多个品牌含毒,那么,没被抽到的成人奶粉呢?液体奶呢?其它奶制品呢?
“供应奥运、残奥奶粉未出现问题”?看似为了平息国际舆论,让洋人释怀,但却令国人深深地悲哀——
这说明,一,在我们的长官看来,国人的生命和健康是不如洋人重要的;二,掺毒行为是完全可以操纵、控制的,是有选择的主观故意!
所以,把掺毒归结于个别奶农的所为完全是扯JB蛋的事,这是一个行业的疯狂,是中国奶业的潜规则!
日本人说,每天一杯奶,拯救了一个民族;中国人说,每天一杯奶,毁灭了一个民族。
一个连自己子孙都不放过的民族是可耻的民族,是一个没有任何希望的民族!
在我看来,这场三鹿引发的奶业危机,其对国人造成的影响远远大于当年的非典。因为非典毕竟有不可抗逆性,是偶发和局部的。
但中国喝奶的人有多少?东南西北、老弱病残、城镇乡村,总该有十亿吧?!
我的悲哀和绝望在于,如此影响民生的惊天事件,在传媒中却为刻意地淡化了!我甚至在想,八月初即被发现了的毒奶粉,如果不是新西兰政府的直接干预,或许永远都不会暴露在国人面前。
我们看到过太多太多类似的事件。下面的发展用屁股都能想得出——
追源溯流:抓几个“黑心”奶农,判了(正在进行中);
现身说法:奶农现场演示,并表示认罪、忏悔;
严查三鹿:老总一干人辞职(正在进行中),最多抓上一两个;
举一反三:市长省长部长局长做深刻检讨,最多撤上一两个;
亡羊补牢:行业措施、整改方案纷纷出笼;
专家解惑:不知其名的专家称三聚氰胺并不可怕,不会有后遗症
党恩国爱:政府关怀受害儿童,白衣天使救死扶伤;
情绪稳定:受害家长纷纷谢谢党和政府;
多难兴业,中国奶业走出低谷重现辉煌;
……
三鹿事件可能出现的结局,按照那些老套手法,也许是这样的:抓几个“不法奶农”、“不法奶霸”,三鹿的一些采购人员及质检人员被抓。田文华董事长辞职及石家庄市的某位分管领导撤职,这可能都不容易看到。然后,宣传机器高速运转,从父母到专家,纷纷出现在媒体上赞美政府。
如果我们的政府不想倒台,就按上面的手法做吧。这次,若不彻查所有涉及人员,那么,连锁反应将这样发生:
1、中国乳制品业一同崩溃。三鹿这样的企业都下毒,人们有理由相信,其他企业也有嫌疑。三鹿为了自保,可能放风它的做法是行业“公开的秘密”,拉着整个行业一同陷入信任危机。
2、中国的食品业接着垮台。连自己的孩子都可以毒,那么,还有什么底线?毒毒宠物,毒毒青少年、成年人,不更是毫无顾忌吗?中国制造由于连连涉毒,在国际上已经恶名远扬,三鹿这次安然过关,就等于让三鹿为大家敲下最后一根棺材钉。
3、所有相关职能部门的破产。三鹿不仅牵扯到质检、卫生、工商、食品药品监督等等部门,还有强大的国家宣传机器背书----比如CCTV,三鹿从现在新闻来看,早在07年底就涉毒,从高强的讲话来看,三鹿三月就知道自己产品有毒,这反证了所有职能部门形同虚设,在这么长的时间里,它们没有作为,甚至几天前,还有甘肃的质检部门证明其合格,人们因此得出政府信用破产的结论,是必然的。三鹿背后的黑幕也是我们永远可能不知道的。
4、政府为了挽救自己,只有一个方法,让调查公开、深入,让新闻媒体与公众舆论持续监督,处理一切涉及到的官员。任何人管制言论,民众都将视之为不法三鹿的利益共同体。
5、中国人固然温良,但是一个政府一再为了不法企业的私利、为了政府所谓的面子而牺牲中国人的孩子----这次波及全国,北京上海等中心城市也受害----那么,这个政府的寿数也就到了。
6、一个国家,国民最重,国民认为他们的孩子更重。政府应该尽快知道这个常识,不然,建议所有当政者成为莫扎特的乐迷,多听听他的《安魂曲》,可能会用得上了。
可是可是,这分明是一场蓄谋已久的谋财害命啊,这分明是一个行业对一个民族的的投毒啊!
看看去年七月质监局长李长江在出口有毒宠物饲料在国际上引发轩然大波后说的那番无耻的话吧,如果发生在中国的这起毒奶事件仍不能让这些官老爷猛省的话,如果他们还试图不断用新的错误去掩盖旧的错误的话,如果他们还把中国民众当成愚民、贱民而试去打压、蒙骗的话,我相信,政府会彻底丧失掉仅有一点的民心了。
三鹿事件,不过是风暴潮的一角。
森拉克台风过后的大地,也许土地依旧,但下面的地基可能已经彻底被掏空,大厦随时都有倾覆的危险。
天作孽,犹可违;人作孽,不可活!

Tuesday, September 16, 2008

人生需要学会欣赏

欣赏是一道绝美的风景,一隅人人渴望、四季相宜、风味独特的景观。学会欣赏,你便懂得享受;学会欣赏,你便拥有快乐;学会欣赏,你便走近幸福;学会欣赏,便成为一个大写的人!

欣赏是一种享受,是一种实实在在的享受。无论何时何地,你学会了欣赏,你便收获快乐,收获温馨。懂得欣赏,你的心情便永远阳光灿烂。

欣赏是一种情怀,是一种博大高雅的情怀。没有爱心的人,不懂得欣赏;缺少情趣的人,不知道欣赏。欣赏需要知本。

欣赏是一种幸福,是一种少数人才能享受的幸福。大千世界,芸芸众生,自以为是者多,懂得欣赏别人的少;自私自利者多,专门利人者少。欣赏滋生幸福,幸福需要懂得欣赏。

欣赏是一种学习,是一种真心实意的学习。生活里,每个人都有每个人的优点,每个人都有每个人的弱点。学会欣赏,就要时刻看到别人的优点,让别人的优点自觉地成为自己的优点。久而久之,你便自然成为一个优秀的人;优秀的人,自然也懂得欣赏。

欣赏是一种态度,是一种发自内心羡慕的态度。当你读到一首诗或看到一幅画,一首清新流丽、情味隽永的小诗,一幅别有格调、神韵悠然的国画,你不能不激动,你不能不羡慕,除非你是傻瓜。此时,羡幕无需理由。

欣赏是一种风格,是一种独特自在的感悟风格。纷繁世界,无奇不有,有山有水,有花有草,有风有雨,时时刻刻,变幻无穷。懂得欣赏,便懂得感悟;感悟愈深,生活得愈滋润、愈轻松;轻松滋润的生活便是至高无上的生活,既然知道无上生活的秘诀,为何不学会欣赏?利人利己的欣赏,应当义不容辞、义无返顾!

欣赏是一种精神,是一种情高趣雅的精神。蚂蚁有蚂蚁的生活,大像有大像的情调,仙鹤有仙鹤的风姿。懂得欣赏,你便懂得生活的真谛;懂得欣赏,你便拥有别人所没有的情调;懂得欣赏,你也便拥有迷人的风姿。

欣赏是一种力量;是一种与时俱进、自强不息、自我奋斗的力量。人生在世,区区百年,匆匆一日,忽忽一生,若不见贤思齐,脚踏实地,真抓实干,争分夺秒,多做一些有利于人类文明发展的大事、好事,年老时,你就会后悔不迭、悔之晚矣。学会欣赏,你便懂得珍惜,你便拥有更多、奉献更多。

欣赏是阳光,是雨露,是冬天里的一把烈火;欣赏是玉液,是琼浆,是夏日里的一片浓阴。让我们学会欣赏,让我们温暖处处。让我们学会欣赏,让我们阴凉处处……

中秋去了海边


中秋去了海边,到处是沙子,和水!
旁边那个傻乎乎的丫头就是我传说中的美眉!

Friday, September 12, 2008

about TEXTADDR, ZTEXTADDR, PAGE_OFFSET etc...

Initial definitions
-------------------

The following symbol definitions rely on you knowing the translation that
__virt_to_phys() does for your machine. This macro converts the passed
virtual address to a physical address. Normally, it is simply:

phys = virt - PAGE_OFFSET + PHYS_OFFSET


Decompressor Symbols
--------------------

ZTEXTADDR
Start address of decompressor. There's no point in talking about
virtual or physical addresses here, since the MMU will be off at
the time when you call the decompressor code. You normally call
the kernel at this address to start it booting. This doesn't have
to be located in RAM, it can be in flash or other read-only or
read-write addressable medium.

ZBSSADDR
Start address of zero-initialised work area for the decompressor.
This must be pointing at RAM. The decompressor will zero initialise
this for you. Again, the MMU will be off.

ZRELADDR
This is the address where the decompressed kernel will be written,
and eventually executed. The following constraint must be valid:

__virt_to_phys(TEXTADDR) == ZRELADDR

The initial part of the kernel is carefully coded to be position
independent.

INITRD_PHYS
Physical address to place the initial RAM disk. Only relevant if
you are using the bootpImage stuff (which only works on the old
struct param_struct).

INITRD_VIRT
Virtual address of the initial RAM disk. The following constraint
must be valid:

__virt_to_phys(INITRD_VIRT) == INITRD_PHYS

PARAMS_PHYS
Physical address of the struct param_struct or tag list, giving the
kernel various parameters about its execution environment.


Kernel Symbols
--------------

PHYS_OFFSET
Physical start address of the first bank of RAM.

PAGE_OFFSET
Virtual start address of the first bank of RAM. During the kernel
boot phase, virtual address PAGE_OFFSET will be mapped to physical
address PHYS_OFFSET, along with any other mappings you supply.
This should be the same value as TASK_SIZE.

TASK_SIZE
The maximum size of a user process in bytes. Since user space
always starts at zero, this is the maximum address that a user
process can access+1. The user space stack grows down from this
address.

Any virtual address below TASK_SIZE is deemed to be user process
area, and therefore managed dynamically on a process by process
basis by the kernel. I'll call this the user segment.

Anything above TASK_SIZE is common to all processes. I'll call
this the kernel segment.

(In other words, you can't put IO mappings below TASK_SIZE, and
hence PAGE_OFFSET).

TEXTADDR
Virtual start address of kernel, normally PAGE_OFFSET + 0x8000.
This is where the kernel image ends up. With the latest kernels,
it must be located at 32768 bytes into a 128MB region. Previous
kernels placed a restriction of 256MB here.

DATAADDR
Virtual address for the kernel data segment. Must not be defined
when using the decompressor.

VMALLOC_START
VMALLOC_END
Virtual addresses bounding the vmalloc() area. There must not be
any static mappings in this area; vmalloc will overwrite them.
The addresses must also be in the kernel segment (see above).
Normally, the vmalloc() area starts VMALLOC_OFFSET bytes above the
last virtual RAM address (found using variable high_memory).

VMALLOC_OFFSET
Offset normally incorporated into VMALLOC_START to provide a hole
between virtual RAM and the vmalloc area. We do this to allow
out of bounds memory accesses (eg, something writing off the end
of the mapped memory map) to be caught. Normally set to 8MB.

Architecture Specific Macros
----------------------------

BOOT_MEM(pram,pio,vio)
`pram' specifies the physical start address of RAM. Must always
be present, and should be the same as PHYS_OFFSET.

`pio' is the physical address of an 8MB region containing IO for
use with the debugging macros in arch/arm/kernel/debug-armv.S.

`vio' is the virtual address of the 8MB debugging region.

It is expected that the debugging region will be re-initialised
by the architecture specific code later in the code (via the
MAPIO function).

BOOT_PARAMS
Same as, and see PARAMS_PHYS.

FIXUP(func)
Machine specific fixups, run before memory subsystems have been
initialised.

MAPIO(func)
Machine specific function to map IO areas (including the debug
region above).

INITIRQ(func)
Machine specific function to initialise interrupts.

/arch/arm/boot/compressed/head.S 分析

/arch/arm/boot/compressed/head.S
这是ARM-Linux运行的第一个文件,这些代码是一个比较独立的代码包裹器。其作用就是解压Linux内核,并将PC指针跳到内核(vmlinux)的第一条指令。Bootloader中传入到Linux中的参数总共有三个,Linux中用到的是第二个和第三个。第二个参数是architecture id,第三个是taglist的地址。Architecture id的arm芯片在Linux中一定要唯一。Taglist是bootload向Linux传入的参数列表。
//程序的入口点

.section ".start", #alloc, #execinstr
/*
* sort out different calling conventions
*/
.align
start:
.type start,#function
.rept 8 //重复8次下面的指令,也就是空出中断向量表的位置
mov r0, r0 //就是nop指令
.endr

b 1f
.word 0x016f2818 @ Magic numbers to help the loader
.word start @ absolute load/run zImage address
.word _edata @ zImage end address
1: mov r7, r1 @ save architecture ID
mov r8, r2 @ save atags pointer

#ifndef __ARM_ARCH_2__
/*
* Booting from Angel - need to enter SVC mode and disable
* FIQs/IRQs (numeric definitions from angel arm.h source).
* We only do this if we were in user mode on entry.
*/
mrs r2, cpsr @ get current mode
tst r2, #3 @ not user?
bne not_angel
mov r0, #0x17 @ angel_SWIreason_EnterSVC
swi 0x123456 @ angel_SWI_ARM
not_angel:
mrs r2, cpsr @ turn off interrupts to
orr r2, r2, #0xc0 @ prevent angel from running
msr cpsr_c, r2
#else
teqp pc, #0x0c000003 @ turn off interrupts
#endif

一定要保证当前运行在SVC模式下,否则会跳到swi里面去(为什么?我不清楚,而且我没有处理过这个swi)。然后再关闭irq和fiq。

/*
* Note that some cache flushing and other stuff may
* be needed here - is there an Angel SWI call for this?
*/

/*
* some architecture specific code can be inserted
* by the linker here, but it should preserve r7, r8, and r9.
*/

读入地址表。因为我们的代码可以在任何地址执行,也就是位置无关代码(PIC),所以我们需要加上一个偏移量。下面有每一个列表项的具体意义。
GOT表的初值是连接器指定的,当时程序并不知道代码在哪个地址执行。如果当前运行的地址已经和表上的地址不一样,还要修正GOT表。
.text
adr r0, LC0
ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp}
subs r0, r0, r1 @ calculate the delta offset

@ if delta is zero, we are
beq not_relocated @ running at the address we
@ were linked at.

/*
* We're running at a different address. We need to fix
* up various pointers:
* r5 - zImage base address
* r6 - GOT start
* ip - GOT end
*/
add r5, r5, r0
add r6, r6, r0
add ip, ip, r0

/*
* If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
* we need to fix up pointers into the BSS region.
* r2 - BSS start
* r3 - BSS end
* sp - stack pointer
*/
add r2, r2, r0
add r3, r3, r0
add sp, sp, r0

修改GOT(全局偏移表)表。根据当前的运行地址,修正该表。
/*
* Relocate all entries in the GOT table.
*/
1: ldr r1, [r6, #0] @ relocate entries in the GOT
add r1, r1, r0 @ table. This fixes up the
str r1, [r6], #4 @ C references.
cmp r6, ip
blo 1b

清BSS段,所有的arm程序都需要做这些的。

not_relocated: mov r0, #0
1: str r0, [r2], #4 @ clear bss
str r0, [r2], #4
str r0, [r2], #4
str r0, [r2], #4
cmp r2, r3
blo 1b

正如下面的注释所说,C环境我们已经设置好了。下面我们要打开cache和 mmu。为什么要这样做呢?这只是一个解压程序?为了速度。那为什么要开mmu呢,而且只是做一个平板式的映射?还是为了速度。如果不开mmu的话,就只能打开icache。因为不开mmu的话就无法实现内存管理,而io区是决不能开dcache的。

/*
* The C runtime environment should now be setup
* sufficiently. Turn the cache on, set up some
* pointers, and start decompressing.
*/
bl cache_on
是不是要跟读进去呢?对于只是对流程感兴趣的人只是知道打开cache就行了。不过跟进去是很有乐趣的,这就是为什么虽然Linux如此庞大,但仍有人会孜孜不倦的研究它的每一行代码的原因吧。反过来说,对于Linux内核的整体把握更加重要,要不然就成盲人摸象了。还有,想做ARM高手的人可以读 Linux下的每一个汇编文件,因为Linux内核用ARM的东西还是比较全的。

mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max

对下面这些地址的理解其实还是很麻烦,但有篇文档写得很清楚《About TEXTADDR, ZTEXTADDR, PAGE_OFFSET etc...》。下面程序的意义就是保证解压地址和当前程序的地址不重叠。上面分配了64KB的空间来做解压时的数据缓存。
/*
* Check to see if we will overwrite ourselves.
* r4 = final kernel address//内核执行的最终实地址
* r5 = start of this image//该程序的首地址
* r2 = end of malloc space (and therefore this image)
* We basically want:
* r4 >= r2 -> OK
* r4 + image length <= r5 -> OK
*/
cmp r4, r2
bhs wont_overwrite
add r0, r4, #4096*1024 @ 4MB largest kernel size
cmp r0, r5
bls wont_overwrite

如果空间不够了,只好解压到缓冲区地址后面。调用decompress_kernel进行解压缩,这段代码是用c实现的,和架构无关。

mov r5, r2 @ decompress after malloc space
mov r0, r5
mov r3, r7
bl decompress_kernel

完成了解压缩之后,由于空间不够,内核也没有解压到正确的地址,必须通过代码搬移来搬到指定的地址。搬运过程中有可能会覆盖掉现在运行的这段代码,所以必须将有可能会执行到的代码搬运到安全的地方,这里用的是解压缩了的代码的后面。

add r0, r0, #127
bic r0, r0, #127 @ align the kernel length
/*
* r0 = decompressed kernel length
* r1-r3 = unused
* r4 = kernel execution address
* r5 = decompressed kernel start
* r6 = processor ID
* r7 = architecture ID
* r8 = atags pointer
* r9-r14 = corrupted
*/
add r1, r5, r0 @ end of decompressed kernel
adr r2, reloc_start
ldr r3, LC1
add r3, r2, r3
1: ldmia r2!, {r9 - r14} @ copy relocation code
stmia r1!, {r9 - r14}
ldmia r2!, {r9 - r14}
stmia r1!, {r9 - r14}
cmp r2, r3
blo 1b

bl cache_clean_flush//因为有代码搬移,所以必须先清理(clean)清除(flush)cache。
add pc, r5, r0 @ call relocation code

decompress_kernel共有4个参数,解压的内核地址、缓存区首地址、缓存区尾地址、和芯片ID,返回解压缩代码的长度。

/*
* We're not in danger of overwriting ourselves. Do this the simple way.
*
* r4 = kernel execution address
* r7 = architecture ID
*/
wont_overwrite: mov r0, r4
mov r3, r7
bl decompress_kernel
b call_kernel

针对于不会出现代码覆盖的情况,就简单了。直接解压缩内核并且跳转到首地址运行。call_kernel这个函数我们会在下面分析它。

.type LC0, #object
LC0: .word LC0 @ r1
.word __bss_start @ r2
.word _end @ r3
.word zreladdr @ r4
.word _start @ r5
.word _got_start @ r6
.word _got_end @ ip
.word user_stack+4096 @ sp
LC1: .word reloc_end - reloc_start
.size LC0, . - LC0

上面这个就是刚才我们说过的地址表,里面有几个符号的地址定义。LC0是在这里定义的。Zreladdr是在当前目录下的Makfile里定义的。其他的符号是在lds里定义的。

下面我们来分析一下有关cache和mmu的代码。通过这些代码我们可以看到Linux的高手们是如何通过汇编来实现各个ARM处理器的识别,以达到通用的目的。
/*
* Turn on the cache. We need to setup some page tables so that we
* can have both the I and D caches on.
*
* We place the page tables 16k down from the kernel execution address,
* and we hope that nothing else is using it. If we're using it, we
* will go pop!
*
* On entry,
* r4 = kernel execution address
* r6 = processor ID
* r7 = architecture number
* r8 = atags pointer
* r9 = run-time address of "start" (???)
* On exit,
* r1, r2, r3, r9, r10, r12 corrupted
* This routine must preserve:
* r4, r5, r6, r7, r8
*/
.align 5
cache_on: mov r3, #8 @ cache_on function
b call_cache_fn

这里涉及到了很多MMU、cache、writebuffer、TLB的操作和协处理器的编程。具体编程的东西,我就不想多说了,可以对这ARM的手册逐行的理解。至于为什么要这样做,熟悉了他们的工作原理后也就不难理解了。因为这里包含了太多的代码搬运、解压等费时的操作,所以打开cache是有必要的。由于要用到数据 cache所以需要对mmu进行配置。为了简单这里制作了一级映射,而且是物理地址和虚拟地址相同的1:1映射。

__setup_mmu: sub r3, r4, #16384 @ Page directory size
bic r3, r3, #0xff @ Align the pointer
bic r3, r3, #0x3f00
/*
* Initialise the page tables, turning on the cacheable and bufferable
* bits for the RAM area only.
*/
mov r0, r3
mov r9, r0, lsr #18
mov r9, r9, lsl #18 @ start of RAM
add r10, r9, #0x10000000 @ a reasonable RAM size
mov r1, #0x12
orr r1, r1, #3 <<> start of RAM
orrhs r1, r1, #0x0c @ set cacheable, bufferable
cmp r1, r10 @ if virt > end of RAM
bichs r1, r1, #0x0c @ clear cacheable, bufferable
str r1, [r0], #4 @ 1:1 mapping
add r1, r1, #1048576
teq r0, r2
bne 1b

参考下面的注释,如果当前在flash中运行,我们再映射2MB。就算是当前在RAM中执行其实也没关系,只不过是做了重复工作。

/*
* If ever we are running from Flash, then we surely want the cache
* to be enabled also for our execution instance... We map 2MB of it
* so there is no map overlap problem for up to 1 MB compressed kernel.
* If the execution is in RAM then we would only be duplicating the above.
*/
mov r1, #0x1e
orr r1, r1, #3 << 10
mov r2, pc, lsr #20
orr r1, r1, r2, lsl #20
add r0, r3, r2, lsl #2
str r1, [r0], #4
add r1, r1, #1048576
str r1, [r0]
mov pc, lr

__armv4_cache_on:
mov r12, lr
bl __setup_mmu
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
mrc p15, 0, r0, c1, c0, 0 @ read control reg
orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
orr r0, r0, #0x0030
bl __common_cache_on
mov r0, #0
mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
mov pc, r12

__common_cache_on:
#ifndef DEBUG
orr r0, r0, #0x000d @ Write buffer, mmu
#endif
mov r1, #-1
mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
mcr p15, 0, r1, c3, c0, 0 @ load domain access control
mcr p15, 0, r0, c1, c0, 0 @ load control register
mov pc, lr

/*
* All code following this line is relocatable. It is relocated by
* the above code to the end of the decompressed kernel image and
* executed there. During this time, we have no stacks.
*
* r0 = decompressed kernel length
* r1-r3 = unused
* r4 = kernel execution address
* r5 = decompressed kernel start
* r6 = processor ID
* r7 = architecture ID
* r8 = atags pointer
* r9-r14 = corrupted
*/

下面这段代码是在解压空间不够的情况下需要重新定位的,具体原因上面已经说明。

.align 5
reloc_start: add r9, r5, r0
debug_reloc_start
mov r1, r4
1:
.rept 4
ldmia r5!, {r0, r2, r3, r10 - r14} @ relocate kernel
stmia r1!, {r0, r2, r3, r10 - r14}
.endr

cmp r5, r9
blo 1b
debug_reloc_end

这是最后一个函数了,这个时候一切实质性的工作已经做完。关闭cache,并跳转到真正的内核入口。

call_kernel: bl cache_clean_flush
bl cache_off
mov r0, #0 @ must be zero
mov r1, r7 @ restore architecture number
mov r2, r8 @ restore atags pointer
mov pc, r4 @ call kernel

/*
* Here follow the relocatable cache support functions for the
* various processors. This is a generic hook for locating an
* entry and jumping to an instruction at the specified offset
* from the start of the block. Please note this is all position
* independent code.
*
* r1 = corrupted
* r2 = corrupted
* r3 = block offset
* r6 = corrupted
* r12 = corrupted
*/

通过下面函数我们可以通过proc_types结构体数组我们可以顺利的找到现在的处理器型号,并且会根据R3的偏移量跳转到相应的函数中。里面涉及到协处理器CP15中c0的操作,如果有疑问,可以参考ARM相关手册。

call_cache_fn: adr r12, proc_types
mrc p15, 0, r6, c0, c0 @ get processor ID
1: ldr r1, [r12, #0] @ get value
ldr r2, [r12, #4] @ get mask
eor r1, r1, r6 @ (real ^ match)
tst r1, r2 @ & mask
addeq pc, r12, r3 @ call cache function
add r12, r12, #4*5
b 1b

/*
* Table for cache operations. This is basically:
* - CPU ID match
* - CPU ID mask
* - 'cache on' method instruction
* - 'cache off' method instruction
* - 'cache flush' method instruction
*
* We match an entry using: ((real_id ^ match) & mask) == 0
*
* Writethrough caches generally only need 'on' and 'off'
* methods. Writeback caches _must_ have the flush method
* defined.
*/
.type proc_types,#object
proc_types:
.word 0x41560600 @ ARM6/610
.word 0xffffffe0
b __arm6_cache_off @ works, but slow
b __arm6_cache_off
mov pc, lr
@ b __arm6_cache_on @ untested
@ b __arm6_cache_off
@ b __armv3_cache_flush

.word 0x00000000 @ old ARM ID
.word 0x0000f000
mov pc, lr
mov pc, lr
mov pc, lr

.word 0x41007000 @ ARM7/710
.word 0xfff8fe00
b __arm7_cache_off
b __arm7_cache_off
mov pc, lr

.word 0x41807200 @ ARM720T (writethrough)
.word 0xffffff00
b __armv4_cache_on
b __armv4_cache_off
mov pc, lr

.word 0x00007000 @ ARM7 IDs
.word 0x0000f000
mov pc, lr
mov pc, lr
mov pc, lr

@ Everything from here on will be the new ID system.

.word 0x4401a100 @ sa110 / sa1100
.word 0xffffffe0
b __armv4_cache_on
b __armv4_cache_off
b __armv4_cache_flush

.word 0x6901b110 @ sa1110
.word 0xfffffff0
b __armv4_cache_on
b __armv4_cache_off
b __armv4_cache_flush

@ These match on the architecture ID

.word 0x00020000 @ ARMv4T
.word 0x000f0000
b __armv4_cache_on
b __armv4_cache_off
b __armv4_cache_flush

.word 0x00050000 @ ARMv5TE
.word 0x000f0000
b __armv4_cache_on
b __armv4_cache_off
b __armv4_cache_flush

.word 0x00060000 @ ARMv5TEJ
.word 0x000f0000
b __armv4_cache_on
b __armv4_cache_off
b __armv4_cache_flush

.word 0x00070000 @ ARMv6
.word 0x000f0000
b __armv4_cache_on
b __armv4_cache_off
b __armv6_cache_flush

.word 0 @ unrecognised type
.word 0
mov pc, lr
mov pc, lr
mov pc, lr

.size proc_types, . - proc_types

/*
* Turn off the Cache and MMU. ARMv3 does not support
* reading the control register, but ARMv4 does.
*
* On entry, r6 = processor ID
* On exit, r0, r1, r2, r3, r12 corrupted
* This routine must preserve: r4, r6, r7
*/
.align 5
cache_off: mov r3, #12 @ cache_off function
b call_cache_fn

//代码略

这里分配了4K的空间用来做堆栈。

reloc_end:

.align
.section ".stack", "w"
user_stack: .space 4096

ARM Linux Boot Sequence

ARM Linux Boot Sequence

The following traces the Linux boot sequence for ARM-based systems in the 2.6.18 kernel. It looks at just the earliest stages of the boot process, until the generic non-processor-specific start_kernel function is called. The line numbers of each statement are in parenthese at the end of the line.

zImage decompression

  • arch/arm/boot/compressed/head.S: start (108)

    • First code executed, jumped to by the bootloader, at label "start" (108)

    • save contents of registers r1 and r2 in r7 and r8 to save off architecture ID and atags pointer passed in by bootloader (118)

    • execute arch-specific code (inserted at 146)

      • arch/arm/boot/compressed/head-xscale.S or other arch-specific code file

      • added to build in arch/arm/boot/compressed/Makefile

      • linked into head.S by linker section declaration: .section “start”

      • flush cache, turn off cache and MMU

    • load registers with stored parameters (152)

      • sp = stack pointer for decompression code (152)

      • r4 = zreladdr = kernel entry point physical address

    • check if running at link address, and fix up global offset table if not (196)

    • zero decompression bss (205)

    • call cache_on to turn on cache (218)

      • defined at arch/arm/boot/compressed/head.S (320)

      • call call_cache_fn to turn on cache as appropriate for processor variant

        • defined at arch/arm/boot/compressed/head.S (505)

        • walk through proc_types list (530) until find corresponding processor

        • call cache-on function in list item corresponding to processor (511)

          • for ARMv5tej core, cache_on function is __armv4_mmu_cache_on (417)

            • call setup_mmu to set up initial page tables since MMU must be on for cache to be on (419)

            • turn on cache and MMU (426)

    • check to make sure won't overwrite image during decompression; assume not for this trace (232)

    • call decompress_kernel to decompress kernel to RAM (277)

    • branch to call_kernel (278)

      • call cache_clean_flush to flush cache contents to RAM (484)

      • call cache_off to turn cache off as expected by kernel initialization routines (485)

      • jump to start of kernel in RAM (489)

        • jump to address in r4 = zreladdr from previous load

          • zreladdr = ZRELADDR = zreladdr-y

          • zreladdr-y specified in arch/arm/mach-vx115/Makefile.boot



ARM-specific kernel code

  • arch/arm/kernel/head.S: stext (72)

    • call __lookup_processor_type (76)

      • defined in arch/arm/kernel/head-common.S (146)

      • search list of supported processor types __proc_info_begin (176)

        • kernel may be built to support more than one processor type

        • list of proc_info_list structs

          • defined in arch/arm/mm/proc-arm926.S (467) and other corresponding proc-*.S files

          • linked into list by section declaration: .section ".proc.info.init"

      • return pointer to proc_info_list struct corresponding to processor if found, or loop in error if not

    • call __lookup_machine_type (79)

      • defined in arch/arm/kernel/head-common.S (194)

      • search list of supported machines (boards)

        • kernel may be built to support more than one board

        • list of machine_desc structs

          • machine_desc struct for boards defined in board-specific file vx115_vep.c

          • linked into list by section declaration that's part of MACHINE_DESC macro

      • return pointer to machine_desc struct corresponding to machine (board)

    • call __create_page_tables to set up initial MMU tables (82)

    • set lr to __enable_mmu, r13 to address of __switch_data (91, 93)

      • lr and r13 used for jumps after the following calls

      • __switch_data defined in arch/arm/kernel/head-common.S (15)

    • call the __cpu_flush function pointer in the previously returned proc_info_list struct (94)

      • offset is #PROCINFO_INITFUNC into struct

      • this function is __arm926_setup for the ARM 926EJ-S, defined in arch/arm/mm/proc-arm926.S (392)

        • initialize caches, writebuffer

        • jump to lr, previously set to address of __enable_mmu

    • __enable_mmu (147)

      • set page table pointer (TTB) in MMU hardware so it knows where to start page-table walks (167)

      • enable MMU so running with virtual addresses (185)

      • jump to r13, previously set to address of __switch_data, whose first field is address of __mmap_switched

        • __switch_data defined in arch/arm/kernel/head-common.S (15)



  • arch/arm/kernel/head-common.S: __mmap_switched (35)

    • copy data segment to RAM (39)

    • zero BSS (45)

    • branch to start_kernel (55)



Processor-independent kernel code

  • init/main.c: start_kernel (456)


In either case, the following conditions must be met:

(启动内核时需要满足的必要条件)

  • CPU register settings

    • r0 = 0.

    • r1 = machine type number discovered in (3) above.

    • r2 = physical address of tagged list in system RAM.

  • CPU mode

    • All forms of interrupts must be disabled (IRQs and FIQs.)

    • The CPU must be in SVC mode. (A special exception exists for Angel.)

  • Caches, MMUs

    • The MMU must be off.

    • Instruction cache may be on or off.

    • Data cache must be off and must not contain any stale data.

  • Devices

    • DMA to/from devices should be quiesced.

  • The boot loader is expected to call the kernel image by jumping directly to the first instruction of the kernel image.


Tuesday, September 9, 2008

进取

多付出一点点的最大好处之一,就是使你重视个人进取心.

有二种人绝不会成大器,一种是非别人要他做,否则绝不主动做事的人;另一种人则是即使别人要他做,也做不好事情的人。那些不需要别人催促,就会动去做应做的事,而且不会半途而废的人必将成功,这种人懂得要求自己多付出一点点,而且做得比别人预期的更多。

个人进取心,是实现目标不可少的要素,会使人进步,使自己受到注意并获取机会。

反省一下,自己是否具备以下特质并如何增加和强化这些特质呢?

1,订定明确目标。

2,不断追求明确目标的动机。

3,成立智囊团以期获得达到目标的力量。

4,独立。

5,自律。

6,坚毅精神。

7,丰富想像力。

8,迅速且明确的决策的习惯。

9,以事实为根据发表意见而非猜测。

10,要求自己多付出一点点的习惯。

11,激发热枕和控制热枕的能力。

12,要求细节的习惯。

13,听取批评而不动怒的能力。

14,一次致力于一项工作的能力。

15,为自己的行为负更多责任的能力。

16,为属下的过失承担所有责任的意愿。

17,对属下和朋友付出耐心。

18,随时保持积极心态。

19,坚定信心。

20,贯彻到底的习惯。

21,强调彻底而非强调速度的习惯。

无疑,其中有许多特质是熟悉的,可能会认为 “我已经有这些特质”了。

上述原则的本质在于这些原则都是息息相关的,不可能只发挥其中一项,而不去理会其他项。如何不经由个人进取心,来运用信心而又能发挥呢?而你又如何能在没有订定明确目标的情况下,发挥个人进取心呢?事物是普遍联系的,相辅相成,缺一不可!

Monday, September 8, 2008

毛润之

毛泽东作为继曾国藩之后的另外一个文人带兵的典型,也是很值得关注的,某些优秀点非常值得借鉴和学习。

看其著作,积累心得,灵活运用!

ubuntu搭建tftp和nfs

安装配置tftp:

1. 首先安装tftp和tftpd,前者是客户端,后者是服务器。因为tftp是要inetd来控制的,而ubuntu类的系统,默认是没有安装inetd的,安装一下。(我第一次失败了就是因为没有安装正确的inetd)
#apt-get install tftp tftpd
#apt-get install netkit-inetd

2、在/目录下建一个tftpboot, 把属性改成777。

#cd /
#mkdir tftpboot
#chmod 777 tftpboot

3、修改/etc/inetd.conf
#emacs /etc/inetd.conf
tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /tftpboot
#:INTERNAL: Internal services
#echo stream tcp nowait root internal
#echo dgram udp wait root internal
#chargen stream tcp nowait root internal
#chargen dgram udp wait root internal
#discard stream tcp nowait root internal
#discard dgram udp wait root internal
#daytime stream tcp nowait root internal
#daytime dgram udp wait root internal
#time stream tcp nowait root internal
#time dgram udp wait root internal
#tftp dgram udp wait nobody /usr/sbin/tcpd/usr/sbin/in.tftpd/tftpboot

4、重新加载inetd进程
#/etc/init.d/inetd reload

5、测试tftpd服务是否成功
tftp localhost
tftp> put mydoc.tar.gz
tftp> put test.log
tftp> get test.log
tftp> get mydoc.tar.gz
tftp>

上述表明在主机上测试tftp成功,在DM6446板子上,以root登录,使用busybox附带的tftp客户端上传/下载文件:
root@DVS6446:/tftp -r thttpd.conf -g 192.168.1.19

当然,安装tftp也可以这样:

首先介要安装的三个软件包:

1.xinetd:xinetd是一个守护进程,用于处理对各种服务的请求,当xinetd监控的服务请求出现时,xinetd会使用/etc /xinetd.conf文件 读取/etc/xinetd.d目录中的配置文件,然后,根据所请求服务的xinetd.conf文件内容,启动相应的程序.

2.tftpd :服务端

3.tftp:客户端

第一步:安装相关软件包

sudo apt-get install tftpd (服务端)
sudo apt-get install tftp (客户端)
sudo apt-get install xinetd

第二步:建立配置文件

#cd /etc/xinetd.d/

#emacs tftp

输入下列配置信息:

service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}

存盘退出

3、建立tftp服务文件目录
mkdir /tftpboot
4、重新启动服务
/etc/init.d/xinetd restart


安装配置nfs:
主机host:
OS:ubuntu 8.04 kernel 2.6.24-17
IP:192.168.1.19
netmask:255.255.255.0

板子:
OS:MV4.0 kernel2.6.10
IP:192.168.1.24
netmask:255.255.255.0

busybox v1.1.0

以下为搭建NFS全过程:

1. Install NFS software
$ sudo apt-get install nfs-common
$ sudo apt-get install nfs-kernel-server

2.在/建立共享项目nfsboot
#mkdir nfsboot
#chmod 777 -R nfsboot/
保证使用者都能够读、写、执行

3.编辑/etc/exports
#emacs /etc/exports
/nfsboot 192.168.1.*(rw,sync,no_root_squash)
其中/nfsboot表示主机要共享的目录,192.168.1.*为主机所允许访问的机器名,即处于192.168.1.*IP段的机器都可以访问共享目录。

4.#exportfs -r
更新exportfs

5.然后重启nfs服务,执行下面命令
#/etc/init.d/portmap restart
#/etc/init.d/nfs-kernel-server restart

成功启动后,执行
#showmount -e
显示如下:
/nfsboot 192.168.1.*

6.本机测试
在主机上测试一下nfs服务,具体过程如下:
#mount -t nfs 192.168.1.19:/nfsboot /mnt
即把主机上/nfsboot目录mount到主机/mnt目录,正常,可以顺利mount成功。

7.在板子(客户端)进入shell,以root登录,设置板子的IP地址和子网掩码跟主机在一个地址段
#ifconfig eth0 address 192.168.1.24 netmask 255.255.255.0

8.然后相互ping,均能够ping通。
在板子上mount共享目录,将共享目录mount到/root
#mount -t nfs 192.168.1.19:/nfsboot /root
等待一段时间之后,报错如下:
root@DVS6446:/# mount -t nfs 192.168.1.19:/nfsboot /mnt
mount: RPC: Timed out
mount: nfsmount failed: Bad file descriptor
mount: Mounting 192.168.1.19:/nfsboot on /mnt failed: No such file or directory

以上描述的就是开发环境的设置和出错信息,搞了大半天,也参阅了一些帖子,问题始终没有能够解决.最后查阅网络上有关文章,说有可能是防火墙搞的鬼,仔细 检查了下,发现我的unbutu8.04 已经安装了Firestarter 1.0.3,而且处于运行状态,马上关闭之,然后重启网络,再mount即可。

拉里.埃里森耶鲁大学演讲稿

原文:

"Graduates of Yale University, I apologize if you have endured this type of prologue before, but I want you to do something for me. Please, take a good look around you. Look at the classmate on your left. Look at the classmate on your right.

Now, consider this: five years from now, 10 years from now, even thirty years from now, odds are the person on your left is going to be a loser. The person on your right, meanwhile, will also be a loser. And you, in the middle? What can you expect? Loser. Loserhood. Loser Cum Laude. In fact, as I look out before me today, I don’t see a thousand hopes for a bright tomorrow. I don’t see a thousand future leaders in a thousand industries. I see a thousand losers. You’re upset. That’s understandable. After all, how can I,Lawrence "Larry" Ellison, college dropout, have the audacity to spout such heresy to the graduating class of one of the nation’s most prestigious institutions?

I’ll tell you why. Because I, Lawrence "Larry" Ellison, second richest man on the planet, am college dropout, and you are not. Because Bill Gates, richest man on the planet-for now anyway-is a college dropout, and you are not. Because Paul Allen, the third richest man on the planet, dropped out of college, and you did not. And for good measure, because Michael Dell, No.9 on the list and moving up fast, is a college dropout, and you, yet again, are not.

Hmm ... you’re very upset. That’s understandable. So let me stroke your Egos for a moment by pointing out, quite sincerely, that your diplomas were not attained in vain. Most of you, I imagine, have spent four to five years here, and in many ways what you’ve learned and endured will serve you well in the years ahead. You’ve established good work habits. You’ve established a network of people that will help you down the road. And you’ve established what will be lifelong relationships with the word "therapy." All that of is good.

For in truth, you will need that network. You will need those strong work habits. You will need that therapy. You will need them because you didn’t drop out, and so you will never be among the richest people in the world. Oh sure, you may, perhaps, work your way up to #10 or #11, like Steve Ballmer. But then, I don’t have to tell you who he really works for, do I? And for the record, he dropped out of grad school. Bit of a late bloomer.

Finally, I realize that many of you, and hopefully by now most of you, Are wondering, "Is there anything I can do? Is there any hope for me at all? Actually, no. It’s too late. You’ve absorbed too much, think you know too much. You’re not 9 anymore. You have a built-in cap,and I’m not referring to the mortarboards on your heads.

Hmm ... you’re really very upset. That’s understandable. So perhaps this Could be a good time to bring up the silver lining. Not for you, Class of ’00. You are a write-off, so I’ll let you slink off to your pathetic $200,000-a-year jobs, where your cheques will be signed by former classmates who dropped out two years ago. Instead, I want to give hope to any underclassmen here today. I say to you, and I can’t stress this enough: leave. Pack your things and your ideas and don’t come back. Drop out. Start up. For I can tell you that a cap and gown will keep you down just as surely as these security guards dragging me off this stage are keeping me down..."

翻译

耶鲁的毕业生们,我很抱歉---如果你们不喜欢这样的开场白。我想请你们为我做一件事。请你---好好看一看周围,看一看站在你左边的同学,看一看站在你右边的同学。

请你设想这样的情况:从现在起5年之后,10年之后,或30年之后,今天站在你左边的这个人会是一个失败者;右边的这个人,同样,也是个失败者。而你,站在中间的家伙,你以为会怎样?一样是失败者。失败的经历。失败的优等生。

说实话,今天我站在这里,并没有看到一千个毕业生的灿烂未来。我没有看到一千个行业的一千名卓越领导者,我只看到了一千个失败者。你们感到沮丧,这是可以理解的。为什么,我,埃里森,一个退学生,竟然在美国最具声望的学府里这样厚颜地散布异端?

我来告诉你原因。因为,我,埃里森,这个行星上第二富有的人,是个退学生,而你不是。因为比尔盖茨,这个行星上最富有的人---就目前而言---是个退学 生,而你不是。因为艾伦,这个行星上第三富有的人,也退了学,而你没有。再来一点证据吧,因为戴尔,这个行星上第九富有的人---他的排位还在不断上升, 也是个退学生。而你,不是。

你们非常沮丧,这是可以理解的。

你们将来需要这些有用的工作习惯。你将来需要这种“治疗”`。你需要它们,因为你没辍学,所以你永远不会成为世界上最富有的人。哦,当然,你可以, 也许,以你的方式进步到第10位,第11位,就像Steve。不过,我没有告诉你他在为谁工作,是吧?根据记载,他是研究生时辍的学,开化得稍晚了些。

现在,我猜想你们中间很多人,也许是绝大多数人,正在琢磨,"能做什么?我究竟有没有前途?"当然没有。太晚了,你们已经吸收了太多东西,以为自己懂得太多。你们再也不是19岁了。你们有了“内置“的帽子,哦,我指的可不是你们脑袋上的学位帽。

嗯......你们已经非常沮丧啦。这是可以理解的。所以,现在可能是讨论实质的时候啦---绝不是为了你们,2000年毕业生。你们已经被报销, 不予考虑了。我想,你们就偷偷摸摸去干那年薪20万的可怜工作吧,在那里,工资单是由你两年前辍学的同班同学签字开出来的。事实上,我是寄希望于眼下还没 有毕业的同学。我要对他们说,离开这里。收拾好你的东西,带着你的点子,别再回来。退学吧,开始行动。

我要告诉你,一顶帽子一套学位服必然要让你沦落......就像这些保安马上要把我从这个讲台上撵走一样必然......(此时,拉里埃里森被带离了讲台)

Sunday, September 7, 2008

孙子兵法

计篇

孙子曰:兵者,国之大事,死生之地,存亡之道,不可不察也。

故经之以五事,校之以计而索其情:一曰道,二曰天,三曰地,四曰将,五曰法。道者,令民于上同意也,可以与之死,可以与之生,而不畏危。天者,阴阳、寒 暑、时制也。地者,远近、险易、广狭、死生也。将者,智、信、仁、勇、严也。法者,曲制、官道、主用也。凡此五者,将莫不闻,知之者胜,不知之者不胜。故 校之以计而索其情,曰:主孰有道?将孰有能?天地孰得?法令孰行?兵众孰强?士卒孰练?赏罚孰明?吾以此知胜负矣。

将听吾计,用之必胜,留之;将不听吾计,用之必败,去之。

计利以听,乃为之势,以佐其外。势者,因利而制权也。

兵者,诡道也。故能而示之不能,用而示之不用,近而示之远,远而示之近。利而诱之,乱而取之,实而备之,强而避之,怒而挠之,卑而骄之,佚而劳之,亲而离之,攻其无备,出其不意。此兵家之胜,不可先传也。

夫未战而庙算胜者,得算多也;未战而庙算不胜者,得算少也。多算胜,少算不胜,而况于无算乎!吾以此观之,胜负见矣。

作战篇

孙子曰:凡用兵之法,驰车千驷,革车千乘,带甲十万,千里馈粮。则内外之费,宾客之用,胶漆之材,车甲之奉,日费千金,然后十万之师举矣。

其用战也胜,久则钝兵挫锐,攻城则力屈,久暴师则国用不足。夫钝兵挫锐,屈力殚货,则诸侯乘其弊而起,虽有智者,不能善其后矣。故兵闻拙速,未睹巧之久也。夫兵久而国利者,未之有也。故不尽知用兵之害者,则不能尽知用兵之利也。

善用兵者,役不再籍,粮不三载,取用于国,因粮于敌,故军食可足也。

国之贫于师者远输,远输则百姓贫;近于师者贵卖,贵卖则百姓财竭,财竭则急于丘役。力屈、财殚,中原内虚于家。百姓之费,十去其七;公家之费,破车罢马,甲胄矢弩,戟盾蔽橹,丘牛大车,十去其六。

故智将务食于敌。食敌一钟,当吾二十钟;萁杆一石,当吾二十石。

故杀敌者,怒也;取敌之利者,货也。故车战,得车十乘已上,赏其先得者,而更其旌旗,车杂而乘之,卒善而养之,是谓胜敌而益强。

故兵贵胜,不贵久。

故知兵之将,生民之司命。国家安危之主也。

谋攻篇

孙子曰:凡用兵之法,全国为上,破国次之;全军为上,破军次之;全旅为上,破旅次之;全卒为上,破卒次之;全伍为上,破伍次之。是故百战百胜,非善之善者也;不战而屈人之兵,善之善者也。

故上兵伐谋,其次伐交,其次伐兵,其下攻城。攻城之法,为不得已。修橹[车贲][“温”字“氵”旁换“车”],具器械,三月而后成,距[“门”内上“西”下“土”],又三月而后已。将不胜其忿而蚁附之,杀士卒三分之一而城不拔者,此攻之灾也。

故善用兵者,屈人之兵而非战也,拔人之城而非攻也,毁人之国而非久也,必以全争于天下,故兵不顿而利可全,此谋攻之法也。

故用兵之法,十则围之,五则攻之,倍则分之,敌则能战之,少则能逃之,不若则能避之。故小敌之坚,大敌之擒也。

夫将者,国之辅也。辅周则国必强,辅隙则国必弱。

故君之所以患于军者三:不知军之不可以进而谓之进,不知军之不可以退而谓之退,是谓縻军。不知三军之事,而同三军之政者,则军士惑矣;不知三军之权,而同三军之任,则军士疑矣。三军既惑且疑,则诸侯之难至矣。是谓乱军引胜。

故知胜有五:知可以战与不可以战者胜;识众寡之用者胜;上下同欲者胜;以虞待不虞者胜;将能而君不御者胜。此五者,知胜之道也。

故曰:知己知彼者,百战不殆;不知彼而知己,一胜一负;不知彼,不知己,每战必殆。

形篇

孙子曰:昔之善战者,先为不可胜,以待敌之可胜。不可胜在己,可胜在敌。故善战者,能为不可胜,不能使敌之可胜。故曰:胜可知而不可为。

不可胜者,守也;可胜者,攻也。守则不足,攻则有余。善守者,藏于九地之下;善攻者,动于九天之上,故能自保而全胜也。

见胜不过众人之所知,非善之善者也;战胜而天下曰善,非善之善者也。故举秋毫不为多力,见日月不为明目,闻雷霆不为聪耳。古之所谓善战者,胜于易胜者也。 故善战者之胜也,无智名,无勇功,故其战胜不忒。不忒者,其所措必胜,胜已败者也。故善战者,立于不败之地,而不失敌之败也。是故胜兵先胜而后求战,败兵 先战而后求胜。善用兵者,修道而保法,故能为胜败之政。

兵法:一曰度,二曰量,三曰数,四曰称,五曰胜。地生度,度生量,量生数,数生称,称生胜。故胜兵若以镒称铢,败兵若以铢称镒。胜者之战民也,若决积水于千仞之溪者,形也。

势篇

孙子曰:凡治众如治寡,分数是也;斗众如斗寡,形名是也;三军之众,可使必受敌而无败者,奇正是也;兵之所加,如以[“瑕”的“王”旁换“石”旁]投卵者,虚实是也。

凡战者,以正合,以奇胜。故善出奇者,无穷如天地,不竭如江河。终而复始,日月是也;死而更生,四时是也。声不过五,五声之变,不可胜听也;色不过五,五 色之变,不可胜观也;味不过五,五味之变,不可胜尝也;战势不过奇正,奇正之变,不可胜穷也。奇正相生,如循环之无端,孰能穷之?

激水之疾,至于漂石者,势也;鸷鸟之疾,至于毁折者,节也。是故善战者,其势险,其节短。势如[弓广]弩,节如发机。

纷纷纭纭,斗乱而不可乱也;浑浑沌沌,形圆而不可败也。乱生于治,怯生于勇,弱生于强。治乱,数也;勇怯,势也;强弱,形也。故善动敌者,形之,敌必从之;予之,敌必取之。以利动之,以卒待之。

故善战者,求之于势,不责于人,故能择人而任势。任势者,其战人也,如转木石。木石之性,安则静,危则动,方则止,圆则行。故善战人之势,如转圆石于千仞之山者,势也。

虚实篇

孙子曰:凡先处战地而待敌者佚,后处战地而趋战者劳。故善战者,致人而不致于人。能使敌人自至者,利之也;能使敌人不得至者,害之也。故敌佚能劳之,饱能饥之,安能动之。

出其所必趋,趋其所不意。行千里而不劳者,行于无人之地也;攻而必取者,攻其所不守也。守而必固者,守其所不攻也。故善攻者,敌不知其所守;善守者,敌不知其所攻。微乎微乎,至于无形;神乎神乎,至于无声,故能为敌之司命。

进而不可御者,冲其虚也;退而不可追者,速而不可及也。故我欲战,敌虽高垒深沟,不得不与我战者,攻其所必救也;我不欲战,画地而守之,敌不得与我战者,乖其所之也。

故形人而我无形,则我专而敌分;我专为一,敌分为十,是以十攻其一也,则我众而敌寡;能以众击寡者,则吾之所与战者约矣。吾所与战之地不可知,不可知,则 敌所备者多,敌所备者多,则吾所与战者寡矣。故备前则后寡,备后则前寡;备左则右寡,备右则左寡;无所不备,则无所不寡。寡者,备人者也;众者,使人备己 者也。

故知战之地,知战之日,则可千里而会战;不知战地,不知战日,则左不能救右,右不能救左,前不能救后,后不能救前,而况远者数十里,近者数里乎?以吾度之,越人之兵虽多,亦奚益于胜败哉?故曰:胜可为也。敌虽众,可使无斗。

故策之而知得失之计,作之而知动静之理,形之而知死生之地,角之而知有余不足之处。故形兵之极,至于无形;无形,则深间不能窥,智者不能谋。因形而错胜于众,众不能知;人皆知我所以胜之形,而莫知吾所以制胜之形。故其战胜不复,而应形于无穷。

夫兵形象水,水之行,避高而趋下;兵之形,避实而击虚。水因地而制流,兵因敌而制胜。故兵无常势,水无常形,能因敌变化而取胜者,谓之神。故五行无常胜,四时无常位,日有短长,月有死生。

军争篇

孙子曰:凡用兵之法,将受命于君,合军聚众,交和而舍,莫难于军争。军争之难者,以迂为直,以患为利。故迂其途而诱之以利,后人发,先人至,此知迂直之计者也。

故军争为利,军争为危。举军而争利则不及,委军而争利则辎重捐。是故卷甲而趋,日夜不处,倍道兼行,百里而争利,则擒三将军,劲者先,疲者后,其法十一而 至;五十里而争利,则蹶上将军,其法半至;三十里而争利,则三分之二至。是故军无辎重则亡,无粮食则亡,无委积则亡。

故不知诸侯之谋者,不能豫交;不知山林、险阻、沮泽之形者,不能行军;不用乡导者,不能得地利。故兵以诈立,以利动,以分和为变者也。故其疾如风,其徐如 林,侵掠如火,不动如山,难知如阴,动如雷震。掠乡分众,廓地分利,悬权而动。先知迂直之计者胜,此军争之法也。

《军政》曰:“言不相闻,故为金鼓;视不相见,故为旌旗。”夫金鼓、旌旗者,所以一人之耳目也。人既专一,则勇者不得独进,怯者不得独退,此用众之法也。故夜战多火鼓,昼战多旌旗,所以变人之耳目也。

故三军可夺气,将军可夺心。是故朝气锐,昼气惰,暮气归。故善用兵者,避其锐气,击其惰归,此治气者也。以治待乱,以静待哗,此治心者也。以近待远,以佚待劳,以饱待饥,此治力者也。无邀正正之旗,勿击堂堂之陈,此治变者也。

故用兵之法,高陵勿向,背丘勿逆,佯北勿从,锐卒勿攻,饵兵勿食,归师勿遏,围师必阙,穷寇勿迫,此用兵之法也。

九变篇

孙子曰:凡用兵之法,将受命于君,合军聚众,圮地无舍,衢地交合,绝地无留,围地则谋,死地则战。涂有所不由,军有所不击,城有所不攻,地有所不争,君命 有所不受。故将通于九变之地利者,知用兵矣;将不通于九变之利者,虽知地形,不能得地之利矣。治兵不知九变之术,虽知五利,不能得人之用矣。

是故智者之虑,必杂于利害,杂于利而务可信也,杂于害而患可解也。

是故屈诸侯者以害,役诸侯者以业,趋诸侯者以利。

故用兵之法,无恃其不来,恃吾有以待也;无恃其不攻,恃吾有所不可攻也。

故将有五危,必死,可杀也;必生,可虏也;忿速,可侮也;廉洁,可辱也;爱民,可烦也。凡此五者,将之过也,用兵之灾也。覆军杀将,必以五危,不可不察也。

行军篇

孙子曰:凡处军、相敌:绝山依谷,视生处高,战隆无登,此处山之军也。绝水必远水;客绝水而来,勿迎之于水内,令半济而击之,利;欲战者,无附于水而迎 客;视生处高,无迎水流,此处水上之军也。绝斥泽,惟亟去无留;若交军于斥泽之中,必依水草而背众树,此处斥泽之军也。平陆处易而右背高,前死后生,此处 平陆之军也。凡此四军之利,黄帝之所以胜四帝也。

凡军好高而恶下,贵阳而贱阴,养生而处实,军无百疾,是谓必胜。丘陵堤防,必处其阳而右背之,此兵之利,地之助也。上雨,水沫至,欲涉者,待其定也。凡地 有绝涧、天井、天牢、天罗、天陷、天隙,必亟去之,勿近也。吾远之,敌近之;吾迎之,敌背之。军行有险阻、潢井、葭苇、山林、[“翳”加“艹”头]荟者, 必谨复索之,此伏奸之所处也。

敌近而静者,恃其险也;远而挑战者,欲人之进也;其所居易者,利也。众树动者,来也;众草多障者,疑也;鸟起者,伏也;兽骇者,覆也;尘高而锐者,车来 也;卑而广者,徒来也;散而条达者,樵采也;少而往来者,营军也。辞卑而益备者,进也;辞强而进驱者,退也;轻车先出居其侧者,陈也;无约而请和者,谋 也;奔走而陈兵者,期也;半进半退者,诱也。杖而立者,饥也;汲而先饮者,渴也;见利而不进者,劳也。鸟集者,虚也;夜呼者,恐也;军扰者,将不重也;旌 旗动者,乱也;吏怒者,倦也;粟马肉食,军无悬[“缸”字右边“工”换“瓦”],不返其舍者,穷寇也。谆谆翕翕,徐与人言者,失众也;数赏者,窘也;数罚 者,困也;先暴而后畏其众者,不精之至也;来委谢者,欲休息也。兵怒而相迎,久而不合,又不相去,必谨察之。

兵非益多也,惟无武进,足以并力、料敌、取人而已;夫惟无虑而易敌者,必擒于人。

卒未亲附而罚之则不服,不服则难用也;卒已亲附而罚不行,则不可用也。故令之以文,齐之以武,是谓必取。令素行以教其民,则民服;令素不行以教其民,则民不服。令素行者,与众相得也。

地形篇

孙子曰:地形有通者,有挂者,有支者,有隘者,有险者,有远者。我可以往,彼可以来,曰通;通形者,先居高阳,利粮道,以战则利。可以往,难以返,曰挂; 挂形者,敌无备,出而胜之;敌若有备,出而不胜,难以返,不利。我出而不利,彼出而不利,曰支;支形者,敌虽利我,我无出也;引而去之,令敌半出而击之, 利。隘形者,我先居之,必盈之以待敌;若敌先居之,盈而勿从,不盈而从之。险形者,我先居之,必居高阳以待敌;若敌先居之,引而去之,勿从也。远形者,势 均,难以挑战,战而不利。凡此六者,地之道也;将之至任,不可不察也。

故兵有走者、有驰者,有陷者,有崩者,有乱者,有北者。凡此六者,非天之灾,将之过也。夫势均,以一击十,曰走。卒强吏弱,曰驰。吏强卒弱,曰陷。大吏怒 而不服,遇敌怼而自战,将不知其能,曰崩。将弱不严,教道不明,吏卒无常,陈兵纵横,曰乱。将不能料敌,以少合众,以弱击强,兵无选锋,曰北。凡此六者, 败之道也;将之至任,不可不察也。

夫地形者,兵之助也。料敌制胜,计险厄、远近,上将之道也。知此而用战者必胜,不知此而用战者必败。故战道必胜,主曰无战,必战可也;战道不胜,主曰必战,无战可也。故进不求名,退不避罪,唯人是保,而利合于主,国之宝也。

视卒如婴儿,故可以与之赴深溪;视卒如爱子,故可与之俱死。厚而不能使,爱而不能令,乱而不能治,譬若骄子,不可用也。

知吾卒之可以击,而不知敌之不可击,胜之半也;知敌之可击,而不知吾卒之不可以击,胜之半也;知敌之可击,知吾卒之可以击,而不知地形之不可以战,胜之半也。故知兵者,动而不迷,举而不穷。故曰:知彼知己,胜乃不殆;知天知地,胜乃不穷。

九地篇

孙子曰:用兵之法,有散地,有轻地,有争地,有交地,有衢地,有重地,有圮地,有围地,有死地。诸侯自战之地,为散地。入人之地而不深者,为轻地。我得则 利,彼得亦利者,为争地。我可以往,彼可以来者,为交地。诸侯之地三属,先至而得天下之众者,为衢地。入人之地深,背城邑多者,为重地。行山林、险阻、沮 泽,凡难行之道者,为圮地。所由入者隘,所从归者迂,彼寡可以击吾之众者,为围地。疾战则存,不疾战则亡者,为死地。是故散地则无战,轻地则无止,争地则 无攻,交地则无绝,衢地则合交,重地则掠,圮地则行,围地则谋,死地则战。

所谓古之善用兵者,能使敌人前后不相及,众寡不相恃,贵贱不相救,上下不相收,卒离而不集,兵合而不齐。合于利而动,不合于利而止。敢问:“敌众而整将来,待之若何?”曰:“先夺其所爱,则听矣。”兵之情主速,乘人之不及。由不虞之道,攻其所不戒也。

凡为客之道,深入则专。主人不克;掠于饶野,三军足食;谨养而勿劳,并气积力,运兵计谋,为不可测。投之无所往,死且不北。死焉不得,士人尽力。兵士甚陷 则不惧,无所往则固,深入则拘,不得已则斗。是故其兵不修而戒,不求而得,不约而亲,不令而信,禁祥去疑,至死无所之。吾士无余财,非恶货也;无余命,非 恶寿也。令发之日,士卒坐者涕沾襟,偃卧者涕交颐,投之无所往者,诸、刿之勇也。

故善用兵者,譬如率然;率然者,常山之蛇也。击其首则尾至,击其尾则首至,击其中则首尾俱至。敢问:“兵可使如率然乎?”曰:“可。”夫吴人与越人相恶 也,当其同舟而济,遇风,其相救也如左右手。是故方马埋轮,未足恃也;齐勇若一,政之道也;刚柔皆得,地之理也。故善用兵者,携手若使一人,不得已也。

将军之事,静以幽,正以治,能愚士卒之耳目,使之无知;易其事,革其谋,使人无识;易其居,迂其途,使人不得虑。帅与之期,如登高而去其梯。帅与之深入诸 侯之地,而发其机,焚舟破釜,若驱群羊,驱而往,驱而来,莫知所之。聚三军之众,投之于险,此谓将军之事也。九地之变,屈伸之利,人情之理,不可不察。

凡为客之道,深则专,浅则散。去国越境而师者,绝地也;四达者,衢地也;入深者,重地也;入浅者,轻地也;背固前隘者,围地也;无所往者,死地也。是故散 地,吾将一其志;轻地,吾将使之属;争地,吾将趋其后;交地,吾将谨其守;衢地,吾将固其结;重地,吾将继其食;圮地,吾将进其涂;围地,吾将塞其阙;死 地,吾将示之以不活。故兵之情,围则御,不得已则斗,过则从。

是故不知诸侯之谋者,不能预交;不知山林、险阻、沮泽之形者,不能行军;不用乡导者,不能得地利。四五者,不知一,非霸王之兵也。夫霸王之兵,伐大国,则 其众不得聚;威加于敌,则其交不得合。是故不争天下之交,不养天下之权,信己之私,威加于敌,故其城可拔,其国可隳。施无法之赏,悬无政之令,犯三军之 众,若使一人。犯之以事,勿告以言;犯之以利,勿告以害。投之亡地然后存,陷之死地然后生。夫众陷于害,然后能为胜败。故为兵之事,在于顺详敌之意,并敌 一向,千里杀将,此谓巧能成事者也。

是故政举之日,夷关折符,无通其使,厉于廊庙之上,以诛其事。敌人开阖,必亟入之。先其所爱,微与之期。践墨随敌,以决战事。是故始如处女,敌人开户;后如脱兔,敌不及拒。

火攻篇

孙子曰:凡火攻有五:一曰火人,二曰火积,三曰火辎,四曰火库,五曰火队。行火必有因,烟火必素具。发火有时,起火有日。时者,天之燥也。日者,月在箕、壁、翼、轸也,凡此四宿者,风起之日也。

凡火攻,必因五火之变而应之。火发于内,则早应之于外。火发兵静者,待而勿攻,极其火力,可从而从之,不可从而止。火可发于外,无待于内,以时发之。火发上风,无攻下风。昼风久,夜风止。凡军必知五火之变,以数守之。

故以火佐攻者明,以水佐攻者强。水可以绝,不可以夺。

夫战胜攻取,而不修其功者,凶。命曰费留。故曰:明主虑之,良将修之,非利不动,非得不用,非危不战。主不可以怒而兴师,将不可以愠而致战。合于利而动, 不合于利而止。怒可以复喜,愠可以复悦;亡国不可以复存,死者不可以复生。故明君慎之,良将警之。此安国全军之道也。

用间篇

孙子曰:凡兴师十万,出征千里,百姓之费,公家之奉,日费千金;内外骚动,怠于道路,不得操事者,七十万家。相守数年,以争一日之胜,而爱爵禄百金,不知 敌之情者,不仁之至也,非人之将也,非主之佐也,非胜之主也。故明君贤将,所以动而胜人,成功出于众者,先知也。先知者,不可取于鬼神,不可象于事,不可 验于度,必取于人,知敌之情者也。

故用间有五:有因间,有内间,有反间,有死间,有生间。五间俱起,莫知其道,是谓神纪,人君之宝也。因间者,因其乡人而用之。内间者,因其官人而用之。反间者,因其敌间而用之。死间者,为诳事于外,令吾间知之,而传于敌间也。生间者,反报也。

故三军之事,莫亲于间,赏莫厚于间,事莫密于间。非圣智不能用间,非仁义不能使间,非微妙不能得间之实。微哉微哉!无所不用间也。间事未发,而先闻者,间与所告者皆死。

凡军之所欲击,城之所欲攻,人之所欲杀,必先知其守将、左右、谒者、门者、舍人之姓名,令吾间必索知之。

必索敌人之间来间我者,因而利之,导而舍之,故反间可得而用也。因是而知之,故乡间、内间可得而使也。因是而知之,故死间为诳事,可使告敌。因是而知之,故生间可使如期。五间之事,主必知之,知之必在于反间,故反间不可不厚也。

昔殷之兴也,伊挚在夏;周之兴也,吕牙在殷。故惟明君贤将,能以上智为间者,必成大功。此兵之要,三军之所恃而动也。

 

 

中国古典文化----孙子兵法(英文版)

SUN TZU ON THE ART OF WAR
THE OLDEST MILITARY TREATISE IN THE WORLD

Translated from the Chinese
By LIONEL GILES, M.A. (1910)

--------------------------------------------------------------------------------
[This is the basic text of Sun Tzu on the Art of War. It was extracted from Mr. Giles' complete work as titled above. The commentary itself, which, of course includes this work embedded within it, has been released as suntzu10.txt (or suntzu10.zip). This is being released only as an adjunct to that work, which contains a wealth of commentary upon this text.]
--------------------------------------------------------------------------------
The Art of War has 13 chapters.
--------------------------------------------------------------------------------

I. LAYING PLANS (计篇)


1. Sun Tzu said: The art of war is of vital importance to the State.

2. It is a matter of life and death, a road either to safety or to ruin. Hence it is a subject of inquiry
which can on no account be neglected.

3. The art of war, then, is governed by five constant factors, to be taken into account in one's deliberations,
when seeking to determine the conditions obtaining in the field.

4. These are: (1) The Moral Law; (2) Heaven; (3) Earth; (4) The Commander; (5) Method and discipline.

5,6. The Moral Law causes the people to be in complete accord with their ruler, so that they will follow him
regardless of their lives, undismayed by any danger.

7. Heaven signifies night and day, cold and heat, times and seasons.

8. Earth comprises distances, great and small; danger and security; open ground and narrow passes;
the chances of life and death.

9. The Commander stands for the virtues of wisdom, sincerely, benevolence, courage and strictness.

10. By method and discipline are to be understood the marshaling of the army in its proper subdivisions,
the graduations of rank among the officers, the maintenance of roads by which supplies may reach the army, and the control of military expenditure.

11. These five heads should be familiar to every general: he who knows them will be victorious; he who knows them
not will fail.

12. Therefore, in your deliberations, when seeking to determine the military conditions, let them be made
the basis of a comparison, in this wise:--

13. (1) Which of the two sovereigns is imbued with the Moral law?
(2) Which of the two generals has most ability?
(3) With whom lie the advantages derived from Heaven and Earth?
(4) On which side is discipline most rigorously enforced?
(5) Which army is stronger?
(6) On which side are officers and men more highly trained?
(7) In which army is there the greater constancy both in reward and punishment?

14. By means of these seven considerations I can forecast victory or defeat.

15. The general that hearkens to my counsel and acts upon it, will conquer: let such a one be retained in command!
The general that hearkens not to my counsel nor acts upon it, will suffer defeat:--let such a one be dismissed!

16. While heading the profit of my counsel, avail yourself also of any helpful circumstances
over and beyond the ordinary rules.

17. According as circumstances are favorable, one should modify one's plans.

18. All warfare is based on deception.

19. Hence, when able to attack, we must seem unable; when using our forces, we must seem inactive; when we
are near, we must make the enemy believe we are far away; when far away, we must make him believe we are near.

20. Hold out baits to entice the enemy. Feign disorder, and crush him.

21. If he is secure at all points, be prepared for him. If he is in superior strength, evade him.

22. If your opponent is of choleric temper, seek to irritate him. Pretend to be weak, that he may grow arrogant.

23. If he is taking his ease, give him no rest. If his forces are united, separate them.

24. Attack him where he is unprepared, appear where you are not expected.

25. These military devices, leading to victory, must not be divulged beforehand.

26. Now the general who wins a battle makes many calculations in his temple ere the battle is fought.
The general who loses a battle makes but few calculations beforehand. Thus do many calculations
lead to victory, and few calculations to defeat: how much more no calculation at all! It is by attention
to this point that I can foresee who is likely to win or lose.

II. WAGING WAR (作战篇)


1. Sun Tzu said: In the operations of war, where there are in the field a thousand swift chariots, as many heavy chariots, and a hundred thousand mail-clad soldiers, with provisions enough to carry them a thousand li, the expenditure at home and at the front, including entertainment of guests, small items such as glue and paint, and sums spent on chariots and armor, will reach the total of a thousand ounces of silver per day. Such is the cost of raising an army of 100,000 men.

2. When you engage in actual fighting, if victory is long in coming, then men's weapons will grow dull and
their ardor will be damped. If you lay siege to a town, you will exhaust your strength. 3. Again, if the campaign is protracted, the resources of the State will not be equal to the strain.

4. Now, when your weapons are dulled, your ardor damped, your strength exhausted and your treasure spent,
other chieftains will spring up to take advantage of your extremity. Then no man, however wise,
will be able to avert the consequences that must ensue.

5. Thus, though we have heard of stupid haste in war, cleverness has never been seen associated with long delays.

6. There is no instance of a country having benefited from prolonged warfare.

7. It is only one who is thoroughly acquainted with the evils of war that can thoroughly understand
the profitable way of carrying it on.

8. The skillful soldier does not raise a second levy, neither are his supply-wagons loaded more than twice.

9. Bring war material with you from home, but forage on the enemy. Thus the army will have food enough
for its needs.

10. Poverty of the State exchequer causes an army to be maintained by contributions from a distance.
Contributing to maintain an army at a distance causes the people to be impoverished.

11. On the other hand, the proximity of an army causes prices to go up; and high prices cause the people's
substance to be drained away.

12. When their substance is drained away, the peasantry will be afflicted by heavy exactions.

13,14. With this loss of substance and exhaustion of strength, the homes of the people will be stripped bare,
and three-tenths of their income will be dissipated; while government expenses for broken chariots, worn-out horses, breast-plates and helmets, bows and arrows, spears and shields, protective mantles, draught-oxen and heavy wagons, will amount to four-tenths of its total revenue.

15. Hence a wise general makes a point of foraging on the enemy. One cartload of the enemy's provisions
is equivalent to twenty of one's own, and likewise a single picul of his provender is equivalent to twenty
from one's own store.

16. Now in order to kill the enemy, our men must be roused to anger; that there may be advantage from
defeating the enemy, they must have their rewards.

17. Therefore in chariot fighting, when ten or more chariots have been taken, those should be rewarded who took the first. Our own flags should be substituted for those of the enemy, and the chariots mingled and used in conjunction with ours. The captured soldiers should be kindly treated and kept.

18. This is called, using the conquered foe to augment one's own strength.

19. In war, then, let your great object be victory, not lengthy campaigns.

20. Thus it may be known that the leader of armies is the arbiter of the people's fate, the man on whom it
depends whether the nation shall be in peace or in peril.

III. ATTACK BY STRATAGEM (谋攻篇)


1. Sun Tzu said: In the practical art of war, the best thing of all is to take the enemy's country whole and intact; to shatter and destroy it is not so good. So, too, it is better to recapture an army entire than to destroy it, to capture a regiment, a detachment or a company entire than to destroy them.

2. Hence to fight and conquer in all your battles is not supreme excellence; supreme excellence consists
in breaking the enemy's resistance without fighting.

3. Thus the highest form of generalship is to balk the enemy's plans; the next best is to prevent
the junction of the enemy's forces; the next in order is to attack the enemy's army in the field;
and the worst policy of all is to besiege walled cities.

4. The rule is, not to besiege walled cities if it can possibly be avoided. The preparation of mantlets,
movable shelters, and various implements of war, will take up three whole months; and the piling up of mounds over against the walls will take three months more.

5. The general, unable to control his irritation, will launch his men to the assault like swarming ants,
with the result that one-third of his men are slain, while the town still remains untaken. Such are the disastrous effects of a siege.

6. Therefore the skillful leader subdues the enemy's troops without any fighting; he captures their cities
without laying siege to them; he overthrows their kingdom without lengthy operations in the field.

7. With his forces intact he will dispute the mastery of the Empire, and thus, without losing a man, his triumph
will be complete. This is the method of attacking by stratagem.

8. It is the rule in war, if our forces are ten to the enemy's one, to surround him; if five to one,
to attack him; if twice as numerous, to divide our army into two.

9. If equally matched, we can offer battle; if slightly inferior in numbers, we can avoid the enemy;
if quite unequal in every way, we can flee from him.

10. Hence, though an obstinate fight may be made by a small force, in the end it must be captured
by the larger force.

11. Now the general is the bulwark of the State; if the bulwark is complete at all points; the State will
be strong; if the bulwark is defective, the State will be weak.

12. There are three ways in which a ruler can bring misfortune upon his army:--

13. (1) By commanding the army to advance or to retreat, being ignorant of the fact that it cannot obey.
This is called hobbling the army.

14. (2) By attempting to govern an army in the same way as he administers a kingdom, being ignorant
of the conditions which obtain in an army. This causes restlessness in the soldier's minds.

15. (3) By employing the officers of his army without discrimination, through ignorance of the
military principle of adaptation to circumstances. This shakes the confidence of the soldiers.

16. But when the army is restless and distrustful, trouble is sure to come from the other feudal princes.
This is simply bringing anarchy into the army, and flinging victory away.

17. Thus we may know that there are five essentials for victory:
(1) He will win who knows when to fight and when not to fight.
(2) He will win who knows how to handle both superior and inferior forces.
(3) He will win whose army is animated by the same spirit throughout all its ranks.
(4) He will win who, prepared himself, waits to take the enemy unprepared.
(5) He will win who has military capacity and is not interfered with by the sovereign.

18. Hence the saying: If you know the enemy and know yourself, you need not fear the result of a
hundred battles. If you know yourself but not the enemy, for every victory gained you will also suffer a defeat.
If you know neither the enemy nor yourself, you will succumb in every battle.


IV. TACTICAL DISPOSITIONS (形篇)


1. Sun Tzu said: The good fighters of old first put themselves beyond the possibility of defeat, and then
waited for an opportunity of defeating the enemy.

2. To secure ourselves against defeat lies in our own hands, but the opportunity of defeating the enemy
is provided by the enemy himself.
3. Thus the good fighter is able to secure himself against defeat, but cannot make certain of defeating the enemy.

4. Hence the saying: One may know how to conquer without being able to do it.

5. Security against defeat implies defensive tactics; ability to defeat the enemy means taking the offensive.

6. Standing on the defensive indicates insufficient strength; attacking, a superabundance of strength.

7. The general who is skilled in defense hides in the most secret recesses of the earth; he who is skilled in
attack flashes forth from the topmost heights of heaven. Thus on the one hand we have ability to protect ourselves; on the other, a victory that is complete.

8. To see victory only when it is within the ken of the common herd is not the acme of excellence.

9. Neither is it the acme of excellence if you fight and conquer and the whole Empire says, "Well done!"

10. To lift an autumn hair is no sign of great strength; to see the sun and moon is no sign of sharp sight;
to hear the noise of thunder is no sign of a quick ear.

11. What the ancients called a clever fighter is one who not only wins, but excels in winning with ease.

12. Hence his victories bring him neither reputation for wisdom nor credit for courage.

13. He wins his battles by making no mistakes. Making no mistakes is what establishes the certainty
of victory, for it means conquering an enemy that is already defeated.

14. Hence the skillful fighter puts himself into a position which makes defeat impossible, and does
not miss the moment for defeating the enemy.

15. Thus it is that in war the victorious strategist only seeks battle after the victory has been won,
whereas he who is destined to defeat first fights and afterwards looks for victory.

16. The consummate leader cultivates the moral law, and strictly adheres to method and discipline; thus it is
in his power to control success.

17. In respect of military method, we have, firstly, Measurement; secondly, Estimation of quantity;
thirdly, Calculation; fourthly, Balancing of chances; fifthly, Victory.

18. Measurement owes its existence to Earth; Estimation of quantity to Measurement; Calculation to
Estimation of quantity; Balancing of chances to Calculation; and Victory to Balancing of chances.

19. A victorious army opposed to a routed one, is as a pound's weight placed in the scale against a single grain.

20. The onrush of a conquering force is like the bursting of pent-up waters into a chasm a thousand fathoms deep.

Labels

Followers