完成了所谓的理想
放纵了情绪的泛滥
汗都流亁 天都微亮
然后怎样
拥有了旅行的空档
却遗失流浪的背囊
沿着轨道一直浏览
然后怎样
假期过完有什么打算
走过一个天堂少一个方向
谁在催我成长 让我失去迷途的胆量
我怕谁失望我为谁而忙
我最初只贪玩为何变负担
为何我的问题 总得等待别人的答案
我的快乐时代唱烂
才领悟代价多高昂
不能满足不敢停站
然后怎样
2010年的最后几天,满屏的年度总结,我就对我自己说:“绝对不能如去年一样落入俗套!”,于是。。。我成功的憋到了2011年第一个周末。。。
浙大真是一个人才辈出的地方,一直听pff跟houshui在说这个冰河如何如何,最近才有机会看到他的博客,崇拜得五体投地。本想学冰河的文章来总结一下我的2010, 但看了一下我在2010年所写过的寥寥数文,我不得不放弃了这样的念头,仅能取个类似的标题来表达我的崇拜。
我的2010,参加了一场求婚N场订婚并缺席N场婚礼,办了去香港的签证却因为错过了十一黄金周最终没有成行。尽管心中无比鄙视,却不免俗地去了一趟世博,又不免俗的“更后侮”一把。为某些官员的政绩工程做出了小部分贡献,但也没能获得啥,反而个税交得多了,工资增长幅度赶不上实际物价增长,甚至连官方CPI都赶不上。值得大书特书的似乎也只有换工作了,离开了原先的老东家勤路软件,到了HMT(HangZhou Motorola Technology)。这是我第一次换工作,如今回头看看,我自己都很困惑我是如何在对以前同事的万般不舍中推动整件事情的发展的,有那么几次我都快要放弃了,但最终还是选择了跳槽。到了HMT以后,能够明显的感觉到与原公司的不同,两相比较之下似乎也符合了丁香园CTO冯大辉大牛在前不久的一篇文章里所提到的大公司与小公司的不同。
小公司的人力资源比较少,像一个项目开发的Team最多也只有五六人,我原先的Team更是只有三个人。开发人员除了做编程以外,要做的其他事情零零碎碎也挺多的,像SVN搭建,代码服务器搭建,权限管理,项目进度控制等等基本上都是自己包办了,这样也就导致了小公司里的开发人员基本上都是多面手。而且小公司里的项目开发,所有的代码基本上都是本Team内的成员写的,像我原先的项目从驱动层写到应用层,对整个项目的架构以及实现方法也更清楚一些。大公司则不然,各个小组负责各自的部分,驱动是驱动,应用是应用,平台是平台,IT部门是IT部门,分得很清楚。不同的层之间会选择封装提供API,尽量不让其他组的人看到自己的代码实现,这样也就导致像我们做应用的对一些底层的实现在一开始是云里雾里,遇到某些底层的问题就只好束手无策,转而寻求其他小组的帮忙了。
大公司对流程和项目管理更为看重。小公司的项目通常比较小,有些开发时间也短,于是开发人员在开发过程中会忽略流程和文档这些内容,只求在最短的时候内完成项目。项目质量的控制基本靠个人,后续项目的开发支持基本靠口头交流和代码阅读,一但Team内人员流失,新接手的人员便需要花费大量时间去了解前任的代码实现方法和项目架构。而大公司则在这方面好些,对流程和项目管理的重视保证项目开发的质量并且游刃有余的面对正常人员流动的情况。
扯得远了。。。
随着我的跳槽,我也跟着搬了一次家,从城西搬到了滨江。搬家之后才算体会到了城西的好,以至于每次去城西都要感慨一番。滨江这个荒芜的地方,想要找个腐败吃饭的地方都难,怀念在城西时每到周末都有饭局可以蹭有球可以打的日子T_T。
另外在10年的1月份,原先在blogbus的博客因为blogbus的陌名被封而无法访问,再加上后来的CN域名要求备案,于是我选择到dreamhost上购买了虚拟主机以及域名来重新搭建我的个人博客。价格不是很贵,两年的host plan只要50美刀,再加上域名一年10美刀,每年的成本也就35美刀,在国内买件衣服差不多也这价,前不久又发现在拥有host plan的前提下,第二年的域名是免费的,成本更低了。后来跟阿德相互讨论了一下,发现国外的虚拟主机提供商跟国内的虚拟主机提供商比起来,真的是一个在天一个在地,于是成功拉拢阿德将他自己的博客从国内移到了国外,跟我一起合租虚拟主机,成本再度降低。当初购买这个虚拟主机的本意是能够自由的写些博客,不用时不时的因为被博客服务提供商的自我阉割而憋满肚子的火无处发泄,如今回头一看,在这一年中博客写的只有寥寥无几的几篇,反而是因为虚拟主机提供的SSH功能得以无障碍的翻墙上twitter,发了不少的微博,也算是此消彼涨吧。
年初的时候,曾经有机会去谈一场真正的恋爱,但我退却了,似乎我是这样一种人, 害怕过于亲近,喜欢保持距离,不喜欢表达感情。在这里对那位女孩说声对不起,不过现在她应该也有自己的幸福了,套用冰河的一句话,“如果每个心爱的小姑娘都过上幸福的生活了,那我应该也是幸福的”。
此情可待成追忆,只是当时已茫然。过去的一切已经成为回忆,将来的一切仍是未知,期待我的2011。。。
《精通正则表达式》的中文译者余晟老师曾经写过一篇文章《看得见的和看不见的》,里面讲到一个故事:
“2003年夏天,我正在复习托福考试,每天的生活就是背单词,做一两套模拟题。当时正是暑假,许多人都回家了,留下的人也大多过得逍遥,想到这自己还能坚持每天复习,我颇有些自豪。当时托福的满分是667,我每次做模拟题都有630到640,自己也很满意——复习托福不过如此嘛。考前一两周,与朋友W通电话,我告诉他自己水平很稳定。于是他问我“很稳定是个什么概念?”。我说“就是每次都有630左右啊。”“这怎么能行呢?复习这种考试就应该只有一个目标啊。”我忙问“什么目标?” 他说,“就是满分啊,要不你总这么630就满意了,考试时全部发挥出来最多也只有630。再说我们大家复习都是以满分为目标的……” 许多年后,我依然清楚记得当时自己有多么震惊和羞愧,他的话好像晴空霹雳,而我猛然发现自己之前的想法是多么可笑。于是我强打起精神,努力分析总结自己每一个错误,努力抠每一点分数。可惜觉悟还是太晚了,考试的分数果然只有六百出头。这些年来,我时常想到,如果当年我能早点看到其他人认真投入复习的样子,而不是看看自己周围就满意了(好像看到玻璃匠得了6法郎,就认定打破玻璃有益于经济发展一样),会是一番多么不同的景象呀。不过,我也因此学会了在许多事情上“较真”,不要觉得还凑合,就糊弄自己,坚持下来还是很有收获的。”
虽然这篇文章的接下来几个例子跟上面的故事更多想表达的主题是“多留心一些‘看不见的’的东西,有助于我们形成更加准备的认识”,但对于我来说,触动最大的反而是这第一个故事,做事情要以满分为目标,而不仅是达到最低标准。
无独有偶,入职HMT后公司给的推荐阅读《做事做到位》里以胡适先生的《差不多先生》为引子,在讲述国人的做事不到位现象及如何消除这种现象的过程中,也提到了类似的观点:“凡事都要以高标准要求自己”。
凡事都要以高标准要求自己,也就要求一切要追求尽善尽美。犹豫是做决定之前的事,一旦做出决定,那么就要尽自己的最大努力把事情做到最好。就好像准备考试一样,应该总是以满分做为自己的目标,而不仅仅是满足在及格线上。那些以及格线做为自己标准的人,绝大多数都达不到及格,而那些以满分为自己目标的人,大部分都能取得很好的成绩。任何值得做的事,都值得做好,任何值得做好的事,都值得做得尽善尽美。
追求尽善尽美,就是注重细节的完美。在能看到见的地方,别人能够做到跟你一样好,那么就用看不到的地方的完美来击败对手。这里所说的“看不到的地方”指得就是细节的地方, 一个最典型的例子就是百度搜索框高度:
有个好事者分析了一下百度搜索框跟Google搜索框的高度,发现百度搜索框比Google的搜索框要高出6个像素,将百度搜索框跟大部分浏览器的地址栏一比较,发现百度搜索框的高度同样也比那些地址栏高一小块,于是他用这一发现来解释为什么会有人宁肯在百度中输入新浪网址而不是在地址栏上输入:
- 百度的搜索框在屏幕中间,浏览器地址栏在屏幕上方,根据懒人法则,他肯定首选百度搜索框,因为光标定位时鼠标移动路径相对会比较短;
- 百度的搜索框高度比地址栏高,这就更加使得懒人愿意使用百度搜索框来代替地址栏,因为高高的输入框能更快捷容易的定位光标。
这篇文章出来后不久, Google中国的搜索框宽度也跟着提高了6个像素,似乎进一步证明了这一说法。百度能在中国市场打败Google中国,可以说是细节的问题,细节决定成败。
这就是百分百标准:以高标准要求自己,尽善尽美并注重细节的去完成每一件事情。随之而来的就是在每一件事情上你都能够超出别人的想象,哪怕只是一点点也能给别人留下好的印象。同时,在百分百标准下,会使得你有额外的动力去学习及获取新的知识,不断成长,不断改进。尤其是在这样一个技术不断的更新的时代,只有不断的去学习新的技术和知识,才能跟得上时代的节奏。
宿主机环境:
Linux version 2.6.32-24, Ubuntu10.04
gcc version 4.1.3, Thread model: posix;
GNU Make 3.81
arm-linux-gcc 3.4.5
开发板环境:
CPU: S3C2410X
SDRAM: HY57V561620(32MB)
FLASH: K9F1208(64MB)
Linux Kernel: 2.6.23.8
移植步骤:
运行kernel的时候,我们会发现如下的错误:
JFFS2 version 2.2. (NAND) .. 2001-2006 Red Hat, Inc.
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
s3c2410-lcd s3c2410-lcd: no platform data for lcd, cannot attach
s3c2410-lcd: probe of s3c2410-lcd failed with error -22
lp: driver loaded but no devices found
ppdev: user-space parallel port driver
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing enabled
s3c2410-uart.0: s3c2410_serial0 at MMIO 0×50000000 (irq = 70) is a S3C2410
s3c2410-uart.1: s3c2410_serial1 at MMIO 0×50004000 (irq = 73) is a S3C2410
s3c2410-uart.2: s3c2410_serial2 at MMIO 0×50008000 (irq = 76) is a S3C2410
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
表示与LCD相关的平台信息没有找到,因此没法加载LCD。 我们所要做的就是将对LCD设备的初始化加入到整个S3C2410的初始化过程中。
通过对arch/arm/mach-smdk2410/mach-smdk2410.c与arch/arm/mach-smdk2440/mach-smdk2440.c进行对比后,可以发现在smdk2440上存在着对结构体s3c2410fb_mach_info的初始化,而smdk2410则不存在,所以我们所要做的是把smdk2440上的初始化操作复制到smdk2410上,并做一定的修改。
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8$ vim arch/arm/mach-s3c2410/mach-smdk2410.c
#include <asm/plat-s3c24xx/common-smdk.h>
#include <asm/arch/smdk2410.h> // sean chi 18Aug2010, added.
#include <asm/arch/fb.h> // sean chi 31Aug2010, added.
static struct map_desc smdk2410_iodesc[] __initdata = {
{ vSMDK2410_ETH_IO , pSMDK2410_ETH_IO, SZ_1M, MT_DEVICE }, // sean chi 18Aug2010, added.
/* nothing here yet */
};// sean chi 31Aug2010, added.
static struct s3c2410fb_mach_info nano2410_fb_info __initdata = {
.fixed_syncs = 1,
.type = S3C2410_LCDCON1_TFT,
.width = 240,
.height = 320,
.xres = {
.min = 240,
.max = 240,
.defval = 240,
},.yres = {
.min = 320,
.max = 320,
.defval = 320,
},.bpp = {
.min = 16,
.max = 16,
.defval = 16,
},
.regs = {.lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
S3C2410_LCDCON1_TFT |
S3C2410_LCDCON1_CLKVAL(0×04),.lcdcon2 = S3C2410_LCDCON2_VBPD(1) |
S3C2410_LCDCON2_LINEVAL(319) |
S3C2410_LCDCON2_VFPD(5) |
S3C2410_LCDCON2_VSPW(1),.lcdcon3 = S3C2410_LCDCON3_HBPD(36) |
S3C2410_LCDCON3_HOZVAL(239) |
S3C2410_LCDCON3_HFPD(19),.lcdcon4 = S3C2410_LCDCON4_MVAL(13) |
S3C2410_LCDCON4_HSPW(5),.lcdcon5 = S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVLINE|
S3C2410_LCDCON5_INVVFRAME|
S3C2410_LCDCON5_PWREN|
S3C2410_LCDCON5_HWSWP,
},
#if 1
.gpccon =0xaaaaaaaa,
.gpccon_mask =0xffffffff,
.gpcup =0xffffffff,
.gpcup_mask =0xffffffff,.gpdcon =0xaaaaaaaa,
.gpdcon_mask =0xffffffff,
.gpdup =0xffffffff,
.gpdup_mask =0xffffffff,#endif
.lpcsel = 0×01,
};……
…….
static void __init smdk2410_init(void)
{
s3c24xx_fb_set_platdata(&nano2410_fb_info); // sean chi 31Aug2010, added.
platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
smdk_machine_init();
}
在对源代码进行修改了以后,配置内核,将Device Driver->Graphic support下的Support for frame buffer devices, S3C2410 LCD framebuffer support和Bootup logo勾选上。
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8$ make menuconfig
Device Driver –>
Graphics support ->
<*>Support for frame buffer devices
<*>S3C2410 LCD framebuffer support
<*>Bootup logo
对于其他版本来说,在这里可以重新编译内核,加载到开发板上运行就可以了,但在linux kernel 2.6.23上,这还不够,这时候如果编译加载的话,会在开发板上显示如下结果:
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Unable to handle kernel NULL pointer dereference at virtual address 00000014
pgd = c0004000
[00000014] *pgd=00000000
Internal error: Oops: 805 [#1]
Modules linked in:
CPU: 0 Not tainted (2.6.23.8 #18)
PC is at s3c2410fb_set_lcdaddr+0×94/0xb4
LR is at 0xc02fdb48
pc : [] lr : [] psr: 60000013
sp : c03ebe24 ip : c02fdb48 fp : c03ebe40
r10: c02fc714 r9 : c0333d60 r8 : c02fc70c
r7 : c0305358 r6 : 19e80000 r5 : 19e92c00 r4 : 000000f0
r3 : 00000014 r2 : 00000001 r1 : 00000001 r0 : 00000025
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: c000717f Table: 30004000 DAC: 00000017
Process swapper (pid: 1, stack limit = 0xc03ea258)
Stack: (0xc03ebe24 to 0xc03ec000)
be20: c3c4025c c4a00000 c0305358 c0333d60 c03ebe60 c03ebe44 c014f03c
be40: c014e500 00000000 c3c4025c c3c40000 00000000 c03ebe9c c03ebe64 c001afa0
be60: c014ef7c c3c4025c c3c400a8 00000020 c03dd454 c02fc714 00000000 c03052c8
be80: c03052c8 c0337038 c0024860 00000000 c03ebeac c03ebea0 c0179df0 c001aad4
bea0: c03ebed0 c03ebeb0 c0177f30 c0179de0 c02fc7d4 c02fc714 c0178090 c03052c8
bec0: c03ea000 c03ebee8 c03ebed4 c0178110 c0177e58 00000000 c03ebeec c03ebf14
bee0: c03ebeec c0176f44 c01780a0 c0309250 c0309250 c02fc75c 00000000 c03052c8
bf00: c03052d0 c0309164 c03ebf24 c03ebf18 c0178190 c0176f04 c03ebf4c c03ebf28
bf20: c017770c c0178180 c03052c8 00000000 00000000 c0023410 c03ea000 00000000
bf40: c03ebf60 c03ebf50 c017860c c01776a8 00000000 c03ebf70 c03ebf64 c0179f04
bf60: c017859c c03ebf80 c03ebf74 c014f284 c0179ea8 c03ebff4 c03ebf84 c0008c3c
bf80: c014f280 e1a00007 e89da9f0 00000000 00000001 e24cb004 00000000 00000000
bfa0: 00000000 c03ebfb0 c002cec4 c0044b38 00000000 00000000 c0008b5c c004aee8
bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfe0: 00000000 00000000 00000000 c03ebff8 c004aee8 c0008b6c 1580302c e5943018
Backtrace:
[] (s3c2410fb_set_lcdaddr+0×0/0xb4) from [] (s3c2410fb_init_registers+0xd0/0×144)
r7:c0333d60 r6:c0305358 r5:c4a00000 r4:c3c4025c
[] (s3c2410fb_init_registers+0×0/0×144) from [] (s3c2410fb_probe+0x4dc/0x5e8)
r7:00000000 r6:c3c40000 r5:c3c4025c r4:00000000
[] (s3c2410fb_probe+0×0/0x5e8) from [] (platform_drv_probe+0×20/0×24)
[] (platform_drv_probe+0×0/0×24) from [] (driver_probe_device+0xe8/0x18c)
[] (driver_probe_device+0×0/0x18c) from [] (__driver_attach+0×80/0xe0)
r8:c03ea000 r7:c03052c8 r6:c0178090 r5:c02fc714 r4:c02fc7d4
[] (__driver_attach+0×0/0xe0) from [] (bus_for_each_dev+0×50/0×84)
r5:c03ebeec r4:00000000
[] (bus_for_each_dev+0×0/0×84) from [] (driver_attach+0×20/0×28)
r7:c0309164 r6:c03052d0 r5:c03052c8 r4:00000000
[] (driver_attach+0×0/0×28) from [] (bus_add_driver+0×74/0x1b0)
[] (bus_add_driver+0×0/0x1b0) from [] (driver_register+0×80/0×88)
[] (driver_register+0×0/0×88) from [] (platform_driver_register+0x6c/0×88)
r4:00000000
[] (platform_driver_register+0×0/0×88) from [] (s3c2410fb_init+0×14/0x1c)
[] (s3c2410fb_init+0×0/0x1c) from [] (kernel_init+0xe0/0x29c)
[] (kernel_init+0×0/0x29c) from [] (do_exit+0×0/0×748)
Code: e3530000 e1a01004 1bfbec4f e3a03014 (e4836004)
Kernel panic – not syncing: Attempted to kill init!
通过上面错误信息中的Backtrace,可以看到问题出在一个名为s3c2410fb_lcd_setaddr的函数上。在源代码中找到这个函数,存在于drivers/video/s3c2410fb.c文件里,通过对Linux 2.6.22, 2.6.23, 2.6.24的对比,发现对这段函数做如下代码修改即可,原因末知,发了邮件给写这部分代码的Ben Dooks大神询问,末回。。。
static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)
{
struct fb_var_screeninfo *var = &fbi->fb->var;
void __iomem *regs = fbi->io; // sean chi 31Aug2010, added.
unsigned long saddr1, saddr2, saddr3;saddr1 = fbi->fb->fix.smem_start >> 1;
saddr2 = fbi->fb->fix.smem_start;
saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8;
saddr2>>= 1;saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH((var->xres * var->bits_per_pixel / 16) & 0x3ff);
dprintk(“LCDSADDR1 = 0x%08lx\n”, saddr1);
dprintk(“LCDSADDR2 = 0x%08lx\n”, saddr2);
dprintk(“LCDSADDR3 = 0x%08lx\n”, saddr3);writel(saddr1, regs + S3C2410_LCDSADDR1); // sean chi 31Aug2010, was writel(saddr, S3C2410_LCDSADDR1);
writel(saddr2, regs + S3C2410_LCDSADDR2);
writel(saddr3, regs + S3C2410_LCDSADDR3);
}
除此之外,还要把drivers/video/fbmem.c中的register_framebuffer做如下修改:
/**
* register_framebuffer – registers a frame buffer device
* @fb_info: frame buffer info structure
*
* Registers a frame buffer device @fb_info.
*
* Returns negative errno on error, or zero for success.
*
*/int
register_framebuffer(struct fb_info *fb_info)
{
int i;
struct fb_event event;
struct fb_videomode mode;if (num_registered_fb == FB_MAX)
return -ENXIO;
num_registered_fb++;
for (i = 0 ; i < FB_MAX; i++) if (!registered_fb[i]) break; fb_info->node = i;fb_info->dev = device_create(fb_class, fb_info->device,
MKDEV(FB_MAJOR, i), “fb%d”, i);
if (IS_ERR(fb_info->dev)) {
/* Not fatal */
printk(KERN_WARNING “Unable to create device for framebuffer %d; errno = %ld\n”, i, PTR_ERR(fb_info->dev));
fb_info->dev = NULL;
} else
fb_init_device(fb_info);if (fb_info->pixmap.addr == NULL) {
fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
if (fb_info->pixmap.addr) {
fb_info->pixmap.size = FBPIXMAPSIZE;
fb_info->pixmap.buf_align = 1;
fb_info->pixmap.scan_align = 1;
fb_info->pixmap.access_align = 32;
fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;
}
}
fb_info->pixmap.offset = 0;if (!fb_info->pixmap.blit_x)
fb_info->pixmap.blit_x = ~(u32)0;if (!fb_info->pixmap.blit_y)
fb_info->pixmap.blit_y = ~(u32)0;if (!fb_info->modelist.prev || !fb_info->modelist.next)
INIT_LIST_HEAD(&fb_info->modelist);fb_var_to_videomode(&mode, &fb_info->var);
fb_add_videomode(&mode, &fb_info->modelist);
registered_fb[i] = fb_info;event.info = fb_info;
// sean chi 31Aug2010, removed. fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);return 0;
}
否则将会出现kernel的启动过程hang掉的情况,至于为什么这么改的原因。。。我也不知道,同样问了Ben Dooks大神,没回。。。
对Linux2.6.23进行这样的修改将会导致启动后LCD屏上不会显示LOGO, 原因在于Linux启动时LOGO的加载是由fb_notifier_call_chain调用的,但由于我们之前把fb_notifier_call_chain从启动过程中去掉了,因此我们不会看到LOGO,但通过编写应用程序对/dev/fb0进行读写依然可以在LCD屏上画出图像。
宿主机环境:
Linux version 2.6.32-24, Ubuntu10.04
gcc version 4.1.3, Thread model: posix;
GNU Make 3.81
arm-linux-gcc 3.4.5
开发板环境:
CPU: S3C2410X
SDRAM: HY57V561620(32MB)
FLASH: K9F1208(64MB)
NET: CS8900
Linux Kernel: 2.6.23.8
移植步骤:
使用s3c2410的默认配置文件编译出来的内核不能识别USB设备,在插上U盘的时候,内核会显示如下内容:
usb 1-1: new full speed USB device using s3c2410-ohci and addr2
usb 1-1: device descriptor read/64, error -62
usb 1-1: device descriptor read/64, error -62
usb 1-1: new full speed USB device using s3c2410-ohci and address 3
usb 1-1: device descriptor read/64, error -62
usb 1-1: device descriptor read/64, error -62
usb 1-1: new full speed USB device using s3c2410-ohci and address 4
usb 1-1: device not accepting address 4, error -62
usb 1-1: new full speed USB device using s3c2410-ohci and address 5
usb 1-1: device not accepting address 5, error -62
这里有两个问题需要解决,一个是”device not accepting address #, error -62″, 另外一个就是在查看partition下的分区信息的时候,没有出现usb设备:
[root@armsys /]# cat /proc/partitions
major minor #blocks name
31 0 16 mtdblock0
31 1 2048 mtdblock1
31 2 4096 mtdblock2
31 3 2048 mtdblock3
31 4 4096 mtdblock4
31 5 10240 mtdblock5
31 6 24576 mtdblock6
31 7 16384 mtdblock7
为了解决”error -62″的问题,我们需要修改drivers/usb/host/ohci-s3c2410.c:
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8$ vim drivers/usb/host/ohci-s3c2410.c
#include <asm/hardware.h>
#include <asm/arch/usb-control.h>
#if 1 // sean chi 20Aug2010, added.
#include <asm/arch-s3c2410/regs-clock.h>
#include <asm-arm/io.h>unsigned long upllvalue = (0×78 << 12) | (0×02 << 4) | (0×03);
#endif#define valid_port(idx) ((idx) == 1 || (idx) == 2)
/* clock device associated with the hcd */
…………
static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd)
{
struct s3c2410_hcd_info *info = dev->dev.platform_data;dev_dbg(&dev->dev, “s3c2410_start_hc:\n”);
clk_enable(usb_clk);
mdelay(2); /* let the bus clock stabilise */clk_enable(clk);
if (info != NULL) {
info->hcd = hcd;
info->report_oc = s3c2410_hcd_oc;if (info->enable_oc != NULL) {
(info->enable_oc)(info, 1);
}
}// sean chi 20Aug2010, added.
while (upllvalue !=__raw_readl(S3C2410_UPLLCON))
{
__raw_writel(upllvalue, S3C2410_UPLLCON);
mdelay(1);
}
}
之后,我们需要重新配置内核,确保勾选以下选项
Device Drivers —>
[*] USB support —>
[*] Support for Host-side USB
[*] USB device filesystem
[*] OHCI HCD support
[*] USB Mass Storage support
[*] The shared table of common (or usual) storage devicesSCSI device support —>
[*] SCSI device support
[*] SCSI target support
[*] legacy /proc/scsi/ support
[*] SCSI disk support
重新编译, 加载新的内核,这样从根文件系统上查看分区信息就可以看到usb设备的分区信处sda, sda1。
[root@armsys /]# cat /proc/partitions
major minor #blocks name
31 0 16 mtdblock0
31 1 2048 mtdblock1
31 2 4096 mtdblock2
31 3 2048 mtdblock3
31 4 4096 mtdblock4
31 5 10240 mtdblock5
31 6 24576 mtdblock6
31 7 16384 mtdblock7
8 0 3895296 sda
8 1 3891200 sda1
挂载USB设备:
[root@armsys /]# mount -t vfat /dev/sda1 /mnt
出现如下错误:
Unable to load NLS charset cp437
FAT: codepage cp437 not found
mount: mounting /dev/sda1 on /mnt failed: Invalid argument
这时,需要make menuconfig时选择cp437的支持:
File systems —>
-*- Native language support —>
— Native language support
[*] Codepage 437 (United States, Canada)
[*] NLS ISO 8859-1 (Latin 1; Western European Languages)
当然也可以设置其他编码方式:
[*] Simplified Chinese charset (CP936, GB2312)
[*] ASCII (United States)
[*] NLS UTF-8
重新编译后,加载内核就可以读取USB设备里的内容了。
参考资料:
linux-2.6.28系统移植s3c6410开发板USB不能识别的处理
USB error-62
Linux 2.6.24.4移植到S3C2410(nano2410)之:USB
linux-2.6.28 s3c2410上添加USB和SD卡设备
宿主机环境:
Linux version 2.6.32-24, Ubuntu10.04
gcc version 4.1.3, Thread model: posix;
GNU Make 3.81
arm-linux-gcc 3.4.5
开发板环境:
CPU: S3C2410X
SDRAM: HY57V561620(32MB)
FLASH: K9F1208(64MB)
Linux Kernel: 2.6.23.8
移植步骤:
将前面生成的内核加载到开发板中的时候,我们可以发现以下的内容:
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
TCP cubic registered
NET: Registered protocol family 1
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
IP-Config: Complete:
device=eth0, addr=10.12.33.38, mask=255.255.255.0, gw=10.12.33.254,
红色字体部分表示S3C2410的RTC支持已经在kernel中,但是没有将rtc device加入SMDK2410 targetboard的device列表中,所以我们需要将RTC加入初始化的设备列表中。
修改文件arch/arm/mach-s3c2410/mach-smdk2410.c,在数组smdk2410_devices[]中添加&s3c_device_rtc:
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8$ cd arch/arm/mach-s3c2410/
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8/arch/arm/mach-s3c2410$ vim mach-smdk2410.c
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_rtc, // sean chi 20Aug2010, added.
};static void __init smdk2410_map_io(void)
{
s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
重新编译内核后,加载内核到开发板,发现以下内容:
S3C24XX RTC, (c) 2004,2006 Simtec Electronics
s3c2410-rtc s3c2410-rtc: rtc disabled, re-enabling
s3c2410-rtc s3c2410-rtc: rtc core: registered s3c as rtc0
…………
NET: Registered protocol family 1
s3c2410-rtc s3c2410-rtc: hctosys: invalid date/time
IP-Config: Complete:
device=eth0, addr=10.12.33.38, mask=255.255.255.0, gw=10.12.33.254,
以上信息表示RTC设备已经初始化成功。红色字体问题表示从硬件时钟(hc)处读到的时间转换到系统时钟(sys)的过程发生错误,硬件时钟传递的时间参数是一个不合法的时间参数(invalid date/time)。从内核函数int rtc_valid_tm(struct rtc_time *tm),可以看出,当year小于1970时,认为是时间 invalid,函数返回-EINVAL。
/*
* Does the rtc_time represent a valid date/time?
*/
int rtc_valid_tm(struct rtc_time *tm)
{
if (tm->tm_year < 70
|| ((unsigned)tm->tm_mon) >= 12
|| tm->tm_mday < 1
|| tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900)
|| ((unsigned)tm->tm_hour) >= 24
|| ((unsigned)tm->tm_min) >= 60
|| ((unsigned)tm->tm_sec) >= 60)
return -EINVAL;return 0;
}
从根文件系统上运行hwclock可以看到,hwclock的初始值是小于1970的,也验证了上面所说出现invalid date/time的原因:
[root@armsys /]# hwclock
Wed Dec 31 23:59:59 1969 0.000000 seconds
所以我们需要设置正确的系统时间,然后再把系统时间传递给RTC:
[root@armsys /]# date 082013342010.0
Fri Aug 20 13:34:00 UTC 2010
[root@armsys /]# hwclock -w
[root@armsys /]# hwclock
Fri Aug 20 13:34:42 2010 0.000000 seconds
为了使系统时间和RTC时间同步,可以在初始化文件中添加命令
hwclock –s
使每次开机时读取RTC时间,并同步给系统时间。
[root@armsys /]# vi /etc/init.d/rcS
#! /bin/sh
echo “Processing etc/init.d/rc.s”#hostname ${HOSTNAME}
echo “Mount all”
/bin/mount -aecho “Start mdev….”
/bin/echo /sbin/mdev >proc/sys/kernel/hotplug
mdev -secho “Set RTC…”
/sbin/hwclock -secho “******************************************”
echo ” rookiesean’s rootfs ”
echo ” 8Aug2010 ”
echo “******************************************”
echo
搞定。
主机环境:
Linux version 2.6.32-24, Ubuntu10.04
gcc version 4.1.3, Thread model: posix;
GNU Make 3.81
arm-linux-gcc 3.4.5
所需源文件:
busybox-1.9.2.tar.bz2
1. 解压busybox-1.9.2.tar.bz2后,修改Makefile中的ARCH和CROSS_COMPILE与本机的路径一致
rookiesean@rookiesean-desktop:~/workspace$ cd busybox-1.9.2/
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2$ vi Makefile
ARCH ?= arm
CROSS_COMPILE ?= /usr/local/arm/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-
2. 编译busybox, 首先运行make menuconfig
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2$ make menuconfig
大部分的menu config都可以自定义,但是这里有几个是必须要选上的
Busybox Settings —>
Build Options —>
[*] Build BusyBox as a static binary (no shared libs)
//若想直接编译成静态库,勾选此选项,若想使用动态链接,则不选。
Installation Options —>
[*] Don’t use /usr
//不用本机的目录,否则生成的/bin/*会覆盖本机的/bin/*文件,会导致宿主机损坏。
Shells —>
Choose your default shell (ash) —>
//这里选择shell为ash,应该是默认选中的
— ash
//把ash这档的选项全部选上
保存退出,执行以下命令编译生成busybox基本文件:
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2$ make
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2$ make install
在make的过程中,有可能遇到这样的问题:
applets/applets.c:20:2: error: #warning Static linking against glibc produces buggy executables
applets/applets.c:21:2: error: #warning (glibc does not cope well with ld –gc-sections).
applets/applets.c:22:2: error: #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
applets/applets.c:23:2: error: #warning Note that glibc is unsuitable for static linking anyway.
applets/applets.c:24:2: error: #warning If you still want to do it, remove -Wl,–gc-sections
applets/applets.c:25:2: error: #warning from top-level Makefile and remove this warning.
make[1]: *** [applets/applets.o] Error 1
这个警告的定义在applets/applets.c中, 它的意思是告诉你最好用uclibc编译,而不是用glibc因为glibc比较大,busybox在寸土寸金的嵌入式系统中运用比较多,所以会有这样的要求。
解决方案是去掉这一段注释:
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2$ vim applets/applets.c
/* vi: set sw=4 ts=4: */
/*
* Stub for linking busybox binary against libbusybox.
*
* Copyright (C) 2007 Denys Vlasenko <vda.linux@googlemail.com>
*
* Licensed under GPLv2, see file License in this tarball for details.
*/#include <assert.h>
#include “busybox.h”/* Apparently uclibc defines __GLIBC__ (compat trick?). Oh well. */
#if ENABLE_STATIC && defined(__GLIBC__) && !defined(__UCLIBC__)
//#warning Static linking against glibc produces buggy executables
//#warning (glibc does not cope well with ld –gc-sections).
//#warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
//#warning Note that glibc is unsuitable for static linking anyway.
//#warning If you still want to do it, remove -Wl,–gc-sections
//#warning from scripts/trylink and remove this warning.
//#error Aborting compilation.
#endif
或者按照Warning message的提示,到scripts/trylink里面移掉-Wl跟–gc-sections.
3. 用shell脚本创建根文件系统的目录结构
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2$ vim makedir.sh
#!/bin/sh
echo “makeing rootdir”
mkdir rootfs
cd rootfsecho “makeing dir: bin dev etc lib proc sbin sys usr”
mkdir bin dev etc lib proc sbin sys usr #8 dirs
mkdir usr/bin usr/lib usr/sbin lib/modules#Don’t use mknod, unless you run this Script as
#mknod -m 600 dev/console c 5 1
#mknod -m 666 dev/null c 1 3echo “making dir: mnt tmp var”
mkdir mnt tmp var
chmod 1777 tmp
mkdir mnt/etc mnt/jiffs2 mnt/yaffs mnt/data mnt/temp
mkdir var/lib var/lock var/log var/run var/tmp
chmod 1777 var/tmpecho “making dir: home root boot”
mkdir home root boot
echo “done”
执行makedir.sh:
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2$ sh makedir.sh
将会在busybox目录下生成文件夹rootfs, 以及rootfs里一批文件夹及文件:
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2$ cd rootfs/
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs$ ls
bin boot dev etc home lib mnt proc root sbin sys tmp usr var
4. 将busybox源码目录下etc里的内容拷贝到rootfs下在的etc
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs$ cp ../examples/bootfloppy/etc/* ./etc/
5. 修改拷贝过来的profile文件
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs$ cd etc/
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/etc$ vim profile
# /etc/profile: system-wide .profile file for the Bourne shells
echo
echo -n “Processing /etc/profile… ”
# no-op#sean chi 29Aug2010, added, set search library path
echo “Set search library path”
export LD_LIBRARY_PATH=/lib:/usr/lib#sean chi 29Aug2010, added, set user path
echo “Set user path”
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH#sean chi 29Aug2010, added, set PS1
echo “Set PS1″
HOSTNAME=`/bin/hostname`
export PS1=”\\e[32m[$USER@$HOSTNAME \\w\\a]\\$\\e[00;37m "echo "Done"
echo
6. 修改inittab与fstab文件
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/etc$ vim inittab
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::restart:/sbin/inittty2::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/etc$ vim fstab
proc /proc proc defaults 0 0
none /tmp ramfs defaults 0 0
mdev /dev ramfs defaults 0 0
sysfs /sys sysfs defaults 0 0
7. 修改初始化脚本文件init.d/rcS
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/etc$ vim init.d/rcS
#! /bin/sh
echo "Processing etc/init.d/rcS"echo "Mount all"
/bin/mount -aecho "Start mdev..."
/bin/echo /sbin/mdev > proc/sys/kernel/hotplugmdev -s
echo "**********************************"
echo " "
echo " rootFS created by Sean chi 29Aug "
echo " "
echo "**********************************"
echo
8. 创建一个空的mdev.conf文件,在挂载根文件系统时会用到的
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/etc$ touch mdev.conf
9. 把busybox默认安装目录中的文件全部复制到这里的rootfs中。会发现多了linuxrc -> bin/busybox文件,这是挂载文件系统需要执行的,基本上和init相同,入口都是init_main,在init/init.c里面。至于init,一般是读/etc/inittab,根据里面的定义运行若干子进程
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs$ cp ../_install/* ./ -r
如果编译busybox时选择动态库方式编译,则需要查看生成的busybox使用哪些动态库,然后把它们拷贝到rootfs/lib目录下。
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs$cd bin
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/bin$ /usr/local/arm/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-readelf -d busybox
得到如下结果:
Dynamic segment at offset 0xd46c8 contains 22 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libcrypt.so.1]
0×00000001 (NEEDED) Shared library: [libm.so.6]
0×00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0xd5d4
0x0000000d (FINI) 0xbdfbc
0×00000004 (HASH) 0×8128
0×00000005 (STRTAB) 0xace8
0×00000006 (SYMTAB) 0x8d38
0x0000000a (STRSZ) 5067 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0×00000015 (DEBUG) 0×0
0×00000003 (PLTGOT) 0xe47b4
0×00000002 (PLTRELSZ) 3080 (bytes)
0×00000014 (PLTREL) REL
0×00000017 (JMPREL) 0xc9cc
0×00000011 (REL) 0xc58c
0×00000012 (RELSZ) 1088 (bytes)
0×00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0xc4ac
0x6fffffff (VERNEEDNUM) 3
0x6ffffff0 (VERSYM) 0xc0b4
0×00000000 (NULL) 0×0
所以我们从交叉编译工具链的库文件目录下面拷取以下的文件(自编译交叉工具链的具体操作见《嵌入式Linux移植 – 使用crosstool创建自己的交叉编译器》一文):
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/bin$ cd ../lib/
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/lib$ cp /usr/local/arm/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/ld* ./
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/lib$ cp /usr/local/arm/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/libc-2.3.6.so ./
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/lib$ cp /usr/local/arm/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/libc.so.6 ./
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/lib$ cp /usr/local/arm/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/libm.so.6 ./
rookiesean@rookiesean-desktop:~/workspace/busybox-1.9.2/rootfs/lib$ cp /usr/local/arm/arm-9tdmi-linux-gnu/arm-9tdmi-linux-gnu/lib/libcrypt.so.1 ./
对busybox的配置工作完成。在对宿主机和开发板的bootloader配置,使其能以NFS的形式加载内核后,启动开发板,得到如下显示:
Looking up port of RPC 100005/1 on 10.12.33.30
VFS: Mounted root (nfs filesystem).
Freeing init memory: 132K
init started: BusyBox v1.9.2 (2010-08-29 15:45:16 CST)
starting pid 772, tty ”: ‘/etc/init.d/rcS’
Processing etc/init.d/rcS
Mount all
Start mdev…
**********************************rootFS created by Sean chi 29Aug
**********************************
starting pid 776, tty ”: ‘/bin/sh’
Processing /etc/profile… Set search library path
Set user path
Set PS1
Done[root@armsys /]#
根文件系统顺利加载。
参考资料:
用busybox创建基于Linux2.6.24内核的nfs根文件系统
Linux2.6.24.4 根文件系统移植到S3C2410
宿主机环境:
Linux version 2.6.32-24, Ubuntu10.04
gcc version 4.1.3, Thread model: posix;
GNU Make 3.81
arm-linux-gcc 3.4.5
开发板环境:
CPU: S3C2410X
SDRAM: HY57V561620(32MB)
FLASH: K9F1208(64MB)
NET: CS8900
Linux Kernel: 2.6.23.8
所需源文件:
cs8900.tar.gz
移植步骤:
下载上面所给出的cs8900.tar.bz2文件,解压缩到drivers/net/arm/目录下面。
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8$ cd drivers/net/arm/
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8/drivers/net/arm$ tar xvf /home/rookiesean/Downloads/cs8900.tar.bz2
在/drivers/net/arm/Kconfig中增加menu config中CS8900编译选项。
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8/drivers/net/arm$ vim Kconfig
config ARM_CS8900
tristate “CS8900 support (sean chi 18Aug2010, added)”
depends on NET_ETHERNET && ARM && ARCH_SMDK2410
help
Support for CS8900A chipset based Ethernet cards. If you have a
network card of this type, say Y and read the EthernetHOWTO, available
from as well as. To compile this driver as a module, choose M here and
read. The module will be called cs8900.o
在/drivers/net/arm/Makefile中添加如下内容:
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8/drivers/net/arm$ vim Makefile
obj-$(CONFIG_ARM_CS8900) += cs8900.o#sean chi 18Aug2010, added.
然后我们在include/asm-arm/arch-s3c2410/目录下面创建一个smdk2410.h的头文件。
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8$ cd include/asm-arm/arch-s3c2410/
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8/include/asm-arm/arch-s3c2410$ vim smdk2410.h
添加如下代码:
#define pSMDK2410_ETH_IO __phys_to_pfn(0×19000000)
#define vSMDK2410_ETH_IO 0xE0000000
#define SMDK2410_EHT_IRQ IRQ_EIN
修改arch/arm/mach-s3c2410/mach-smdk2410.c文件,包含新创建的smdk2410.h头文件,并在map_desc smdk2410_iodesc[]
中添加cs8900的对于的io空间映射:
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8$ cd arch/arm/mach-s3c2410/
rookiesean@rookiesean-desktop:~/workspace/linux-2.6.23.8/arch/arm/mach-s3c2410$ vi mach-smdk2410.c
#include <asm/plat-s3c24xx/devs.h>
#include <asm/plat-s3c24xx/cpu.h>#include <asm/plat-s3c24xx/common-smdk.h>
#include <asm/arch/smdk2410.h> // sean chi 18Aug2010, added.
static struct map_desc smdk2410_iodesc[] __initdata = {
{ vSMDK2410_ETH_IO , pSMDK2410_ETH_IO, SZ_1M, MT_DEVICE }, // sean chi 18Aug2010, added.
/* nothing here yet */
};#define UCON S3C2410_UCON_DEFAULT
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
执行menu config。 Device drivers->network device support->Ethernet中选择(*)CS8900 support。
编译内核make zImage。
通过uboot把zImage加载到SDRAM的0×30008000处,接着运行新的内核。
SMDK2410 # tftp 30008000 zImage.sean.cs8900
SMDK2410 # g 30008000
可以看到如下结果,表示添加对cs8900的支持成功。
dm9000 Ethernet Driver
Cirrus Logic CS8900A driver for Linux (Modified for SMDK2410)
eth0: CS8900A rev E at 0xe0000300 irq=53, addr: 00: 0:3E:26:0A: 0
Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx














Comments