星期三, 二月 27, 2008

重读 《节妇吟》

节妇吟
【唐】张籍

君知妾有夫,赠妾双明珠;
感君缠绵意,系在红罗襦。
妾家高楼连苑起,良人执戟明光里。
知君用心如日月,事夫誓拟同生死。
还君明珠双泪垂,恨不相逢未嫁时!


今天重读这首诗,心里又有别样的感觉,最近发生了很多事,自己也需要静下来
淡泊以明志,宁静而致远。

Read More...

星期日, 二月 17, 2008

一种在U-BOOT中嵌入千兆网络功能的方法【转】

摘 要:U-BOOT是一种开放源码的、用于多种嵌入式微处理器的引导加载程序,目前U-BOOT仅支持10M/100M网络功能。本文介绍了一种让U- BOOT支持千兆网络功能的方法及所需的硬件平台结构,重点介绍了此千兆网络驱动程序的结构及设计方法,并给出了驱动程序在U-BOOT中的移植过程。该 设计可以使U-BOOT功能更加强大,使用更加方便,同时也能使嵌入式系统网络接口设计更加灵活。
关键词: U-BOOT;千兆网;AX88180;驱动

引言
U-BOOT是德国DENX小组开发的用于多种嵌入式微处理器的引导加载程序,它是系统上电后运行的第一段程序代码,用于初始化目标板 硬件,为嵌入式操作系统提供目标板硬件配置信息,并装载、引导和运行嵌入式操作系统等。U-BOOT支持网络功能,在下载操作系统内核和大的文件系统时, 比其它不支持网络的引导加载程序速度更快、更方便。目前U-BOOT仅支持10M/100M的网络功能,随着科学技术发展,千兆网络功能必将大量应用在嵌 入式系统中。本文介绍了一种让U-BOOT支持千兆网络功能的方法,可以使U-BOOT功能更加强大,使用更加方便。

U-BOOT简介
U-Boot的全称是Universal Boot Loader,它遵循GPL条款的开放源码项目,支持多种处理器,如ARM、PowerPC、MIPS等,也支持Linux、VxWorks、QNX、RTEMS、ARTOS、LynxOS等嵌入式操作系统。
U- BOOT包含两种不同的工作模式:启动加载模式和下载模式。启动加载模式也称为自主模式,即U-BOOT从目标机上的某个固态存储设备上将操作系统加载到 RAM 中运行,这种模式是U-BOOT的正常工作模式。下载模式就是在开发或生产过程中,U-BOOT通过网络连接等通信手段从主机下载操作系统内核和文件系统 等到目标机的 RAM 中,然后再写到目标机上的FLASH 类固态存储设备中。U-BOOT允许用户在这两种工作模式间进行切换,系统启动时会延时等待一段时间,如果这时用户没有按键,U-Boot就默认进入启动 加载模式。
U-BOOT代码采用一种高度模块化的编程方式,可以很方便地在不同的硬件平台上进行移植。U-BOOT下包含多个目录,如图1所示。 其中BOARD目录下存放了所有其支持的目标板子目录,比如BOARD/SMDK2440/就是本文将要用到的目标板;COMMON目录是与体系结构无关 的文件,实现各种命令的C文件;CPU目录存放了其支持的CPU类型, 比如arm920t、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c和interrupt.c、start.S; DRIVERS目录存放了各种外设接口的驱动程序,其中就包含本文用到的千兆网络的驱动程序;FS目录存放了一些文件系统,U-BOOT现在支持 cramfs、fat、fdos、jffs2和registerfs;net目录存放的是与网络有关的代码,BOOTP协议、TFTP协议、RARP协议 和NFS文件系统的实现;INCLUDE目录存放了一些相关头文件,还有对各种硬件平台支持的汇编文件、系统的配置文件和对文件系统支持的文件。



图1? U-BOOT目录

硬件平台
本文使用的硬件平台是基于S3C2440A的开发板和基于非PCI千兆以太网控制芯片AX88180的嵌入式网卡,如图2所示。 S3C2440A是ARM920T 核的16/32 位RISC嵌入式微处理器,运行频率高达500MHz,开发板上有64M NAND闪存、64M SDRAM;网卡由MAC芯片AX88180、PHY芯片88E1111、RJ45等电路组成;S3C2440A目标板与网卡之间采用目标板32位扩展总 线相连接,在产品设计时也可以将这两部分设计在同一块板上。

驱动程序
在U-BOOT中嵌入千兆网络功能需要设计千兆网卡驱动程序,并在U-BOOT中进行移植,在相应的硬件平台上实现通过千兆网口下 载等功能。网卡驱动程序主要由初始化程序eth_init(bd_t*bd)、关闭网络设备程序eth_halt(void)、发送数据包程序 eth_send(volatilevoid* packet,intlength)、接收数据包程序inteth_rx(void)等组成。初始化程序的工作主要是配置和初始化硬件,在初始化程序里可 以完成对网络控制芯片AX88180和PHY芯片的配置,比如将接口设置为1000Mbps、全双工模式等。数据发送就是将上层协议打包好的数据放在发送 数据缓冲区,然后由网卡发送到网络上;数据接收就是在网卡接收到网络传来的数据包产生中断后,从缓冲区将数据取出交给上层协议程序进行解包处理。中断服务 程序处理网卡发送数据包后、接收到数据包后产生的中断以及PHY产生的中断等。



图2 硬件平台结构框图


网卡初始化程序如下:
int eth_init (bd_t * bd)
{
...
memset (&axlocal, 0, sizeof(AX88180_PRIVATE));
RESET_MAC;
DISABLE_INTERRUPT;
WRITE_MACREG(CMD, WAKEMOD);
tmp16 = bd->bi_enetaddr[1];
macid0_val = (tmp16 << 8) | bd->bi_enetaddr[0];
tmp16 = bd->bi_enetaddr[3];
macid1_val = (tmp16 << 8) | bd->bi_enetaddr[2];
tmp16 = bd->bi_enetaddr[5];
macid2_val = (tmp16 << 8) | bd->bi_enetaddr[4];
WRITE_MACREG(MACID0, macid0_val);
WRITE_MACREG(MACID1, macid1_val);
WRITE_MACREG(MACID2, macid2_val);
ax88180_PHY_initial();
ax88180_meida_config();
WRITE_MACREG(RXFILTER, DEFAULT_RXFILTER);
INIT_TXRX_VARIABLES;
READ_MACREG(ISR, tmp_regval);
PRINTK(INIT_MSG, "ax88180: The interrupt status = 0x%08lx\n", tmp_regval);
if (tmp_regval)?WRITE_MACREG(ISR, tmp_regval);
WRITE_MACREG(CMD, RXEN | TXEN | WAKEMOD);
return 0;}

驱动移植
驱动移植是在基于S3C2440A硬件平台的U-BOOT中添加驱动程序代码和相关配置,具体如下:
1. 在drivers/目录中添加网口设备驱动程序ax88180.c和ax88180.h。
2. 在lib_arm/board.c中相应位置(参考CS8900)添加如下代码:
#ifdef CONFIG_DRIVER_AX88180
extern void ax88180_get_ enetaddr (uchar * addr);
#endif
#ifdef CONFIG_DRIVER_AX88180
ax88180_get_enetaddr (gd->bd->bi_enetaddr);
#endif
3. 在include/configs/smdk2440.h中相应位置(参考CS8900)添加如下代码:
#define CONFIG_DRIVER_AX88180?1
#define AX88180_BASE???0x08000000
4. 最后在drivers/Makefile中加入ax88180.o,重新编译生成U-BOOT即可。

结语
U-BOOT广泛应用在嵌入式系统中,本文阐述的方法可以使U-BOOT功能更强大、使用更方便,文中介绍的硬件平台给嵌入式系统千兆 网络功能的设计提供了一定的指导。本设计虽然基于S3C2440A平台,对其它类似的系统也有很好的借鉴作用,本文介绍的方法已经在产品中得到应用,效果 良好。 ■

参考文献
1. 钱峰. U-Boot在S3C44B0上的移植[J].微计算机信息.2006年第9-2期:P119-121
2. 聂强,孙贺. linux_mig_ release.pdf. http://www.hhcn.com/chinese/files
3. Allan Chou. ax88180.c.ASIX Electronics Corporation.2006

Read More...

U-Boot中SMDK2410的NAND Flash驱动。

本来不应该先写这个的,呵呵,但是我这个人记忆力很差,说不定过几天我就忘了移植过程中的代码是哪里弄来的了。
 
首先庆祝一下,我学生生涯所有的考试都结束了,哈哈哈。不过希望不要补考……听说我们的研究生教学院长赵学增老师的课很变态,120个抓50个……上帝保佑我啊。
 
开始吧。标准的SMDK2410板不支持NAND Flash,启动的时候是这样的:
 
U-Boot 1.1.2 (May 28 2006 - 08:20:50)
U-Boot code: 33F80000 -> 33F99A14  BSS: -> 33F9DB0C
RAM Configuration:
Bank #0: 30000000 64 MB
Flash:  1 MB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
 
NAND支持的多一行(NAND 64MB):
 
U-Boot 1.1.2 (May 28 2006 - 08:36:42)
U-Boot code: 33F80000 -> 33F99A14  BSS: -> 33F9DB0C
RAM Configuration:
Bank #0: 30000000 64 MB
Flash:  1 MB
NAND:  64 MB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
 
怎么实现这种支持呢?U-Boot真是功能强大的Bootloader,在/inclued/configs/smdk2410.h中有这么一段
 
/***********************************************************
 * Command definition
 ***********************************************************/
#define CONFIG_COMMANDS \
   (CONFIG_CMD_DFL  | \
   CFG_CMD_CACHE  | \
   CFG_CMD_NAND  | \
   /*CFG_CMD_EEPROM |*/ \
   /*CFG_CMD_I2C  |*/ \
   /*CFG_CMD_USB  |*/ \
   CFG_CMD_REGINFO  | \
   CFG_CMD_DATE  | \
   CFG_CMD_ELF)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 
需 要说明一下CONFIG_CMD_DFL,定义的是默认指令,包括bdinfo、bootd、coninfo、saveenv、flinfo、 erase、protect、iminfo、imls、itest、loadb、loads、md、mm、nm、mw、cp、cmp、crc、base、 loop、loopw、mtest、sleep、bootp、tftpboot、rarpboot、run等常用指令,这些指令我以后会结合使用做适当的 说明。关于指令的宏定义说明可以看看U-Boot的README里面的Monitor Functions。这就是对编译成功后的U-Boot支持的命令的定义,SMDK2410默认的smdk2401.h中,红色字部分是注释掉的。但是要 支持NAND Flash远没有去掉一个注释这么简单。
 
我们可以试试单纯把这个注释去掉是什么结果,老步骤:
 
make distclean
make smdk2410_config
make
……一堆编译信息飘过……
 
出 错了,位置指向cmd_nand.c这个文件,好几处错误。原因是SMDK2410的配置里根本就没有对NAND Flash支持的宏定义和函数。怎么办?自己写么?好在U-Boot里有另外一个可以让我们借鉴的配置VCMA9。在Source Navigator里搜索一下vcma,看看vcma9.h和vcma9.c,可以从中摘取出一段宏定义和一些函数声明。网上有人的做法是将其放在 smdk2410.h和smdk2410.c中,但是白痴的cross-2.95.3和cross-3.2都不能认到cmd_nand.c中已经在 smdk2410.h和smdk2410.c中定义的宏所指的函数,就算是加上extern的也不行。也许你没有看懂刚才这句话,解释一下,例如 cmd_nand.c中有这样一段
 
 if(ale_wait)
  NAND_WAIT_READY(nand); /* do the worst case 25us wait */
 else
  udelay(10);
 
其中NAND_WAIT_READY(nand),在smdk2410.h中定义为
 
#define NAND_WAIT_READY(nand) NF_WaitRB()
 
而NF_WaitRB()在smdk2410.c中定义为
 
static inline void NF_WaitRB(void)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 while (!(nand->NFSTAT & (1<<0)));
}
 
这个编译器死活说NF_WaitRB()未定义,就算是我在cmd_nand.c中加上这样一句也不起作用
 
extern void NF_WaitRB(void)
 
也许是我C学的不好,搞不清楚多个文件共同编译的时候static inline的引用关系,不管它,我把这些宏中定义的函数的申明放在了cmd_nand.c中,为了不太无耻,我在前面加上了针对SMDK2410的选择性编译。(请注意,下面这些代码拷贝到cmd_nand.c中的适当位置,cmd_nand.c中有许多选择性编译的宏,注意放的位置,不要被忽略掉了)
 
/*-----------------------------------------------------------------------
 * NAND flash basic functions
 * Added by Lu Xianzi 2006.5.27
 * Copied from board/mpl/vcma9/vcma9.h & vcma9.c
 */
#if (CONFIG_SMDK2410)
#include <s3c2410.h>
typedef enum {
 NFCE_LOW,
 NFCE_HIGH
} NFCE_STATE;
static inline void NF_Conf(u16 conf)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 nand->NFCONF = conf;
}
static inline void NF_Cmd(u8 cmd)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 nand->NFCMD = cmd;
}
static inline void NF_CmdW(u8 cmd)
{
 NF_Cmd(cmd);
 udelay(1);
}
static inline void NF_Addr(u8 addr)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 nand->NFADDR = addr;
}
static inline void NF_SetCE(NFCE_STATE s)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 switch (s) {
  case NFCE_LOW:
   nand->NFCONF &= ~(1<<11);
   break;
  case NFCE_HIGH:
   nand->NFCONF |= (1<<11);
   break;
 }
}
static inline void NF_WaitRB(void)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 while (!(nand->NFSTAT & (1<<0)));
}
static inline void NF_Write(u8 data)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 nand->NFDATA = data;
}
static inline u8 NF_Read(void)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 return(nand->NFDATA);
}
static inline void NF_Init_ECC(void)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 nand->NFCONF |= (1<<12);
}
static inline u32 NF_Read_ECC(void)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 return(nand->NFECC);
}
extern ulong nand_probe(ulong physadr);
static inline void NF_Reset(void)
{
    int i;
    NF_SetCE(NFCE_LOW);
    NF_Cmd(0xFF);  /* reset command */
    for(i = 0; i < 10; i++); /* tWB = 100ns. */
    NF_WaitRB();  /* wait 200~500us; */
    NF_SetCE(NFCE_HIGH);
}
static inline void NF_Init(void)
{
#if 0 /* a little bit too optimistic */
#define TACLS   0
#define TWRPH0  3
#define TWRPH1  0
#else
#define TACLS   0
#define TWRPH0  4
#define TWRPH1  2
#endif
    NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
    /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
    /* 1  1    1     1,   1      xxx,  r xxx,   r xxx */
    /* En 512B 4step ECCR nFCE=H tACLS   tWRPH0   tWRPH1 */
    NF_Reset();
}
void nand_init(void)
{
 S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 NF_Init();
#ifdef DEBUG
 printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
 printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
#endif /* (CONFIG_SMDK2410) */
 
然后把下面这些宏定义放在smdk2410.h中
 
/*-----------------------------------------------------------------------
 * NAND flash settings
 * Added by Lu Xianzi 2006.5.27
 * Copied from include/conifgs/vcma9.h
 */
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices  */
#define SECTORSIZE 512
#define ADDR_COLUMN 1
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3
#define NAND_ChipID_UNKNOWN  0x00
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
#define NAND_WAIT_READY(nand) NF_WaitRB()
#define NAND_DISABLE_CE(nand) NF_SetCE(NFCE_HIGH)
#define NAND_ENABLE_CE(nand) NF_SetCE(NFCE_LOW)

#define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d)
#define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)
#define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d)
#define WRITE_NAND(d, adr)  NF_Write(d)
#define READ_NAND(adr)   NF_Read()
/* the following functions are NOP's because S3C24X0 handles this in hardware */
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
/* #define CONFIG_MTD_NAND_VERIFY_WRITE 1 */
/* This definition above is commented by Lu Xianzi. 2006.05.28
   Because there's no definition of a macro called __mem_pci,
   there will be a link error.
 */

#define CONFIG_MTD_NAND_ECC_JFFS2 1
#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */
 
注 意这段宏定义中与vcma9.h中不同的是我标记红色的部分,网上的一些移植说明没有解决这个问题,导致最后的链接无法通过。事实上,我这样做取消了 cmd_nand.c中对NAND Flash的写校验和ECC校验。__mem_pci是一个什么东西我也不知道,在U-Boot目录下搜索包含“__mem_pci”字串的文件也没有找 到,除了使用它的/include/asm/io.h。顺便说一下,这个麻烦是从cmd_nand.c中的nand_write_page函数中 readb(nand->IO_ADDR)这个宏开始的,你可以用Source Navigator查找一下引用,最后就指向没有__mem_pci宏的这个问题。希望有高手看到这篇文章,并给我指出解决的办法,呵呵。
 
做完这些修改,就再来一次老步骤
 
make distclean
make smdk2410_config
make
………………
 
生 成了U-Boot.bin。NAND Flash的驱动到此完成,好不好使呢?试试看。上次我们已经在板子里烧写进了U-Boot,是一个可以支持串口传输的U-Boot,要是现在还用 sjf2410往里烧U-Boot.bin就太冤大头了。可以利用串口进行传输,操作步骤如下:
使用超级终端,建立一个连接:文件〉新建连接;名称随便,图表随便,确定;连接时使用选择你的开发板所接的COM口;端口设置中,每秒位数选115200,数据位选8,奇偶校验选无,停止位选1,数据流控制选“无”。打开开发板的电源,出现以下提示:
 
U-Boot 1.1.2 (May 28 2006 - 08:20:50)
U-Boot code: 33F80000 -> 33F99A14  BSS: -> 33F9DB0C
RAM Configuration:
Bank #0: 30000000 64 MB
Flash:  1 MB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
LXZROB # loadb
## Ready for binary (kermit) download to 0x33000000 at 115200 bps...
 
loadb 这个指令以kermit协议从串口下载二进制文件到开发板的内存中,默认下载到0x33000000。当然你可以改在别的地址,例如:loadb 30000000就是下载到0x30000000。这时候选择超级终端菜单上:传送〉发送文件,文件名选择编译好的U-Boot.bin,协议选择 Kermit,点发送。可以看到发送进度。
发送结束出现提示:
 
## Total Size      = 0x00019a14 = 104980 Bytes
## Start Addr      = 0x33000000
 
这时可以测试新的修改好不好使:
 
LXZROB # go 33000000
## Starting application at 0x33000000 ...

U-Boot 1.1.2 (May 28 2006 - 08:36:42)
U-Boot code: 33F80000 -> 33F99A14  BSS: -> 33F9DB0C
RAM Configuration:
Bank #0: 30000000 64 MB
Flash:  1 MB
NAND:  64 MB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
LXZROB #
 
go 指令可以直接执行内存地址上的程序,例如刚才下载到0x33000000的新的支持NAND的U-Boot,可以看到出现了“NAND:   64MB”这一项。输入help,你会看到比刚才的U-Boot多了一组指令nand,输入help nand,可以看到更加细节的指令:
 
LXZROB # help nand
nand info  - show available NAND devices
nand device [dev] - show or set current device
nand read[.jffs2[s]]  addr off size
nand write[.jffs2] addr off size - read/write `size' bytes starting
    at offset `off' to/from memory address `addr'
nand erase [clean] [off size] - erase `size' bytes from
    offset `off' (entire device if not specified)
nand bad - show bad blocks
nand read.oob addr off size - read out-of-band data
nand write.oob addr off size - read out-of-band data
 
输入nand info,可以看到:
 
LXZROB # nand info
Device 0: Samsung unknown 64Mb at 0x4e000000 (64 MB, 16 kB sector)
 
说明我们的驱动成功了。也可以试试其他指令。
 
但是现在在NOR Flash中的U-boot还是不支持NAND的,需要重新烧写。U-Boot支持自己烧写自己。
先看看NOR Flash的情况:
 
LXZROB # flinfo
Bank # 1: AMD: 1x Amd29LV800BB (8Mbit)
  Size: 1 MB in 19 Sectors
  Sector Start Addresses:
    00000000 (RO) 00004000 (RO) 00006000 (RO) 00008000 (RO) 00010000 (RO)
    00020000      00030000      00040000      00050000      00060000
    00070000      00080000      00090000      000A0000      000B0000
    000C0000      000D0000      000E0000      000F0000 (RO)
 
一共有19个sector,其中前5个总计128kb的sector有U-Boot程序,是写保护的。要烧写首先要去掉写保护:
 
LXZROB # protect off 0 1ffff
Un-Protected 5 sectors
LXZROB # flinfo
Bank # 1: AMD: 1x Amd29LV800BB (8Mbit)
  Size: 1 MB in 19 Sectors
  Sector Start Addresses:
    00000000      00004000      00006000      00008000      00010000
    00020000      00030000      00040000      00050000      00060000
    00070000      00080000      00090000      000A0000      000B0000
    000C0000      000D0000      000E0000      000F0000 (RO)
 
可以看到写保护已经去掉,擦除:
 
LXZROB # erase 0 1ffff
Erasing sector  0 ... ok.
Erasing sector  1 ... ok.
Erasing sector  2 ... ok.
Erasing sector  3 ... ok.
Erasing sector  4 ... ok.
Erased 5 sectors
 
然后烧写:
 
LXZROB # cp.b 33000000 0 19a14
Copy to Flash... done
 
cp.b 是用来拷贝内存信息的,其格式为cp [.b, .w, .l] source target count,输入这样的指令是因为刚才把程序下载到了0x33000000,NOR Flash的起始地址是0x0,下载的程序长度为0x19a14。重启开发板,U-Boot的烧写就完成了。

Read More...

星期二, 一月 29, 2008

利用google突破各种封锁来下载你要的东西

在搜索框上输入: “index of/ ”  inurl:lib

再按搜索你将进入许多图书馆,并且一定能下载自己喜欢的书籍。

在搜索框上输入: “index of /”  cnki

再按搜索你就可以找到许多图书馆的CNKI、VIP、超星等入口!

在搜索框上输入: “index of /”  ppt

再按搜索你就可以突破网站入口下载powerpint作品!

在搜索框上输入: “index of /”  mp3

再按搜索你就可以突破网站入口下载mp3、rm等影视作品!

在搜索框上输入: “index of /”  swf

再按搜索你就可以突破网站入口下载flash作品!

在搜索框上输入: “index of /”  要下载的软件名

再按搜索你就可以突破网站入口下载软件!

注意引号应是英文的!

再透露一下,如果你输入:

“index of /”  AVI

另补上第二篇
用GOOgle看世界!!!只要你在GOOGLE里输入特殊的关键字,就可以搜到数千个摄象头的IP地址!通过他你就可以看到其所摄的实时影象!!
在google里输入
inurl:"viewerframe?mode="

随便打开一个,然后按提示装一个插件,就可以看到了!!!

再补上第三篇
三则黑客的Google搜索技巧简介
大 家都知道,Google毫无疑问是当今世界上最强大的搜索引擎。然而,在黑客手中,它也是一个秘密武器,它能搜索到一些你意想不到的信息。赛迪编者把他们 进行了简单的总结不是希望您利用他去攻击别人的网站,而是利用这些技巧去在浩如烟海的网络信息中,来个大海捞针,寻找到对您有用的信息。

如 果您是一名普通网民,您可以使用黑客的技巧扩大自己的视野,提高自己的检索效率;如果您是一名网管,请您赶快看看您的网站是否做好了对下面黑客探测手段的 防范措施,如果没有就赶快来个亡羊补牢,毕竟隐患胜于明火,防范胜于救灾;如果您是一名黑客,相信您早以在别的黑客站点上见过类似的方法,这篇文章对您没 什么用处,这里的技巧对您是小儿科,菜鸟级!您可以节省宝贵的时间做更有意义的事情,这篇文章您不用看了,到别处去吧!

基于上面的考虑我编发了这篇文章。

  搜索URL

  比如我们提交这种形式:passwd.txt site:virtualave.net

   看到了什么?是不是觉得太不可思议了!有很多基于CGI/PHP/ASP 类型的留言板存在这种问题。有时我们得到密码甚至还是明码的!管理员或许太不负责了,或许安全防范的意识太差了,如果你是网络管理员,赶快检查一下不要让 恶意攻击者捡了便宜。不要太相信DES加密,即使我们的密码经过DES 加密的密码,黑客们还是可以通过许多破解软件来搞定。

  这次我们能得到包含密码的文件。“site:virtualave.net”意思是只搜索 virutalave.net 的URL。virutalave.net是一个网络服务器提供商。

  同样,我们可以搜索一些顶级域名,比如:.net .org .jp .in .gr

  config.txt site:.jp

  admin.txt site:.tw

  搜索首页的目录

  首页是非常有用的,它会提供给你许多有用的信息。

  我们提交如下的形式:

  "Index of /admin"

  "Index of /secret"

  "Index of /cgi-bin" site:.edu

  你可以自己定义搜索的首页字符。这样就可以获得许多信息。

  搜索特定的文件类型

  比如你想指定一种文件的类型,可以提交如下形式:

  filetype:.doc site:.mil classified

  这个就是搜索军方的资料,你可以自定义搜索。
再提供一个第四篇

Google 的特殊功能
1 、查询电话号码
Google 的搜索栏中最新加入了电话号码和美国街区地址的查询信息。
个人如想查找这些列表,只要填写姓名,城市和省份。
如果该信息为众人所知,你就会在搜索结果页面的最上方看到搜索的电话和街区地址
你还可以通过以下任何一种方法找到该列表:
名字(或首位大写字母),姓,电话地区号
名字(或首位大写字母),姓,邮递区号
名字(或首位大写字母),姓,城市(可写州)
名字(或首位大写字母),姓,州
电话号码,包括区号
名字,城市,州
名字,邮递区号

2 、查找 PDF 文件
现在 GOOGLE 的搜索结果中包括了 PDF 文件。尽管 PDF 文件不如 HTML 文件那么多,但他们经常具备一些其他文件不具备的高质量信息
为了显示一个搜索结果是 PDF 文件而不是网页, PDF 文件的标题开头显示蓝色文本。
这就是让你知道 ACRTOBAT READER 程序会启动来阅读文件
如果你的计算机没装有该程序,计算机会指导你去能免费下载该程序的网页。
使用 PDF 文件时,相关的网页快照会由“ TEXT VERSION ”代替,它是 PDF 文档的复制文件,该文件除去了所有格式化命令。
如果你在没有 PDF 链接的情况下想看一系列搜索结果,只要在搜索栏中打上 -inurldf 加上你的搜索条件。

3 、股票报价
用 Google 查找股票和共有基金信息,只要输入一个或多个 NYSE , NASDAQ , AMEX 或
共有基金的股票行情自动收录机的代码,也可以输入在股市开户的公司名字。
如果 Google 识别出你查询的是股票或者共有基金,它回复的链接会直接连到高质量的金融信息提供者提供的股票和共有基金信息。
在你搜索结果的开头显示的是你查询的股市行情自动收录器的代码。如果你要查找一家公司的名字(比如, INTEL ),请查看“股票报价”在 Google 搜索结果的金融栏里会有那个公司的主页的链接(比如, WWW.INTEL.COM )。
Google 是以质量为基础来选择和决定金融信息提供者的,包括的因素有下载速度,用户界面及其功能。

4 、找找谁和你链接
有些单词如果带有冒号就会有特殊的意思。比如 link :操作员。查询 link:siteURL ,就会显示所有指向那个 URL 的网页。举例来说,链接 www.Google.com 会向你显示所有指向 GOOGLE 主页的网页。但这种方法不能与关键字查询联合使用。

5 、查找站点
单词 site 后面如果接上冒号就能够将你的搜索限定到某个网站。具体做法是:在 c 搜索栏中使用 site:sampledomain.com 这个语法结构。比如,在斯坦福找申请信息,输入:
admission site:www.stanford.edu

6 、查找字典释意
查找字典释意的方法是在搜索栏中输入你要查询的内容。在我们根据要求找到所有的字典释意都会标有下划线,位于搜索结果的上面,点击链接你会找到字典提供者根据要求给出的相关定义。 7 、用 GOOLGE 查找地图
想用 Google 查找街区地图,在 Google 搜索栏中输入美国街区地址,包括邮递区号或城市 / 州(比如 165 大学大街 PALO ALTO CA )。通常情况下,街区地址和城市的名字就足够了。
当 Google 识别你的要求是查找地图,它会反馈给你有高质量地图提供者提供的链接,使你直接找到相关地图。我们是以质量为基础选择这些地图提供者。值得注意的是 Google 和使用的地图信息提供者没有任何关联。

Read More...

一个北大学子毕业后的14点感悟【转】

    1,我刚工作的时候,在一家小公司,很小很小的。和我一起进去的另外2个都是普通一点 的学校的。我们刚去的时候,基本上有了电话都是我站起来跑过去接,其它人根本就不动身。以至于到了后来,电话一响,如果我不起身,大家就会一直等着,一直 等到我终于忍不了了起身去接。每天下班以后,我要检查办公室的垃圾袋,看看是不是需要把垃圾袋提走。而其他人,比如老员工和另外的实习生,他们根本不会去 提垃圾袋。

  2,工作形势非常严峻。尤其是对于刚毕业的学生。如果是大公司,它们可能有能力支 付生手的培训时间和金钱,也有能力承受生手因不熟悉业务而给公司带来的损失,但是对于绝大部分小公司,它们根本就不愿意或者说无法承受这些。所以在一个大 专毕业的熟手和一个北大毕业的生手中间,他们宁可选择前者。

  3,中关村乃至海淀乃至北京,是一个廉价高等教育人才市场。这个大环境决定了我们 在用人单位眼里,都是金属,而不是金子。在这里,大学生就是廉价劳动力,商人看刚毕业的大学生的感觉,和建筑工地上包工头看民工的眼光没有任何区别。尤其 在以赚钱为唯一目的的大部分小公司。所以,刚毕业的同学最需要做的,就是赶紧让自己成为一个熟工。

  4,在学校的时候,好好享受自尊的感觉。有人说,他读大学的时候,以为他毕业后要 变成一条狗只需要3年的时间,但是工作后,他发现对自己真是太不自信了,其实要变成一条狗根本不用3年,半年就足够了。这话是我大4时看见的,过了2年 后,我发现这条伟大真理完全可以和牛顿定律媲美。我们在北大里,享受的是中国最大的自由和民主,这是个可怕的甜蜜。因为当你第一次受到指着鼻子的责骂时你 一下子无法接受。

  5,你在北大的时候,可能会觉得某人很俗。离开北大的时候,你可能会立志你绝对不 要俗。但是过了几年后,你会发现只有那些完成了由不俗到俗的成功转变的同学才能衣着不俗地参加聚会,而那些尚未完成转变的同学则可能潦倒落魄地出现在你面 前。所以,当你在学校的时候,千万不要讥笑(哪怕是在心里)身边那些俗又俗的同学,因为他们很可能就是将来同学聚会上的主角,也是你mm对你进行再教育的 榜样。

  6,在我们所受到的教育里,师长一直告诉我们要诚实、对人真诚。还有,中国的老话 叫“买卖不成仁义在”。这在企业竞争已经到人性化程度的西方世界可能还是真理,但是在现在的中国商场上那是……胡说。举个例子吧,我的诚实让公司失去了一 个客户,让我个人赢得了一个朋友;当这个朋友因我的诚实而给我带来一个大买卖时,我已经被公司老板因那次业务失败而炒了鱿鱼;所以最后我把这宗大买卖带到 了新服务的公司。

  这件事的结果最后是好的;但是这只是一个幸运的偶然。我想大部分人不会这么幸运。 工作以后,如果你每天统计一下,你会惊讶于自己现在从早晨走进办公室的那一刻起就开始说假话。这假话对同事说、对老板说、对客户说、一直说到家里,如果你 的女友or男友还没有工作,而是留在学校上研上博(就像我的情况),你会让他们大为震惊,他们很可能悲痛欲绝地对你说“你怎么能这么说?”然后,你可能更 加愤慨地对她or他说:“这只是交际的手段/业务的需要/如果你能给我提供一个饭碗我肯定不这么说……”最后的最后,你们很可能对彼此失望,比如,对方觉 得你变了;你觉得对方toonaive,toosimple,不理解你。

  7,当你还在学校的时候,平时有空多看几部白痴一点幼稚一点的片子,比如《流星花 园》那种。当年我对此嗤之以鼻,现在我一想起一个宿舍的女生围着一台破电脑看它的情景我就鼻子发酸!!!!现在我们已经没什么心思能沉在一部片子里耐心地 看下去了,偶尔看看电视,就是拿着遥控器拼命跳台。

  8,当你还在学校的时候,多去上上课,少在宿舍打游戏睡觉。多看看那些底高望重的老教授,没问题也找几个出来问问吧,就当小时候听奶奶讲故事。因为,工作 以后就不要指望谁这么耐心给你讲东西了,老板要是让你做啥,不懂的话千万别问!自己想办法查!不要以为像在学校一样,好问是美德!你多问几句,脾气好的老 板会不理你,晾着你知道你自己讪讪地走开,脾气稍微不好地老板会对你阴阴地说:“你们北大的就这素质?这都不会?”你可能会心里喊冤:“拜托!我接触这项 业务才2天,我不问我怎么知道?”你这么想就错了。老板要的是结果,不是过程。他管你怎么做到的,总之你做到了才算完。我现在每想到大学时候不少次我都在 课堂上睡觉,我就觉得特别对不起讲堂上的老师。

  9,当你还在学校的时候,能谈恋爱就谈场恋爱,那时候谈恋爱才叫谈恋爱!你的她很 可能只是因为喜欢你而跟你谈恋爱;你们可能大夏天一起挤公交去动物园,在臭气烘烘的车厢里晃来晃去都是一种甜蜜一种幸福;工作以后你就别指望了!如果她跟 你谈了3年你还没有能买房能加薪的迹象,你就完蛋了!如果你跟她谈了3年你还没有能买房能跟她结婚的迹象,你也完蛋了,你可能会开始怀疑你是不是在耽误她 的青春她的时间。那时候你们一起再坐公交车,你都会觉得心酸:你堂堂一个北大男子汉,还要让lp挤公交车!

  10,当你还在学校的时候,多原谅舍友的小过失。不要因为她or他不小心把一杯水 泼在你的英语词典上就对她or他生气甚至要求赔偿;不要因为她or他的臭袜子忘记从你床上拿走你就对别人抱怨!不要因为她or他借了你2块钱买水果一直忘 记还就在意。不要不要因为她or他的无意中的缺点或失误而对他生气。当你工作以后,你会发现其实他们原来并没有那么讨厌,你会惊讶当初你干吗总是为这种事 情而生气,你会慢慢忘记他们的不好而只记得当初你们床头夜话时的温馨、买一包零食回来大家一起吃的开心。当你刚上大学的时候,你可能感叹过真心朋友只有在 高中才交得到;但当你工作以后你会发现,大学才最可能交到一辈子的能互相倾诉互相帮忙的朋友!
  11,如果你是女生,当你还在学校的时候,多体谅那些你不喜欢甚至讨厌但是狂追你 的男生!因为无论你多讨厌他,毕竟他们是真心喜欢你的,在他们眼里,你很可能就是天使!而在工作后,你在老板看来,很可能你只不过是狗屎!人的一生中没有 多少机会得到一些最真最纯的东西,很多年后那些看起来又矮又丑的男生可能结婚成家,你很可能已经被世事磨得没有知觉,而当你再和他们相遇,你很可能会突然 发现他们原来这么好、这么好、这么这么好,原来他们一点都不丑……你会很想很想哭!

  12,当你在学校的时候,多读一点书,少上网做一些没有意义的东西,比如灌水比如 聊qq!因为你一旦离开校园,你就很可能顶多只有读读《瑞丽》《成都今夜将我遗忘》这样的垃圾杂志和快餐书,而不再有机会去想万圣和风入松!更不会有机会 有时间有气氛去看那里的书!我在大2的时候,曾经惊觉我读的名著基本上停留在高中时代,而当我工作后我发现我读过的书完全停留在大学毕业以前!

  13,当你还在学校的时候,你可能为那些该死的偷车贼而痛不欲生咬牙切齿,你可能 会在临上课前5分钟才起床,然后慢悠悠散步去上课;当工作以后,你最大的可能就是每天6点起床,在沙丁鱼罐头一样的公交车里焦急地等待你的公交车在堵车长 龙里挤牙膏一样一点一点地往前爬;当你因某天某段路发生交通事故而迟到了5分钟却因为老板还没来而庆幸时,很可能某个你的亲密同事已经在准备报告给老板 了。当你晚上再经历同样的堵车回到家想看点书时,你很可能发现时钟已经指到9了,而你这时候很可能还没吃饭!

  14,如果你是女生,当你还在学校的时候,不要为了减肥而 生饿自己把自己弄出胃病来!因为你会发现一旦你有了胃病而后工作你会郁闷todeath!你在学校的时候,很可能因为某天例假来了而轻易就选择不去上课, 而当你工作后,哪怕你痛得浑身发凉你也可能强迫自己不请假!因为你要把一年里有限的几个请假机会留给你最最需要的时候!在学校的时候,你可能觉得在苗条和 健康中你会选择前者,等到你工作了,你会发现,健康才是人生最大的财富!

Read More...

星期一, 一月 28, 2008

Linux启动时间的极限优化

  在上次完成嵌入式应用的Linux裁减后, Linux的启动时间仍需要 7s 左右,虽然勉强可以接受,但仍然没有达到我个人所追求的目标——2s 以内。况且,在实际的商用环境中,设备可靠性的要求可是“5个9”(99.999%,即OOS时间低于5分钟/年),这就意味着每减少一秒钟Linux启 动(设备复位)时间,对可靠性都是一个明显的提升。

  言归正传,如何着手对Linux的启动时间进行优化呢?

  CELF(The Consumer Electronics Linux Forum)论坛为我们指引了一个方向。

(1)首先是对Linux启动过程的跟踪和分析,生成详细的启动时间报告。

  较为简单可行的方式是通过PrintkTime功能为启动过程的所有内核信息增加时间戳,便于汇总分析。PrintkTime最早为CELF所 提供的一个内核补丁,在后来的Kernel 2.6.11版本中正式纳入标准内核。所以大家可能在新版本的内核中直接启用该功能。如果你的Linux内核因为某些原因不能更新为2.6.11之后的版 本,那么可以参考CELF提供的方法修改或直接下载它们提供的补丁:http://tree.celinuxforum.org/CelfPubWiki/PrintkTimes

  开启PrintkTime功能的方法很简单,只需在内核启动参数中增加“time”即可。当然,你也可以选择在编译内核时直接指定 “Kernel hacking”中的“Show timing information on printks”来强制每次启动均为内核信息增加时间戳。这一种方式还有另一个好处:你可以得到内核在解析启动参数前所有信息的时间。因此,我选择后一种 方式。

  当完成上述配置后,重新启动Linux,然后通过以下命令将内核启动信息输出到文件:

dmesg -s 131072 > ktime

  然后利用一个脚本“show_delta”(位于Linux源码的scripts文件夹下)将上述输出的文件转换为时间增量显示格式:

/usr/src/linux-x.xx.xx/scripts/show_delta ktime > dtime

  这样,你就得到了一份关于Linux启动时间消耗的详细报告。

(2)然后,我们就来通过这份报告,找出启动中相对耗时的过程。

  必须明确一点:报告中的时间增量和内核信息之间没有必然的对应关系,真正的时间消耗必须从内核源码入手分析。

  这一点对于稍微熟悉编程的朋友来说都不难理解,因为时间增量只是两次调用printk之间的时间差值。通常来说,内核启动过程中在完成一些耗时 的任务,如创建hash索引、probe硬件设备等操作后会通过printk将结果打印出来,这种情况下,时间增量往往反映的是信息对应过程的耗时;但有 些时候,内核是在调用printk输出信息后才开始相应的过程,那么报告中内核信息相应过程的时间消耗对应的是其下一行的时间增量;还有一些时候,时间消 耗在了两次内核信息输出之间的某个不确定的时段,这样时间增量可能就完全无法通过内核信息反应出来了。

  所以,为了准确判断真正的时间消耗,我们需要结合内核源码进行分析。必要的时候,例如上述第三种情形下,还得自己在源码中插入printk打印,以进一步确定实际的时间消耗过程。

  以下是我上次裁减后Linux内核的启动分析:

  内核启动总时间: 6.188s

  关键的耗时部分:
  1) 0.652s - Timer,IRQ,Cache,Mem Pages等核心部分的初始化
  2) 0.611s - 内核与RTC时钟同步
  3) 0.328s - 计算Calibrating Delay(4个CPU核心的总消耗)
  4) 0.144s - 校准APIC时钟
  5) 0.312s - 校准Migration Cost
  6) 3.520s - Intel E1000网卡初始化

  下面,将针对上述各部分进行逐一分析和化解。

(3)接下来,进行具体的分项优化。

  CELF已经提出了一整套针对消费类电子产品所使用的嵌入式Linux的启动优化方案,但是由于面向不同应用,所以我们只能部分借鉴他们的经验,针对自己面对的问题作出具体的分析和尝试。

  内核关键部分(Timer、IRQ、Cache、Mem Pages……)的初始化目前暂时没有比较可靠和可行的优化方案,所以暂不考虑。

  对于上面分析结果中的 2、3 两项,CELF已有专项的优化方案:“RTCNoSync”和“PresetLPJ”。

  前者通过屏蔽启动过程中所进行的RTC时钟同步或者将这一过程放到启动后进行(视具体应用对时钟精度的需求而定),实现起来比较容易,但需要为 内核打补丁。似乎CELF目前的工作仅仅是去掉了该过程,而没有实现所提到的“延后”处理RTC时钟的同步。考虑到这个原因,我的方案中暂时没有引入这一 优化(毕竟它所带来的时间漂移已经达到了“秒”级),继续关注中。

  后者是通过在启动参数中强制指定LPJ值而跳过实际的计算过程,这是基于LPJ值在硬件条件不变的情况下不会变化的考虑。所以在正常启动后记录下内核信息中的“Calibrating Delay”数值后就可以在启动参数中以下面的形式强制指定LPJ值了:

lpj=9600700

  上面分析结果中的 4、5 两项都是SMP初始化的一部分,因此不在CELF研究的范畴(或许将来会有采用多核的MP4出现?……),只能自力更生了。研究了一下SMP的初始化代 码,发现“Migration Cost”其实也可以像“Calibrating Delay”采用预置的方式跳过校准时间。方法类似,最后在内核启动参数中增加:

migration_cost=4000,4000

  而Intel的网卡驱动初始化优化起来就比较麻烦了,虽然也是开源,但读硬件驱动完全不比读一般的C代码,况且建立在如此肤浅理解基础上的“优 化”修改也实在难保万全。基于可靠性的考虑,我最终在两次尝试均告失败后放弃了这一条路。那么,换一个思维角度,可以借鉴CELF在 “ParallelRCScripts”方案中的“并行初始化”思想,将网卡驱动独立编译为模块,放在初始化脚本中与其它模块和应用同步加载,从而消除 Probe阻塞对启动时间的影响。考虑到应用初始化也可能使用到网络,而在我们的实际硬件环境中,只有eth0是供应用使用的,因此需要将第一个网口初始 化的0.3s时间计算在内。

  除了在我的方案中所遇到的上述各优化点,CELF还提出了一些你可能会感兴趣的有特定针对性的专项优化,如:

  ShortIDEDelays - 缩短IDE探测时长(我的应用场景中不包含硬盘,所以用不上)
  KernelXIP - 直接在ROM或Flash中运行内核(考虑到兼容性因素,未采用)
  IDENoProbe - 跳过未连接设备的IDE口
  OptimizeRCScripts - 优化initrd中的linuxrc脚本(我采用了BusyBox更简洁的linuxrc)

  以及其它一些尚处于设想阶段的优化方案,感兴趣的朋友可以访问CELF Developer Wiki了解详情。

(4)优化结果

  经过上述专项优化,以及对inittab、rcS脚本的冗余裁减,整个Linux内核的启动时间从优化前的 6.188s 下降到了最终的 2.016s,如果不包含eth0的初始化,则仅需 1.708s(eth0初始化可以和系统中间件及部分应用加载并行),基本达到了既定目标。与Kexec配合,可以大大降低软件故障导致的复位时间,有效的提升了产品的可靠性。

  大家如果对内核启动时间的优化还有什么建议或疑惑,都欢迎与我探讨。:)

Read More...

嵌入式应用Linux裁减的初次尝试

  前段时间因为嵌入式应用开发的需要,对Linux进行了一次大幅度的裁减。由于是初次接触Linux启动的核心部分,所以基本上还是对网上各种裁减方案的拼凑和整理,包含自己理解的部分实在很少。总的来说效果不算理想,后面还有很长的路要走。

这里就大致说说目前这个Linux裁减方案的“雏形”吧。

  1. 内核裁减

对Linux内核部分的裁减主要根据实际需求进行了重编译,去掉了大部分用不上的特性,以及实际硬件环境之外的设备驱动。这一过程没啥技术含量,就不细说了。

2. initrd改造

常规的Linux系统启动过程中,initrd仅仅充当一个临时的rootfs,在加载实际的rootfs后即被卸载或转移。出于精简的考虑,我将 原rootfs并入了initrd,让它直接充当rootfs,以节省启动时间,并减小体积。(这个改造方案相对来说最简单,也足以满足实际需要)

改造的过程主要是基于原make install自动生成的initrd镜像之上,进行以下“手术”:

(1) 用BusyBox的linuxrc替代原initrd中的初始化脚本,并将原linuxrc脚本中有用得上的初始化任务都合并至etc/inittab中,以节省启动时间。

(2) 因为要充当rootfs,所以还需为initrd添加Linux启动及运行所必须的一些文件夹和文件(主要复制自原rootfs):

/dev
tty3 - tty10 终端会话设备(Console登录使用)
ttyS0、ttyS1 串口终端设备(串口登录使用)
ptmx、pts 虚拟终端设备(远程登录使用)
/etc
fstab 加载设备的配置文件(后面详述)
gettydefs 仅保留Virtual Console一项
group 仅保留root对应的项
hostname 包含本机的主机名
inittab 初始化脚本(后面详述)
issue 包含本机的全程登录欢迎文字
passwd 仅保留root对应的项
shadow 仅保留root对应的项
termcap 仅保留用于本地console及远程登录的配置项
/etc/init.d
rcS 次级初始化脚本(后面详述)
/lib
libcrypt.so.1 登录认证(login)所需的库文件
/mnt
/proc
/sys
/tmp
/usr
/var

(3) 修改etc/fstab存储设备加载配置文件,只包含下面四行:

sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
tmpfs /dev/shm tmpfs size=512m 0 0
devpts /dev/pts devpts defaults 0 0

由于实际硬件环境的内存比较大,所以给临时文件系统分配的内存上限比较充裕

(4) 创建etc/inittab初始化脚本。由于init模块采用了BusyBox的精简版本,而它采用的inittab文件格式较普通版本有一些区别,所以特别按照BusyBox的格式重新编写了。文件较大,下面仅列举其中的关键部分:

::sysinit:/bin/mount -a 加载etc/fstab中配置的所有存储设备
::sysinit:/bin/mkdir /dev/shm/var 在tmpfs中划分用作var的部分
::sysinit:/bin/mkdir /dev/shm/tmp 在tmpfs中划分用作tmp的部分
::sysinit:/bin/chmod 1777 /dev/shm/var 修改var为合适的权限
::sysinit:/bin/chmod 1777 /dev/shm/tmp 修改tmp为合适的权限
::sysinit:/bin/mount --bind /dev/shm/var /var 将/var绑定到tmpfs中
::sysinit:/bin/mount --bind /dev/shm/tmp /tmp 将/tmp绑定到tmpfs中

::sysinit:/bin/hostname -F /etc/hostname 从etc/hostname中读取并设置主机名
::sysinit:/sbin/ifconfig lo 127.0.0.1 up 配置IP环回界面
::sysinit:/sbin/telnetd 启动Telnet Daemon
::sysinit:/etc/init.d/rcS 调用次级初始化脚本(完成不能在inittab中进行的初始化任务)

::sysinit:/bin/mkdir /var/log 创建日志文件夹
::sysinit:/bin/touch /var/log/messages 创建日志文件
::respawn:/sbin/syslogd -n -m 30 -C 加载循环缓冲模式的系统日志daemon
::respawn:/sbin/klogd -n

::askfirst:/bin/login 在console创建登录进程
tty2::askfirst:/bin/login 在tty2-tty6上创建额外的登录进程
tty3::askfirst:/bin/login
...
ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100 在串口COM1上创建登录进程
tty10::respawn:/sbin/logread -f 将所有日志打印输出到tty10

(5) 创建etc/init.d/rcS次级初始化脚本,包含以下内容:

/bin/mount -o remount,rw / 将rootfs重新加载为可读可写方式

注:由于试验的方便,生成的initrd采用了Ext2文件系统。在实际应用中考虑换为CRAMFS(压缩ROM镜像文件系统),以进一步缩减镜像文件体积并提高读取效率。

3. Boot Loader修改

由于这个裁减方案仅仅使用了内核镜像及initrd,保持了与标准引导方式的高度兼容,因此适用于几乎任何Boot Loader。由于裁减实验中需要频繁替换内核和initrd镜像,因此使用了便于控制的GRUB,以提高实验效率。如果最终方案采取Flash作为镜像 载体,则建议使用LILO,以提高兼容性并节省空间。
为了与本方案中以initrd作为rootfs保持一致,Boot Loader的配置文件中需要修改引导参数,指定“root=/dev/ram0”,无需其它额外的参数。

经过上述裁减,整个Linux的启动时间已经缩短到10s以内。内核+initrd的镜像大小也不足3M,基本达到了预期的目标。后续会针对启动的各个环节作进一步的分析和优化,以期进一步缩短启动时间。

Read More...

2.6的Kernel LOGO真容易改

试着改了一下,似乎比2.4容易。2.6的logo数据在/drivers/video/logo里,ppm文件就是logo图像了。每个ppm对应一 个.c文件,内容大概就是图像尺寸、调色板、位图数据等信息。.c文件无需自己建立,在make的时候如果不存在某个ppm文件对应的.c文件,就会自动 从ppm生成一个,然后把它编译成.o文件。所以看看目录下哪些.ppm文件有同名的.o文件,就说明那个logo被编译进了kernel。标准的224 色logo是logo_linux_clut224.ppm,因此修改这个图片就可以实现修改logo了。 在windows下,可以用PaintShopProX直接打开ppm进行编辑,编辑完毕后用decrease color depth命令降为224色,然后保存,把logo_linux_clut224.c删掉,重新make就可以了。这个是我昨晚随便改的logo :


在 深入一点点。很容易发现,对于一般的vga console,logo是由drivers/video/fbmem.c里的fb_show_logo()函数显示的,这个函数的调用者是 drivers/video/console/fbcon.c(跟2.4差不多,嗯)。这个函数做的事情不多,就是先把非8位色深的位图转换为8位色深, 然后用info->fbops->fb_imageblit(info, &image);把logo显示出来,有一个cpu时显示一个logo,有2个cpu时显示2个,以此类推。
略加修改,就可以实现将logo居中显示,并加入一个“重复显示右边界”,也就是把logo最右边4个点宽的区域作为背景填充到整个logo bar。diff如下:

--- /gs2e/source/linux26-2edev/drivers/video/fbmem.c2006-08-29 14:07:15.000000000 +0800
+++ ./fbmem.c2006-09-27 20:40:08.000000000 +0800
@@ -375,9 +375,9 @@
int fb_show_logo(struct fb_info *info)
{
u32 *palette = NULL, *saved_pseudo_palette = NULL;
-unsigned char *logo_new = NULL;
-struct fb_image image;
-int x;
+unsigned char *logo_new = NULL, *border = NULL;
+struct fb_image image, imageborder;
+int x, xoffset;

/* Return if the frame buffer is not mapped or suspended */
if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
@@ -421,12 +421,45 @@
image.height = fb_logo.logo->height;
image.dy = 0;

+#ifdef CONFIG_LOGO_REPEAT_RIGHT
+border = kmalloc(4 * fb_logo.logo->height, GFP_KERNEL);
+if (border != NULL){
+ for (x = 0; x < fb_logo.logo->height; x++){ /* use x as y */
+*((u32 *)border + x) = /* will repeat 4 pixels of the right side*/
+*(u32 *)(image.data + (x+1)*fb_logo.logo->width - 4);
+ }
+ imageborder.depth = 8;
+ imageborder.data = border;
+ imageborder.width = 4;
+ imageborder.height = image.height;
+ imageborder.dy = 0;
+ for (x = 0; x < info->var.xres; x+=4){
+imageborder.dx = x;
+info->fbops->fb_imageblit(info, &imageborder);
+ }
+ kfree(border);
+}
+#endif
+#ifndef CONFIG_CENTER_LOGO
+xoffset = 0;
for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) &&
x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
image.dx = x;
info->fbops->fb_imageblit(info, &image);
}
-
+#else
+xoffset = (info->var.xres - num_online_cpus() * (fb_logo.logo->width + 8))>>1;
+if (xoffset<0)xoffset = 0;
+ for (x = xoffset; x < num_online_cpus() * (fb_logo.logo->width + 8) + xoffset &&
+ x <= info->var.xres-fb_logo.logo->width+xoffset; x += (fb_logo.logo->width + 8)) {
+ image.dx = x;
+ info->fbops->fb_imageblit(info, &image);
+}
+#endif
kfree(palette);
if (saved_pseudo_palette != NULL)
info->pseudo_palette = saved_pseudo_palette;
我在这里定义了两个配置变量,CONFIG_LOGO_REPEAT_RIGHT和CONFIG_CENTER_LOGO,修改/drivers/video/logo/Kconfig,加上:
config CENTER_LOGO
bool "Center logo"
depends on LOGO
default n
config LOGO_REPEAT_RIGHT
bool "Repeat the right border (4 pixels)"
depends on LOGO
default n
这样就可以在make menuconfig之类的界面中设置是否开启这两项功能了。 更多关于logo hack的信息,可以参考: http://gentoo-wiki.com/HOWTO_Linux_Logo_Hack

Read More...

[Linux] 更換Linux Boot up Logo

2.4 kernel 需要浩大工程才能完成的 Logo更換, 沒想到在2.6 中是
a piece of cake....
如何換咧?

別吵!! 準備好飲料爆米花, silence your mobile phone, 我們正式開始.

1. 到http://kernel.org下載2.6 kernel, 目前已經到2.6.11.4了!

2. 準備好美美的圖片, 使用png 格式, 顏色要少於224, 此例是使用1024x80.
使用pngtopnm及pnmtoplainpnm這兩個tool來轉換
pngtopnm my_logo.png | pnmtoplainpnm > logo_linux_clut224.ppm
cp logo_linux_clut224.ppm /your_kernel_source/drivers/video/logo/

3. Untar kernel source code後, 執行 make menuconfig
Graphics Support ->
[*] Support for frame buffer devices
[*] VESA VGA graphics support

Console display driver support ->
[*] Video mode selection support

<*> Framebuffer Console support

[*]Select compiled-in fonts
[*]VGA 8x16 font

Logo configuration->
[*]Bootup logo
[*] Standard 224-color Linux logo

4. 接下來就是compile kernel囉, 這都不會就收工了 =.=|||
make bzImage

5. 選好心儀的bootloader, 在append 參數中, 加上 'vga=0x318' 會設定
開機時使用1024x768 24bit的模式.

6. 開機試試囉... Enjoy yourself ^_^

Read More...

lInux下修改logo

但你如果想在LCD上显示自己的Logo,那下面我介绍一下自定义Logo的方法:
    (1)进入
linuxkde图形界面,使用The  GIMP 图像编辑器打开你想要的图像文件,依次选择图像->模式->索引颜色,将颜色改为224色;至于图片大小,不要大于你的显示器分辨率就好(我只试过80*80和320*240的大小),最后将文件保存为ppm格式(ASCii码),文件名为:logo_linux_clut224.ppm。
    (2)将logo_linux_clut224.ppm拷贝到/drivers/video/logo文件夹下,替换原有的文件(记得备份啊,以防万一)。
    (3)重新编译内核,tftp到开发板启动。

Read More...