2014年10月29日星期三

程序员开发工具

版本控制工具:
github,sourcetree

开发IDE:

VS2008(C、C++)、PyCharm(Python开发)

代码查看和编辑:

Subtime Text(推荐使用),EditPlus ,Vim

笔记:

有道云笔记,偶尔用下evernote,MarkdownPad Pro(windows下使用,体验很好)

虚拟机软件:

VMware,VirtualBox

串口调试和远程管理:

SecureCRT 5.0(串口连接),winscp(服务器/客户端之间传输文件)

2014年9月23日星期二

大疆笔试题目(嵌入式软件)


    嵌入式软件从整体上说出的难度不是很大,但是感觉出的题还是可以区分开纯软件和嵌入式工程师的,不废话,具体题目想不起来了,只能凭记忆回忆一些。
编程基础
    第一题目是在64位机上,使用32位编译器来编译,求占用内存的大小;如果使用64位编译器又如何?
struct {
int a;
char c;
unsigned short b;
char *p;
void(*p)(int);
};好像粗心做错了,尴尬。。。。
    第二道题目是container_of
    第三道题目是反转某一位。
    还有两道题目想不起来了。
嵌入式基础知识
1.       描述中断处理过程
2.       列举Linux内核态和用户态间通信的方法,你觉得最有效率的是哪一种??这个题不确定。
总线题目
1.       说出UARTI2CUSB总线的异同(全/半双工、串/并行、速率等)
2.       想不起来了
设计题目
已知一个系统中有两个UART接口,UART0UART1UART0是负责接收和回复,UART1是转发。已知有两个字段,一个是命令字段(2字节),一个是数据字段(0~128字节)。
(1)       设计通信数据包格式
(2)       在实时操作系统中,如何设计多个任务和缓存数据,请画出数据流图
(3)       如何设置优先级,说出优缺点

(4)       假如命令字段有高低优先级,重新设计。

2014年9月21日星期日

Linux用户空间和内核空间通信方式比较

资料整理:
1.       论文,主要比较通信方式
http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=5696027
2.       stackoverflow部分讨论
3.       论文,主要讨论netlink
4.       介绍netlink的一篇博文,写的不错!
摘抄自4的博文:
netlink 相对于系统调用,ioctl 以及 /proc 文件系统而言具有以下优点:
1,为了使用 netlink,用户仅需要在 include/linux/netlink.h 中增加一个新类型的 netlink 协议定义即可, #define NETLINK_MYTEST 17 然后,内核和用户态应用就可以立即通过 socket API 使用该 netlink 协议类型进行数据交换。但系统调用需要增加新的系统调用,ioctl 则需要增加设备或文件,那需要不少代码,proc 文件系统则需要在/proc下添加新的文件或目录,那将使本来就混乱的 /proc 更加混乱。
2. netlink是一种异步通信机制,在内核与用户态应用之间传递的消息保存在socket缓存队列中,发送消息只是把消息保存在接收者的socket的接收队列,而不需要等待接收者收到消息,但系统调用与 ioctl 则是同步通信机制,如果传递的数据太长,将影响调度粒度。
3.使用 netlink 的内核部分可以采用模块的方式实现,使用 netlink 的应用部分和内核部分没有编译时依赖,但系统调用就有依赖,而且新的系统调用的实现必须静态地连接到内核中,它无法在模块中实现,使用新系统调用的应用在编译时需要依赖内核。
4netlink支持多播,内核模块或应用可以把消息多播给一个netlink组,属于该neilink 组的任何内核模块或应用都能接收到该消息,内核事件向用户态的通知机制就使用了这一特性,任何对内核事件感兴趣的应用都能收到该子系统发送的内核事件,在 后面的文章中将介绍这一机制的使用。
5.内核可以使用 netlink 首先发起会话,但系统调用和 ioctl 只能由用户应用发起调用。
6netlink 使用标准的 socket API,因此很容易使用,但系统调用和 ioctl则需要专门的培训才能使用。

                                                                                                      jefby


2014年9月19日星期五

阿里面试归来

    一面被问得比较尴尬,好多问题都没有答上来,例如假如有一个8核心的CPU,内存64GB,是使用hash表存储的数据,将其全部倒入内存后,如何让其发挥8核心的威力,你有什么方法?我回答了互斥锁,读写锁,然后试着使用8位的数来判断,还试着说了下ARM big.Little中使用的两种调度方法:GTSHMP但是明显我不了解其原理,面试官让我说具体逻辑的时候回答不上来,太弱了。然后问熟悉操作系统不,我说还行,就开始问了,内核中线程和进程有什么区别?我说进程在内核中是用struct task_struct结构体表示的,线程是轻量级的进程,表示方法应该都一样,然后面试官说这是操作系统书本上的知识,具体描述Linux内核下是怎么表示的?懵了。。线程不太懂啊,进程还知道一点点,亏大发了,然后小声说pthread库??这是应用层的,不算。哎,还是自己技术积累不够。接着问算法和数据结构,问了快排的原理和思路,然后问你能写快排么?我说我忘了,汗。。真忘了啊!!哎。。接着是问我知道C语言里面的mallocfree函数么,问free的时候为啥不用指定需要释放内存的大小,我回答说是因为有个类似表的结构记录申请的内存的,然后接着问我知道这表在操作系统中如何存储的,第一次回答错了,说是环形链表;马上纠正是哈希表。接着面试官继续提问,让我在纸上写代码,写一个类似于动态增长的栈一样的数据结构或者类,主要写它的增加函数,我开始写代码,大体思路是使用链表,然后每个链表节点里面存储一块固定大小的数据,每次增加的时候判断是否需要动态申请新的链表节点,然后按需插入即可。
    写完之后面试官开始问了我一点项目的东西,就叫我在外面等一会。等了一会之后,有人出来通知让到另一个地方去2面,等待的时候太揪心了,自己一面答得不太好,很幸运能获得2面的机会,2面等了很久,大约2小时40分钟的样子,2面的面试官先让我做自我介绍,我就说了下我的性格和研究方向,然后开始问毕设做的什么,我就开始讲我毕设相关的东西(基于云的路由器系统设计),让我画设计简图,然后描述我具体的工作是什么,叙述完后接着让我分析就是当前的作品存在的问题,还有和市场上的产品做对比,我说了个ninja block(幸亏前几天看啊。。^_^),╮(╯▽╰)╭,然后接着问研究生做过的项目和平时玩的一些硬件,2410,6410,5420啊啥的,主要问了我5420有关Android LCD驱动移植的思路和具体做法,我说由于时间不够,我只是自己研究了下,没有精力去开发,就让我叙述下思路。完了后开始问我的家庭地址和对工作地点的要求等等。然后问我有问题没,我就问了下系统工程师和运维一样么?面试官说阿里里面岗位都是互通的,可以根据方向和专业来调整。就让我出去等一会。
    等了一会就是HR面了,HR是个美女,看起来很亲切,比较轻松,聊了下工作意向和个人性格什么的,比较快,30分钟左右就完了,然后让我在外面稍微等一下,等了一会有工作人员通知我可以走了,说应该是过了,可以网上查看。终于松了一口气,早上10点到下午5点左右面完,感觉收获确实很多很多,见了一些牛人,面试官都循循善诱,让你发现表面事物下的原理!!很不错!!静待Offer。。希望早点发啊!!没拿到offer还是心虚的很!!

后记:已经拿到阿里系统工程师offer!!#_#很开心,昨天阿里上市,已经超越Facebook成全球第二大互联网公司!!太牛了!!

今天你对我爱理不理,明天我让你高攀不起!! --马云

2014/09/12
jefby


数码视讯2015年笔试和面试

笔试题(嵌入式/C工程师)

    给数码视讯Email投递了简历后,竟然没有收到笔试通知,太尴尬了!!在同学的鼓舞下,第一次去霸面,拿着转发的短信要试卷,发试卷的哥们说不要忽悠我,直接就走了,有点挂不住,后面又过来,然后说自己是双西电,终于给了笔试试卷,谢天谢地!!开始答题!!

    嵌入式题目感觉还行,选择填空都是平时见过的原题,后面有一个有关指针用法的题目,有个小题目做错了,大题主要有三个,一个是让写一个reset函数,保持1ms的低电平,这个easy,写寄存器,然后sleep或者死循环1ms即可(值根据处理器主频来调整),第二个大题目是写memmove函数实现,这个以前写过,判断特殊情况,然后从后向前拷贝就可以避免重叠问题了。最后一个大题目是写排序算法,给定一个二维数组,让按列优先级来排序,效率越高越好,我用的是快排qsort,传递比较函数。代码还没有测试,等测试编译成功后放出来。试卷部分截图如下:
    下午面阿里的时候错过了两次电话,吃饭的时候又错过了,还好晚上终于接到了数码视讯的电话,一面问了项目还有笔试题目,有一个memmove函数现场写的存在一些问题,没有考虑src>dst的情况,另外整形提升也有问题。指针使用还是有漏洞,另外问AD5342怎么保证数据有效采样,我当时没有理解他问的意图,瞎说了一通,最后面完后再次问这个问题,面试官详细讲解了下,很和蔼;然后推荐我去1902继续参加2面,最后去的是2002,二面就是终面,HR很漂亮,先让自我介绍,然后问工作地点,性格啥的,比较随意!!最后说让我回去等通知,如果通过两天内会打电话通知offer
jefby
2014/09/13

腾讯面试归来

一面
    笔试完后,焦急的等待腾讯面试通知,终于在915号下午5点半左右收到短信通知16号一面,我面试的时间安排的比较晚,是下午6点,由于面试人比较多,等了大约20多分钟,620多的时候进去面试,面试官很和蔼,首先欢迎来腾讯面试,然后让自我介绍,自我介绍中提到研究方向是arm linux内核和驱动开发,可能面试官是做这方面的,开始问字符设备和块设备驱动的区别,然后问mmap实现用的是啥,我可能没理解题目意思,说的是块设备,然后开始问项目可翻墙路由系统,问goagent的实现原理,因为我不太会python,所以没有看源码,只是移植到openwrt系统上,所以说的比较模糊,面试官也没有再问。然后就是开始让我做题目,第一道是atoi函数实现,很快写完了,接着拿了一道全排列问题,之前见过,但是对于原理理解的不够,所以只是知道大致的方法,写不出来。面试官说由于时间差不多了,说回去等结果。

二面

    16号晚上8:30左右收到二面通知,感觉效率好高,二面在902,这次感觉有点尴尬,进来的时候忘了关门,出去的时候又把门给关上了,估计是留下不好印象了吧!!依然是先自我介绍,然后问我面了几家公司,我就很诚实的说了,接着简单的问了一个项目(1分钟),就开始做题目,第一道题目是

假设排列着100个乒乓球,由两个人轮流拿球装入口袋,能拿到第100个乒乓球的人为胜利者.条件是:每次拿球者至少要拿1个,但最多不能超过5个,问:如果你是最先拿球的人,你该拿几个?以后怎么拿就能保证你能得到第100个乒乓球?
答案: 根据以上分析,把100分成6个一组,余数是几,我就先拿几个,
100÷6=17(组)…4(个)
答:我先拿4个,他拿15中的n个,我拿6-n,依此类推,保证我能得到第100个乒乓球.
当时答的很不好,面试官开始逆向推理,依照思路答得感觉还可以吧,接着做题,大致题意是
10个箱子,每个箱子10个苹果,其中一个箱子的苹果9/个,其他的都是1/个.要求利用一个秤,只称一次,找出那个装9/个箱子.
解法:
第一个箱子取1个,第二个箱子取2个,第三个箱子取3个。。第10个箱子取10个,秤和55斤差几两,就是第几个箱子的苹果是9两一个。
后面就是开始做题目,有C语言题目,有编写程序题目。做完觉得应该还可以,但是到目前还是没有收到短信通知也不知道是什么情况。。。纠结ing!!估计要跪的节奏!

9/18号晚上查看微信,已挂!!尴尬,还是没想明白为啥会挂。。?

2014年9月6日星期六

百度西电宣讲会

    算起来这次已经是第3次参加百度的宣讲会了,本科的时候听过一次,研二的时候听过一次,今年是第三次,想来也是最后一次了,会场布置的不错!6点半不到,会场基本已经坐满了,过道和后排站了一大片的人!!大家对百度的期望还是特别高的!#_#
    7点的时候主持人由主持人开始介绍嘉宾,然后由百度的技术人员(也是我们的学长),今年百度的宣讲和往年不太一样,宣讲的人员基本就是会场所在学校的毕业生。今年来了2个学长:一个是电院,一个是本科计算机院的(这个很开心),然后学长上台,先讲有关百度最近发布的一些产品,例如百度Eye,百度筷搜等,感觉百度Eye不错,接着就是分享怎么进百度的,为什么会选择百度等等,然后还分享了一些找工作面试需要准备的东西等。最后就是问答环节了!!整个过程气氛还是很不错的,和去年相比更显得亲近了一些!!至少从本校学生的角度而言,拉近了和学生的距离。
     对了,都差点忘了说学长分享的有关百度工作环境和待遇的事情了,学长通过两,三页PPT丰富的展示了百度技术员工的一天的工作生活情况,饭菜很给力,穿着随意,而且上下级之间关系差别不那么明显,另外同事之间的称呼我觉得也特别人性化,“同学”对于刚毕业的屌丝们来说,太亲切了有木有!!!想去百度的愿望越来越强烈了!!
   
 

2014年9月1日星期一

华为面试归来

    周日收到面试通知,想准备也不知道怎么准备,胡乱看了下简历上写的项目相关的东西,今天就去了面试地点,2点30左右开始面试,一面面试官比较和气,先让我自我介绍,然后根据简历上写的项目开始询问,可能刚好是做芯片级软件开发方面的吧,问的比较细致,当芯片运行出现问题时候该怎么调试,还有开发过程中遇到的问题,怎么解决的??幸好项目大部分都是我自己亲手做的,比较清楚,答得自我感觉还不错;然后问我带成绩单了没,我说带了,大体看了下,然后问你觉得你学的比较好的课程是哪一门?我想好想计算机网络考的分数比较高一些,就顺口答了一下计算机网络,面试官接着问请你用简单的语言描述下计算机网络,然后我当时就有点懵了,这。。。后悔极了,这该怎么答啊?硬着头皮说了计算机网络是由多个节点间连接在一起进行通信,结结巴巴,然后说TCP/IP和OSI模型两种协议栈,IP地址划分。。等等,感觉自己还是有点紧张,后来,他看了下我的比赛获奖证书,然后问了下我比赛做的是什么东西?具体自己又做的是哪个模块。?
    这个项目做的不是很好,有FPGA也有ARM,自己当时水平很菜,FPGA的东西虽然学的时间不算太短,但是FPGA这东西是入门简单,精通难,想把ARM和FPGA配合起来为自己服务,毕竟还是需要长时间的积累和经验,所以我就捡我自己特别熟悉的说,我说我做的是算法的移植和实现,然后面试官继续问,算法是你们自己发明的还是现成的算法,发明??太看得起我们了,就是从论文里面挑选了一些特别好的算法,然后修改移植到ARM平台下,完成了基本的车牌识别!!还好,没太刁难!!
    然后再问了一点数据结构方面的知识,就说让我在外面等综合面试。
 
    综合面试耗时也比较长,先让做简单的自我介绍,然后开始根据我说的想做SoC和底层软件开发问了很多方面的东西,劝我能不能就是接受调剂,把可接受的职位范围放广一些!!我刚开始先是耗着一直要去海思部门,说了好几次,哎,最后我想还是先答应下来吧,等到正式签合同的时候再说,如果分不到海思部门,我还是放弃吧!毕竟华为里面目前我还是特别想做海思相关的软件开发,毕竟海思才是我特别认同华为的部门!!将基带和Application Processor结合起来,全球也就高通和海思两家吧!!!

   如果可以做相关的开发,睡觉都会笑的吧!!!#_#

2014年8月29日星期五

阿里巴巴2015年系统工程师笔试附加题目

作者:jefby
Email: jef199006@gmail.com


       终于做完阿里的系统工程师笔试题目,由于自己的失误,本来以为阿里云事业部的个人云(就是开发云路由,智能家居那部分的部门)应该是属于系统工程师,结果前几天才发现原来是自己投错岗位了,可是想改也已经改不了了!!哎,就先做做吧!!

说明:个人水平有限,做的题目肯定有bug,第一道题是不确定,第2,3道题目都验证过,可能效率不是特别高,欢迎高手拍砖指正!!
题目一:
A公司打算搭建一个Andriod App下载的Web站点,计划将目前常见的手机APP都放到这个网站上提供下载。因为业务开展初期下载量很小,技术部门就用了1台服务器,给服务器配置了一个公网IP对外进行服务。随着销售部门的推广到位,用户量和下载量呈指数级上载,要求技术部门马上进行改造。如果你是技术部门经理,你会怎么改造这个站点,以满足高负载的需求。
提示:短时间修改网站的代码不现实,其他方面的各种改造建议都可以,建议越多越好。
个人解答:
1.基于DNS的负载均衡方法,多个ip对应一个域名,均衡下载

2.使用硬件第四层交换技术
主要思想就是分流,将数据分配都不同的应用服务器上。根据包头信息和应用区间识别业务流,将整个区间段的业务流分配到合适的应用服务器。
就像虚拟IP一样,指向物理服务器。它传输的业务服从的协议多种多样,有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上,
需要复杂的载量平衡算法。在IP世界,业务类型由终端TCP或UDP端口地址来决定,在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。
在硬件四层交换产品领域,有一些知名的产品可以选择,比如Alteon、F5等,这些产品很昂贵,但是物有所值,能够提供非常优秀的性能和很灵活的管理能力。

3.
在软件或者硬件四层交换的基础上搭建squid集群,这种思路在很多大型网站包括搜索引擎上被采用,这样的架构低成本、高性能还有很强的
扩张性,随时往架构里面增减节点都非常容易。

4.使用高速缓存技术,将下载最多的App放到高速缓存中。

5.反向代理负载均衡和高速缓存结合起来,让代理服务器将请求均匀转发给多台内部Web服务器之一上

6.基于NAT的负载均衡技术

7.半中心负载均衡方式
在半中心的负载均衡方式下,即当客户请求发送给负载均衡器的时候,中心负载均衡器将请求打包并发送给某个服务器,
而服务器的回应请求不再返回给中心负载均衡器,而是直接返回给客户,因此中心负载均衡器只负责接受并转发请求,其网络负担就较小了。

题目二:
写一个函数,输入一个二叉树,树中每个节点存放了一个整数值,函数返回这棵二叉树中相差最大的两个节点间的差值绝对值。请注意程序效率。
个人解答:
static int cnt = 0;
static int a[1001];

typedef struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x):val(x),left(NULL),right(NULL){}
}TreeNode;

static void
InOrderTraverse_rec(TreeNode * root)
{
if(!root)
return;
else{
InOrderTraverse_rec(root->left);
a[cnt++]=root->val;
InOrderTraverse_rec(root->right);
}
}

int
compare (const void *elem1, const void *elem2 )
{
    return *(int*)elem1-*(int*)elem2;
}

unsigned int
max_tree(TreeNode* root,int(*cmp)(const void *elem1, const void *elem2 ))
{
    InOrderTraverse_rec(root);
    qsort(a,cnt,sizeof(int),cmp);
    return a[cnt-1]-a[0];
}
题目三:
给定一个query和一个text,均由小写字母组成。要求在text中找出以同样的顺序连续出现在query中的最长连续字母序列的长度。例如, query为“acbac”,text为“acaccbabb”,那么text中的“cba”为最长的连续出现在query中的字母序列,因此,返回结果应该为其长度3。请注意程序效率。
个人解答:
/* 最长公共子串 DP */
int dp[40][40];

int
LCS_dp(char * text,char * query)
{
int matextlen  = 0;
int textlen =0,querylen=0;

textlen= strlen(text);
querylen = strlen(query);

    for(int i = 0; i < textlen; ++i)
    {
        for(int j = 0; j < querylen; ++j)
        {
            if(text[i] == query[j])
            {
                if(i && j)
                    dp[i][j] = dp[i-1][j-1] + 1;
                if(i == 0 || j == 0)
                    dp[i][j] = 1;
                if(dp[i][j] > matextlen)
                    matextlen = dp[i][j];
            }
        }
    }
 
return matextlen;
}

2014年8月27日星期三

chrome37 64bit install error

        今天看到了google官网上发布的chrome更新信息,据说是支持64位的稳定版,速度和效率都得到了很大的提升,所以好奇心驱使下试着卸载了32位,重装64位,但是安装后总是加载不了页面,连基本的设置插件页面都打不开,尴尬极了!最后实在没办法,就只好试着使用兼容模式运行,竟然可以,但是打不开优酷网站,太麻烦了!有解决方法?在plugins中已经设置启用adobe flash和google flash。

2014年8月26日星期二

vim插件的安装和管理

今天晚上在一篇博客中看到有关安装vim插件的用法,心血来潮下自己在CentOS 6.5下试了下,走了一点点的弯路,就把步骤记录下来吧!!以便以后再次能迅速搭建环境!!
vim下vundle是一款管理插件的神器,能够管理众多的vim插件,安装方法如下:
#git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle
然后在/etc/vimrc中添加如下代码
set nocompatible "与vi不一致
filetype off
set rtp+=~/.vim/bundle/vundle/ "载入特定目录插件
"set rtp+=$HOME/.vim/bundle/vundle/ "Windows下
call vundle#rc()
"plugin 
"vimscripts账号下的项目直接填写名称即可
Bundle 'snipMate'
"其它需填写用户/资源名称
Bundle 'gmarik/vundle'
"非github上资源
Bundle 'git://git.wincent.com/command-t.git'
"indent
Bundle 'php.vim-html-enhanced'
"color
Bundle 'Lucius'
filetype plugin indent on
启用vundle,然后安装可以使用vundle管理的插件,例如powerline。
安装方法:
#cd ~/.vim/bundle/
#git clone https://github.com/Lokaltog/vim-powerline
在vimrc中添加如下代码:
set t_Co=256
Bundle 'vim-powerline'
set laststatus=2
let g:Powerline_colorscheme='solarized256'
重启vim,可看到如下图所示:

关于程序员开发环境配置的一点小看法

   前几天在Windows下写代码,使用的是UltraEdit 10.0,界面有点丑,有个师弟见了之后推荐我使用sublime软件试试,于是抱着好奇的心态下载并安装了sublime软件,我只能说好的编辑器能极大的提高程序员开发的积极性!!
   使用了几天之后,我是彻底喜欢上了这款编辑器,sublime最早是为Mac OSX开发的后来做了全平台适配,现在Windows、Linux也可以使用了,当然应该体验最好的是Mac OSX吧,Windows下需要安装cygwin之类的安装包,而Linux下虽然也可以安装sublime,并且自带有gcc编译器等,但是中文输入法是一个大难题,sublime默认不支持ibus输入法,所以就尴尬了,没有中文输入法是个让人很纠结的事情;而windows下虽然没有输入法的限制,但是默认的中文编码GBK是个bug,在默认使用utf-8的sublime下还是需要安装好package-control和convertToUTF-8包才可以较好的看到GB2312编码的中文注释等,当然也可以直接将文件另存为utf-8格式的,然后再使用sublime打开。
   而这更让我对Mac世界充满了向往,Mac下使用的默认编码是utf-8,而且是类Unix设计的操作系统,我想对于Linux开发者也是一个非常好的选择,而且界面设计的非常漂亮!!软件支持包众多!!

2014年8月25日星期一

arm linux内核源码中关于何时开启MMU的思考

   今天再次阅读arm linux内核源码,看MMU启动部分发现了一个问题,就是在常规的__enable_mmu和__turn_mmu_on部分我没有找到真正使能MMU标志的代码,但是它到底是什么时候将MMU的最低位置1的呢??怀着这个疑问我在google上搜索了好多,但是对于这个问题的解答都是模凌两可,说的特别含糊,千篇一律,不能让人信服。

__enable_mmu代码如下:

__enable_mmu:
#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
orr r0, r0, #CR_A
#else
bic r0, r0, #CR_A
#endif
#ifdef CONFIG_CPU_DCACHE_DISABLE
bic r0, r0, #CR_C
#endif
#ifdef CONFIG_CPU_BPREDICT_DISABLE
bic r0, r0, #CR_Z
#endif
#ifdef CONFIG_CPU_ICACHE_DISABLE
bic r0, r0, #CR_I
#endif
#ifndef CONFIG_ARM_LPAE
mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
domain_val(DOMAIN_IO, DOMAIN_CLIENT))
mcr p15, 0, r5, c3, c0, 0 @ load domain access register
mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
#endif
b __turn_mmu_on
ENDPROC(__enable_mmu)

__turn_mmu_on源码如下:
ENTRY(__turn_mmu_on)
mov r0, r0
instr_sync
mcr p15, 0, r0, c1, c0, 0 @ write control reg(启用MMU)
mrc p15, 0, r3, c0, c0, 0 @ read id reg
instr_sync
mov r3, r3
mov r3, r13 @r3中转入最后要跳入的虚拟地址
mov pc, r3 @跳转到__mmap_switched
__turn_mmu_on_end:

在__turn_mmu_on中将r0的值写入协处理CP15的C1寄存器中,但是r0的bit0什么时候被置位了呢??__enable_mmu没有置位,那就肯定是在__enable_mmu之前,搜索代码找到了答案:

::arch/arm/mm/proc-v6.S

其实在__v6_setup中设置的,有一段代码如下:
adr r5,v6_crval @将v6_crval的实际运行地址加载到r5处
ldmia r5,{r5,r6}@将r5地址处的两个字内容保存到r5和r6处,根据v6_crval定义可知,值为clear和mmuset,mmmuset的最后一个比特值为1,也就是CR_M=1
orr r0,r0,r6 @在此处将设置r0的bit0为1。随后在__turn_mmu_on中将MMU的值写入CP15的C1寄存器,真正使能MMU。

v6_crval的定义如下:
.type v6_crval, #object
v6_crval: crval clear=0x01e0fb7f, mmuset=0x00c0387d, ucset=0x00c0187c
其中crval是定义的宏,根据配置CONFIG_MMU不同存放不同的值.
.macro crval, clear, mmuset, ucset
#ifdef CONFIG_MMU
 .word \clear
 .word \mmuset
#else
 .word \clear
 .word \ucset
#endif                                                                                                                  .endm  
至此就非常清楚了,在__v6_setup中设置了r0的bit0,然后调用__enable_mmu和__turn_mmu_on真正开启MMU。

关于积累和专注的想法

   今天偶然间在QQ群消息中知道我12年认识的一个同学获得了研究生电子设计大赛一等奖,感触良多。
   我和他交往不深,只是12年做FPGA比赛的时候认识的,我记得当时给我感触特别大的就是他会把他所做过的东西做一些总结,写成博文;而且更让我钦佩的是会定期做优化,会一点一点的做优化改进,而当时的我什么也没做过,没写过博客或者做过任何项目方面的总结,而他当时已经是chinaAET上的知名博主了,同样是做技术的,同样是一级学生,怎么差距这么大??虽然我不是做硬件的,但是感觉看他的技术真的相当过硬,可以说是见过的同龄人里面最厉害的!
   下午抽空看了下他的比赛作品,更让我吃惊的是竟然是12年他们曾经做过的,不过和当时相比,作品的质量和技术得到了质的飞越,设计的硬件很精致,而且听说是由他自己设计的!我想象不出他是怎么一步一步、脚踏实地把他们当时比较粗糙的东西做优化,做精致;必定是痛苦蜕变的过程!而想想我,12~13年期间做的作品,比赛完后就再也没有看过,13~14年忙于老师的项目,项目做完还是没有做任何的总结和优化,做完也就完了!这才是我和他之间产生如此巨大差异的原因吧!!一个看到不足,然后总结经验,一点点的改进;另一个也看到不足,但是没有深刻总结,只是放弃!!去挖新的井!想起来我就是那成语里面说的那种反面教材吧!!! ||_||
   我还很佩服一个人,他是我大学室友,朝夕相处增加了我们之间的了解,也让我更加佩服他,他和我一样是做软件开发的,不过他更偏重的是应用软件开发,经常会写一些很实用的小软件,然后慢慢改进他自己的代码,不断的总结优化,最后惊艳了似我这类屌丝!!
   向大神们学习!勤于总结,一点点改进优化,最终我要惊艳世人!!

2014年5月23日星期五

wndr3800 实现USB设备自动挂载

   WNDR3800路由器有USB2.0接口,但是插上USB存储设备后,并没有像在Linux下那样,在/dev目录下有诸如sda,sdb等设备名,所以也不能提供设备访问。那么需要重新编译内核以支持设备的自动探测和对NTFS,EXT4分区的支持。具体步骤如下:
   进入trunk目录下,运行make menuconfig配置内核:
   1.配置BASE System => block mount选项,选中
   2.配置Kernel Modules => Block Devices => kmod-scsi-generic
   3.配置对文件系统的支持,NTFS(windows下常用)和EXT4(Linux下用)
     Kernel Modules => File System => kmod-fs-ext4
     NTFS支持,需要安装软件包ntfs-3g  
     配置 Utilities=> Filesystem =>ntfs-3g
   4.保存退出,重新编译内核,并烧写系统到路由器中,使用ssh连接到路由器上,再次插入U盘,可以看到内核提示信息,然后使用mount命令挂载:
   5.测试对NTFS分区的支持
     同样插入一个格式为NTFS分区的U盘或者移动硬盘


 

2014年5月21日星期三

路由器WNDR3800 OpenWrt刷写记录

   对OpenWrt慕名已久,最近有一个想法:实现一个简单的透明翻墙路由器,将校园网共享出来,然后在路由器上运行翻墙代理,实现手机等无线设备的零配置翻墙。网上搜了很多资料,最终决定购买网件的WNDR3800,这台路由器当时配置还可以,但现在看来有点弱,不过相信大品牌的做工和质量。主要的参数如下:
    CPU : AR7161,680MHZ
    RAM: 128M DDR
    FLASH: 16M
    支持双频段:2.4G+5GHZ
   首先是内存大,运行大程序应该无压力,另外是出厂FLASH就是16M,比国内某些路由厂商做的地道多了,可以放置更多的应用程序,同时openwrt系统也支持,适合新手使用。当然,如果老鸟的话可能真的是有点看不上。目前360,小米等鼓吹的AC频段,但似乎很少有设备能支持吧?大部分都是802.11n.
   在淘宝上选了一家价格和评分都不错的店家买了,入手价是269,再加上我用的顺丰快递(+10),总共下来是279,感觉还可以!等熟悉了openwrt后再买一些比较高端的货玩玩哈!^_^。刚开始还想要店家一些技术问题,发现店家似乎也不是很了解,就只好自己先上网搜搜了,幸好对Linux内核和驱动还算有点了解,下载源码,可以使用git或者svn版本控制管理工具,本文使用trunk版本,git的命令如下:
$git clone git://git.openwrt.org/openwrt.git
barrier breaker版本命令如下:
$git clone git://git.openwrt.org/14.07/openwrt.git
SVN的命令如下:
$svn co svn://svn.openwrt.org/openwrt/trunk/
barrier breaker版本命令如下:
$git clone svn://svn.openwrt.org/openwrt/branches/barrier_breaker

============================2014/12/3update========================

然后make menuconfig,选择了CPU和路由器WNDR3800,如果需要界面的话进入到LuCI配置下,选择bootstrap风格(个人比较喜欢,很清新),然后选上develop configure模式(不用每次都从零编译),最后保存并退出。配置界面如下图所示:

接着编译,运行命令:
        make -j8 V=s
-j8表示启动多少个job(主要参考电脑配置,我电脑是4核的,就设置为8,一般是两倍),顺利的话应该会生成一个bin文件夹,在子目录ar71xx/中会看到openwrt-xxxx-wndr3800.squash.img文件,使用网线连接路由器和电脑,进入管理界面中,刷机,完成后重启,再次打开就是OpenWrt的系统啦!!如下图所示: