posts - 33, comments - 0, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          2011年8月29日

                在第一篇時就說過框架要在URL上作文章,是的,本文就框架怎樣充分利用url上作盡可能詳細的說明。

                做web開發(fā)的不可能對url陌生,早在web1.0時代,url作為統(tǒng)一資源定位符,在對web中資源的如何獲得上起到巨大作用。不論用戶請求的時靜態(tài)頁面或者是各種圖片、腳本文件,通過url總能從web網(wǎng)站獲取要訪問的資源。Web2.0更是常常使用url作為get請求時參數(shù)的傳遞,如http://xxx.xxx.xxx/xxx.jsp?user=admin。以及近幾年很火restful web service 摒棄soap而使用url傳遞請求參數(shù) 都說明合理利用url的可行和流行。

                當然不止是使用了url就算好的實踐,而是能夠做到優(yōu)雅的使用,保證層次分明和整體的簡潔,這才算是好的方式,這也正是本框架對使用url 所追求的目標。

                首先來看幾個例子:

          http://www.cnblogs.com/p2
          http://www.xxx.com/index.do?page=2

          http://www.xxx.com/product/
          http://www.xxx.com/channel.do?channel=product

          http://www.xxx.com/product/mobile
          http://www.xxx.com/channel.do?channel=product&&subChannel=mobile

                相信各位看官不用我說也能明白,這幾組的實現(xiàn)肯定第一種實現(xiàn)的方式更佳。拋開它能屏蔽服務(wù)器端使用的技術(shù)這一特性不說,它還能夠更好地說明動態(tài)網(wǎng)站的層次結(jié)構(gòu),讓用戶在訪問時能明確知道在網(wǎng)站的什么位置,而不會覺得是陷入了一個迷宮。

                當然上面列舉的例子是網(wǎng)站前端所使用的url表現(xiàn)方式,因為表現(xiàn)方式可以多種多樣,個人喜好不同,本框架在設(shè)計時沒有給指定前端url的表現(xiàn)方式,而是定義接口,把這個權(quán)利留給使用的用戶??蚣軐⒖紤]更多 通用性的東西而不是 個性 自由的東西。

           

                下面對框架里默認使用的url Router AMPPathRouter做詳細的介紹,包括設(shè)計的思想和實現(xiàn)的方式。首先AMPPathRouter的用途定位為后臺使用。為了理解快速的理解它的工作原理,先來和struts做一下對比。

                Struts關(guān)于請求的配置:

           

          <action name="login" class="com.lscmjx.action.LoginAction" method="login">
          <result name="success">
          main.jsp
          </result>
          <result name="failure">
          login.jsp
          </result>
          </action>

              它提交的url會是http://xxx.xxx.xxx/login,訪問web服務(wù)器時會把此url傳遞到struts框架交給它處理,之后struts會在struts.xml中尋找login的相關(guān)的配置,像上面例子,struts會找到LoginAction的類,并且調(diào)用其login的方法。

                寫到這里,我請問這是最好的方式嗎?當然不是,至少我在使用struts時就認為這是相當撇腳的設(shè)計。上面例子只是列舉一個login方法,假如一個系統(tǒng)中要對后臺調(diào)用的方法是100個,那豈不是就需要在struts.xml中寫100個與之類似的配置。想想都頭大,這樣繁瑣的工作,應(yīng)該是由框架自己去處理,而不是人工給配置。

           

                再來看實現(xiàn)相同功能的Unicorn web框架的配置。

           

          <action class="com.mh.action.UserAction"></action>

                當然提交的url肯定需要包含多一些的信息,來保證能通過url正確調(diào)用框架Action里的方法。這里提交的url方式:http://xxx.xxx.xxx/UserAction/login/

                通過在url里附加調(diào)用的Action類的信息,可以省略為不同的方法都在xml里配置的麻煩。假如UserAction里有100個方法,框架也只需這一行的配置。

                有了大體的認識之后,來看框架的核心部分AMPPathRouter的具體實現(xiàn)。

           

            /**
          * 檢查url是否是此Router類要處理的,/Action/Method/Param 格式的將會被檢查合格,返回true
          *
          @param relativeUri
          *
          @param actionMap
          *
          @return
          */
          public boolean checkUrl(String relativeUri, Map<String, ActionSupport> actionMap) {
          Pattern pattern = Pattern.compile("^/\\w+/\\w+/\\S*");
          Matcher matcher = pattern.matcher(relativeUri);
          if(matcher.matches()) {
          String actionName = relativeUri.split("/")[1];
          ActionSupport actionSupport = actionMap.get(actionName);
          if(null != actionSupport) {
          String actionMethodName = relativeUri.split("/")[2];
          Class<?> actionClass = actionSupport.getClass();
          Method[] methods = actionClass.getMethods();
          for(int i = 0; i < methods.length; i++) {
          Method method = methods[i];
          String methodName = method.getName();
          if(methodName.equals(actionMethodName)) {
          return true;
          }
          }
          } else {
          return false;
          }
          }
          return false;
          }
          /**
          * 匹配規(guī)則為:
          * 1、符合/Action/method/param格式,
          * 2、并且Action在actionMap中的確存在
          * 3、method在此Action中存在
          */
          @Override
          public boolean route(String relativeUri, UrlFilter urlFilter) {
          Map<String, ActionSupport> actionMap = urlFilter.getActionMap();
          if(!this.checkUrl(relativeUri, actionMap)) {
          return false;
          }
          // 攔截Action/Method/Param方式的請求,并構(gòu)建ActionSupport類的屬性
          String[] params = relativeUri.split("/");
          try {
          ActionSupport actionSupport = actionMap.get(params[1]);
          Class<?> action = actionSupport.getClass();
          Method method = action.getMethod(params[2], new Class[] {});
          if(params.length > 3) {
          this.boxingRequest(urlFilter.getRequest(), params[3]);
          }
          // 只要找到ActionSupport的子類,則初始化其所具有的屬性
          Object newInstance = action.newInstance();
          this.initActionSupport(newInstance, urlFilter);
          String result = (String) method.invoke(newInstance, new Object[] {});
          if (null == result || ActionSupport.AJAX.equals(result) || ActionSupport.FORWARD.equals(result) || ActionSupport.WEB_SERVICE.equals(result)) {
          return true;
          }
          if(ActionSupport.REDIRECT.equals(result)) {
          urlFilter.getResponse().sendRedirect(result);
          return true;
          }
          } catch (NoSuchMethodException e) {
          e.printStackTrace();
          } catch (SecurityException e) {
          e.printStackTrace();
          } catch (IllegalAccessException e) {
          e.printStackTrace();
          } catch (IllegalArgumentException e) {
          e.printStackTrace();
          } catch (InvocationTargetException e) {
          e.printStackTrace();
          } catch (InstantiationException e) {
          e.printStackTrace();
          } catch (Exception e) {
          e.printStackTrace();
          }
          return false;
          }
          /**
          * 把url中得param加入到request的attribute里
          *
          @param request
          *
          @param parameter
          */
          private void boxingRequest(HttpServletRequest request, String parameter) {
          String[] parameters = parameter.split("&");
          for (int i = 0; i < parameters.length; i++) {
          String param = parameters[i];
          String[] key_value = param.split("=");
          if(key_value.length == 2) {
          request.setAttribute(key_value[0], key_value[1]);
          }
          }
          }
          /**
          * 初始化ActionSupport類中所需的request、response、session、application等對象
          *
          @param obj
          *
          @param urlFilter
          */
          private void initActionSupport(Object obj, UrlFilter urlFilter) {
          ActionSupport action = (ActionSupport) obj;
          action.setRequest(urlFilter.getRequest());
          action.setResponse(urlFilter.getResponse());
          action.setSession(urlFilter.getSession());
          action.setApplication(urlFilter.getApplication());
          }

           

                這便是AMPPathRouter的全部內(nèi)容,其中在把請求分發(fā)到ActionSupport的子類 并調(diào)用相關(guān)方法時 是通過反射實現(xiàn),其他地方地方都是相當容易理解的。

                空說無憑,把框架應(yīng)用到實戰(zhàn)中才是硬道理:

           

                好了,下一篇介紹Action 和 json。

          posted @ 2011-11-25 18:18 馬航 閱讀(270) | 評論 (0)編輯 收藏

                上篇說過,所有提交到web程序的url都被此UrlFilter攔截。攔截到請求后,UrlFilter則召集它的好多個得力干將Router 們, 詢問他們:“誰能處理此URL啊 ?”

          這時一位叫做AMPRouter 首當其沖 說:“這個url交給我了”。這時filter就會把此url全權(quán)交給AMPRouter來辦,至于如何去處理,filter也不再過問,它覺得:“我把任務(wù)都交給你了,怎么解決是你的事”。

                根據(jù)單一職責的原則,UrlFilter就負責上面情景中的分發(fā)urlRouter中的差事,url如何分發(fā)交給Router處理。并且Router實際是一個接口,使用框架的用戶完全可以自己實現(xiàn)Router,這樣用戶可以自主定義的url分發(fā)的策略。另外呢,框架初始化的一些操作它也是 推脫不掉的,像根據(jù)unicorn-config.xml初始化系統(tǒng)中的RouterAction'。下面是具體的代碼:

           

          @Override
          public void init(FilterConfig config) throws ServletException {
          	application = config.getServletContext();
          	String loadPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
          	String classPath = loadPath.substring(1, loadPath.length());
          	ArrayList<String> actions = XMLReader.getNodeValues(classPath + "unicorn-config.xml", "actions");
          	this.initActions(actions);
          	ArrayList<String> routers = XMLReader.getNodeValues(classPath + "unicorn-config.xml", "routers");
          	this.initRouters(routers);
          }

           

          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
          			throws IOException, ServletException {
          	HttpServletRequest request = (HttpServletRequest) servletRequest;
          	String path = request.getContextPath();
          	String uri = request.getRequestURI();
          	String relativeUri = uri.substring(path.length(), uri.length());
          	this.request = request;
          	this.session = request.getSession();
          	this.response = (HttpServletResponse) servletResponse;
          	// 用戶自定義的Router優(yōu)先級最高,url先通過用戶定義的
          	Iterator<IPathRouter> iterator = routerList.iterator();
          	while(iterator.hasNext()) {
          		IPathRouter router = iterator.next();
          		if(router.route(relativeUri, this)) {
          			return ;
          		}
          	}
          	// 攔截不到的繼續(xù)訪問
          	filterChain.doFilter(servletRequest, servletResponse);
          }
          

                  其中Router類的初始化,Action類的初始化于這個類似:

          private void initRouters(ArrayList<String> routers) {
          	routerList = new ArrayList<IPathRouter>();
          	for (int i = 0; i < routers.size(); i++) {
          		String routerName = routers.get(i);
          		try {
          			Class<?> clz = Class.forName(routers.get(i));
          			// 單例模式通過方法獲取對象實例
          			IPathRouter router = (IPathRouter) clz.newInstance();
          			routerList.add(router);
          		} catch (ClassNotFoundException e) {
          			e.printStackTrace();
          		} catch (IllegalAccessException e) {
          			e.printStackTrace();
          		} catch (SecurityException e) {
          			e.printStackTrace();
          		} catch (IllegalArgumentException e) {
          			e.printStackTrace();
          		} catch (InstantiationException e) {
          			e.printStackTrace();
          		}
          	}
          	// 最后把框架默認的Router加入進來
          	routerList.add(new AMPPathRouter());
          }
          

                  其中unicorn-config.xml文件的編寫,拿其中我一個項目里的這個文件來舉例:

          <?xml version="1.0" encoding="UTF-8" ?>
          <config>
          <routers>
          <router class="com.mh.router.MySessionCheckRouter"></router>
          </routers>
          <actions>
          <action class="com.mh.action.UserAction"></action>
          <action class="com.mh.action.InformationAction"></action>
          <action class="com.mh.action.UploadInformationIconAction"></action>
          <action class="com.mh.action.TempPicAction"></action>
          <action class="com.mh.action.MobileAction"></action>
          </actions>
          </config>

                這里即定義了Action,也定義了自己的Router,并且從名稱上可以看出,這個SessionCheckRouter是要判斷所有提交到服務(wù)器的指定url的請求 是否已經(jīng)登錄過,沒有登錄,可能會把此請求遣送會登錄頁。以及初始化所有的Action,在Router處理完請求,分發(fā)給action時,可以從filter里面去取。

           


          posted @ 2011-11-25 12:35 馬航 閱讀(274) | 評論 (0)編輯 收藏

                承接上篇的簡單介紹,下面詳細介紹整個框架的大致結(jié)構(gòu)。

                先來看一下整個框架包的結(jié)構(gòu):

           

                可以看出框架包含的包很少,包的結(jié)構(gòu)也超簡單。這里 涉及Filter、ActionSupportRouter等三個概念,他們之間的關(guān)系,通過下圖來表示:

           

                圖也不規(guī)范,說不上來是哪個UML圖,不過通過它也能看出一個請求到達時,框架基本的處理流程。首先由Filter攔截到所有請求,然后把請求交給所有注冊的Router類,如果請求的Url正好是一個Router要攔截的,則把此請求交給這個Router,框架不再把請求向下傳遞。Router得到請求后,分析Url,通過Url里的信息把請求交給對應(yīng)的ActionSupport的子類來處理。

                這里攔截采用Filter來處理,這跟多數(shù)的web框架一樣,使用FilterServlet有更多的能力進行請求的分發(fā)。首先在一個web工程的web.xml文件中配置框架的UrlFilter類來攔截所有的請求。需要注意的一點是dispatcher 要設(shè)置為request,如果設(shè)置了forward的話,由框架內(nèi)部進行的forward又會被框架攔截,從而造成無限的循環(huán)。Url-pattern設(shè)置為/*,表示所有的請求都會攔截,從而把對url分發(fā)的權(quán)利交由框架本身,而不是采用jsp規(guī)范里的url分發(fā)策略。框架在處理所有請求的url 時,依次交給各個Router類來處理,如果Router類判斷是符合自己的url格式,則分發(fā)給 action 處理。如果不能處理再交給下一級的Router,最后url經(jīng)由所有Router處理完,剩下的資源文件的url,如http://xxx.xxx.xxx.jpg,則框架調(diào)用filterdoChain()方法,通過filter的過濾去訪問web里的資源。

          <filter>

                <filter-name>unicornWeb</filter-name>

                <filter-class>com.mh.mvc.filter.UrlFilter</filter-class>

          </filter>

          <filter-mapping>

              <filter-name>unicornWeb</filter-name>

              <url-pattern>/*</url-pattern>

              <dispatcher>REQUEST</dispatcher>

          </filter-mapping>

                大致的原理就是這樣,在下篇介紹框架的詳細實現(xiàn)。

          posted @ 2011-11-25 11:43 馬航 閱讀(350) | 評論 (0)編輯 收藏

                我承認有點標題黨了,不過題目中所說的幾項技術(shù)確實有其相似之處,欲知事情原委,且聽我詳細道來。

                項目一開始只是不滿 struts 龐大的體積,于是想自己根據(jù)其原理實現(xiàn)一個tiny 版。后來的開發(fā)中覺得,完全可以把上述的ajax、Restuful web service的一些思想加入進來。經(jīng)過幾周的努力,便開發(fā)出了一個基本成型的web 框架,暫且起名為unicorn(獨角獸,吼吼)。下文開始便對這個自編寫的框架做一些列的介紹,并且初步打算是將其開源,希望能一起交流和完善它。

                首先,為了能快速了解它是什么,先來看一下配置文件:

          <?xml version="1.0" encoding="UTF-8" ?>
          <config>
          <routers>
          <router class="com.mh.router.MySessionCheckRouter"></router>
          </routers>
          <actions>
          <action class="com.mh.action.UserAction"></action>
          <action class="com.mh.action.InformationAction"></action>
          <action class="com.mh.action.MobileAction"></action>
          </actions>
          </config>

                上面就是整個工程的配置文件,可以看出需要配置的東西非常少,只需要制定action類 和 router類有哪些就Ok??蚣芊钚屑s定大于配置的思想,至于請求如何分發(fā),這個不需要人工配置,框架自動解決。這里要介紹兩個概念A(yù)ction 和 Router,熟悉Struts的肯定都知道Action,Action替代Servlet、JSP時代的Servlet,所有提交的請求由struts分發(fā)給不同的Action來處理。這里道理也是一樣的,Action就是經(jīng)過框架處理后的請求接受者。再來說一下Router,字面意思路由器,學(xué)過計算機網(wǎng)絡(luò)的都知道,ip數(shù)據(jù)包在網(wǎng)絡(luò)上之所以能夠順利到達,就是因為路由器根據(jù)路由表來來確定出來傳輸?shù)耐緩?。這里Router也是這個作用,根據(jù)訪問服務(wù)器的URL來制定分發(fā)策略。Router是完全可以自定義的,用戶可以定義自己的Router來制定URL分發(fā)的策略,并且用戶自定義的Router比系統(tǒng)默認的Router有更高的優(yōu)先權(quán)。

          二、URL上做文章

          /UserAction/login/username=admin&&password=admin

                先來介紹系統(tǒng)MethodRouter的處理方式。上面的url根據(jù)"/"分為三個部分,第一部分是請求的Action類,第二部分是類中的方法Method,第三部分是提交的參數(shù)Param。這一點受上篇文章優(yōu)酷的架構(gòu)里URL設(shè)計的啟發(fā)。

                經(jīng)過這樣的設(shè)計,就明白在上述配置文件中為何可以如此簡單了。

                當然也可以不以這樣的方式,框架提供自定義Router的支持。比如你想這樣處理URL:/前臺頁面/子欄目/子欄目

                想實現(xiàn)上面的方式,就可以自己定義Router,在Router里面獲取上述的URL,然后做處理、forward到相應(yīng)的jsp頁面。

          三、使用Json傳輸數(shù)據(jù)

                Ajax請求很容易處理json數(shù)據(jù),ajax可以與系統(tǒng)輕松交互。

                當初Web Service使用SOAP的xml格式傳輸數(shù)據(jù),如今也有人指責這是大費周折。Restful方式提倡遵循HTTP語義,完全使用URL結(jié)合GET、POST、PUT、DELETE來傳輸請求,結(jié)果在roil陣營里廣泛使用,認為是web service更優(yōu)雅的方式。所以本框架也吸取他們的優(yōu)點,也完全可以通過url傳輸請求的數(shù)據(jù),如上述URL中的Param部分。不過沒有遵循Restful強調(diào)的Http語義,全部使用Get和POST的請求方式,當然也可以制定為其他,這完全看你的心情,因為這對功能實現(xiàn)無關(guān)緊要。而且我覺得統(tǒng)一使用一種,更避免了需要指定請求方式的麻煩。

                數(shù)據(jù)的返回使用json格式,比SOAP更為輕量簡潔和優(yōu)雅,而且有更多的平臺直接支持。如在android平臺,本身就支持json格式的處理, 如果使用web service 的SOAP,你可能還要導(dǎo)入KSOAP的第三方庫。

                在非瀏覽器的客戶端,可以借助編寫的工具類,來完成web service方式的操作,

          public interface IWebService {
          	public List<LiteInformationDTO> getInformationsOfOwnerApp(String ownerApp, int start, int limit) throws SocketTimeoutException;
          }
          

                經(jīng)過這樣的封裝,已經(jīng)與使用web service毫無差別,而且還會更加高效,因為處理json總比處理SOAP的xml要容易。

           

                先簡單寫這么多,之后的續(xù)篇詳細介紹。

          posted @ 2011-11-22 16:22 馬航 閱讀(285) | 評論 (0)編輯 收藏

          記得以前給大家介紹過視頻網(wǎng)站龍頭老大YouTube的技術(shù)架構(gòu),相信大家看了都會有不少的感觸,互聯(lián)網(wǎng)就是這么一個神奇的東西。今天我突然想到,優(yōu)酷網(wǎng)在國內(nèi)也算是視頻網(wǎng)站的老大了,不知道他的架構(gòu)相對于YouTube是怎么樣的,于是帶著這個好奇心去網(wǎng)上找了優(yōu)酷網(wǎng)架構(gòu)的各方面資料,雖然談得沒有YouTube那么詳細,但多少還是挖掘了一點,現(xiàn)在總結(jié)一下,希望對喜歡架構(gòu)的朋友有所幫助。

          一、網(wǎng)站基本數(shù)據(jù)概覽

          • 據(jù)2010年統(tǒng)計,優(yōu)酷網(wǎng)日均獨立訪問人數(shù)(uv)達到了8900萬,日均訪問量(pv)更是達到了17億,優(yōu)酷憑借這一數(shù)據(jù)成為google榜單中國內(nèi)視頻網(wǎng)站排名最高的廠商。
          • 硬件方面,優(yōu)酷網(wǎng)引進的戴爾服務(wù)器主要以 PowerEdge 1950與PowerEdge 860為主,存儲陣列以戴爾MD1000為主,2007的數(shù)據(jù)表明,優(yōu)酷網(wǎng)已有1000多臺服務(wù)器遍布在全國各大省市,現(xiàn)在應(yīng)該更多了吧。

          二、網(wǎng)站前端框架

          從一開始,優(yōu)酷網(wǎng)就自建了一套CMS來解決前端的頁面顯示,各個模塊之間分離得比較恰當,前端可擴展性很好,UI的分離,讓開發(fā)與維護變得十分簡單和靈活,下圖是優(yōu)酷前端的模塊調(diào)用關(guān)系:

          這樣,就根據(jù)module、method及params來確定調(diào)用相對獨立的模塊,顯得非常簡潔。下面附一張優(yōu)酷的前端局部架構(gòu)圖:

           

          三、數(shù)據(jù)庫架構(gòu)

          應(yīng)該說優(yōu)酷的數(shù)據(jù)庫架構(gòu)也是經(jīng)歷了許多波折,從一開始的單臺MySQL服務(wù)器(Just Running)到簡單的MySQL主從復(fù)制、SSD優(yōu)化、垂直分庫、水平sharding分庫,這一系列過程只有經(jīng)歷過才會有更深的體會吧,就像MySpace的架構(gòu)經(jīng)歷一樣,架構(gòu)也是一步步慢慢成長和成熟的。

          1、簡單的MySQL主從復(fù)制:

          MySQL的主從復(fù)制解決了數(shù)據(jù)庫的讀寫分離,并很好的提升了讀的性能,其原來圖如下:

          其主從復(fù)制的過程如下圖所示:

          但是,主從復(fù)制也帶來其他一系列性能瓶頸問題:

          1. 寫入無法擴展
          2. 寫入無法緩存
          3. 復(fù)制延時
          4. 鎖表率上升
          5. 表變大,緩存率下降

          那問題產(chǎn)生總得解決的,這就產(chǎn)生下面的優(yōu)化方案,一起來看看。

           

          2、MySQL垂直分區(qū)

          如果把業(yè)務(wù)切割得足夠獨立,那把不同業(yè)務(wù)的數(shù)據(jù)放到不同的數(shù)據(jù)庫服務(wù)器將是一個不錯的方案,而且萬一其中一個業(yè)務(wù)崩潰了也不會影響其他業(yè)務(wù)的正常進行,并且也起到了負載分流的作用,大大提升了數(shù)據(jù)庫的吞吐能力。經(jīng)過垂直分區(qū)后的數(shù)據(jù)庫架構(gòu)圖如下:

          然而,盡管業(yè)務(wù)之間已經(jīng)足夠獨立了,但是有些業(yè)務(wù)之間或多或少總會有點聯(lián)系,如用戶,基本上都會和每個業(yè)務(wù)相關(guān)聯(lián),況且這種分區(qū)方式,也不能解決單張表數(shù)據(jù)量暴漲的問題,因此為何不試試水平sharding呢?

           

          3、MySQL水平分片(Sharding)

          這是一個非常好的思路,將用戶按一定規(guī)則(按id哈希)分組,并把該組用戶的數(shù)據(jù)存儲到一個數(shù)據(jù)庫分片中,即一個sharding,這樣隨著用戶數(shù)量的增加,只要簡單地配置一臺服務(wù)器即可,原理圖如下:

          如何來確定某個用戶所在的shard呢,可以建一張用戶和shard對應(yīng)的數(shù)據(jù)表,每次請求先從這張表找用戶的shard id,再從對應(yīng)shard中查詢相關(guān)數(shù)據(jù),如下圖所示:

          但是,優(yōu)酷是如何解決跨shard的查詢呢,這個是個難點,據(jù)介紹優(yōu)酷是盡量不跨shard查詢,實在不行通過多維分片索引、分布式搜索引擎,下策是分布式數(shù)據(jù)庫查詢(這個非常麻煩而且耗性能)

           

          四、緩存策略

          貌似大的系統(tǒng)都對“緩存”情有獨鐘,從http緩存到memcached內(nèi)存數(shù)據(jù)緩存,但優(yōu)酷表示沒有用內(nèi)存緩存,理由如下:

          1. 避免內(nèi)存拷貝,避免內(nèi)存鎖
          2. 如接到老大哥通知要把某個視頻撤下來,如果在緩存里是比較麻煩的

          而且Squid 的 write() 用戶進程空間有消耗,Lighttpd 1.5 的 AIO(異步I/O) 讀取文件到用戶內(nèi)存導(dǎo)致效率也比較低下。

          但為何我們訪問優(yōu)酷會如此流暢,與土豆相比優(yōu)酷的視頻加載速度略勝一籌?這個要歸功于優(yōu)酷建立的比較完善的內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN),它通過多種方式保證分布在全國各地的用戶進行就近訪問——用戶點擊視頻請求后,優(yōu)酷網(wǎng)將根據(jù)用戶所處地區(qū)位置,將離用戶最近、服務(wù)狀況最好的視頻服務(wù)器地址傳送給用戶,從而保證用戶可以得到快速的視頻體驗。這就是CDN帶來的優(yōu)勢,就近訪問,有關(guān)CDN的更多內(nèi)容,請大家Google一下。

          好了,就總結(jié)這么多了,有興趣的同學(xué)接著補充,雖然很多資料圖片都來自網(wǎng)絡(luò),但整理也不容易,歡迎轉(zhuǎn)載,轉(zhuǎn)載留個出處:青藤屋 原文鏈接

          posted @ 2011-11-02 11:23 馬航 閱讀(289) | 評論 (0)編輯 收藏

          windows系統(tǒng)使我們經(jīng)常使用的操作系統(tǒng)怎么才能使用我們現(xiàn)在經(jīng)常使用的操作系統(tǒng)不變的情況下繼續(xù)我們的SVN之旅,我們在綜合了好動種方法的同時感覺這些內(nèi)容非常貼近我們SVN在Windows種的應(yīng)用與配置.

          1.下載文件,

          下載最新版本subversion,我這里選擇svn-1.4.5-setup.exe

          下載 "Subversion Windows Service" 軟件包

          下載 TortoiseSVN shell integration utility

          2.安裝Subversion 服務(wù)器

          由于我下載的是setup.exe版本,安裝程序安裝后會自動設(shè)置系統(tǒng)變量.如果你下載的是zip版就需要手動設(shè)置系統(tǒng)變量.

          setup.exe版直接安裝就可以了.安裝到D:/Program Files/Subversion

          首先創(chuàng)建SVN儲存庫(repository)

          svnadmin create F:/svn/

          repository創(chuàng)建完畢后會在目錄下生成若干個文件和文件夾,dav目錄是提供給Apache與mod_dav_svn使用的目錄,讓它們存儲內(nèi)部數(shù)據(jù);db目錄就是所有版本控制的數(shù)據(jù)文件;hooks目錄放置hook腳本文件的目錄;locks用來放置Subversion文件庫鎖定數(shù)據(jù)的目錄,用來追蹤存取文件庫的客戶端;format文件是一個文本文件,里面只放了一個整數(shù),表示當前文件庫配置的版本號;

          3.配置SVN服務(wù)器

          (這個位置就是在你建儲存庫的地方F:/svn)

          打開/conf/目錄,打開svnserve.conf找到一下兩句:

          # [general]

          # password-db = passwd

          # anon-access = none

          # auth-access = write

          去之每行開頭的#,其中第二行是指定身份驗證的文件名,即passwd文件.anon-access = none 是匿名用戶不能訪問,必須要有用戶名和密碼。(注意:問題就出在這,一定要注意格式去掉注釋后要頂格不能有空)

          同樣打開passwd文件,將

          # [users]

          # harry = harryssecret

          # sally = sallyssecret

                 格式為“用戶名 = 密碼”,如可插入一行:admin = admin888,即為系統(tǒng)添加一個用戶名為admin,密碼為admin888的用戶

          4.運行SVN服務(wù)器

          運行SVN服務(wù)

          在命令行執(zhí)行

          svnserve --daemon --root F:/svn

          服務(wù)啟動,--daemon可簡寫為-d,--root可簡寫為-r,可以建立一個批處理文件并放在windows啟動組中便于開機就運行SVN服務(wù)(注意:這是臨時打開的服務(wù),命令執(zhí)行后不能關(guān)閉窗口)

          也可以制定subversion工作的端口:svnserve -d -r f:/svn --listen-port 9999

          用后臺服務(wù)的方式可以設(shè)置開機自動執(zhí)行。

          D:/Program Files/Subversion/bin>sc create svnservice binpath= "C:/Program Files/Subversion/bin/svnserve.exe --service -r f:/svn  --listen-port 9999"

          就可以用net svnservice stop 或者start來啟動服務(wù)了 也可以在Sevices.msc來啟動了。

          5、用客戶端訪問

          格式:svn://服務(wù)器IP

           

          ---------------------------------------------------------------------------------------------------------

           

          基于svnserve的服務(wù)器,權(quán)限文件authz配置的常見問題及解答  
           最近在我用Subversion論壇(http://www.iUseSVN.com/bbs)經(jīng)常有人提到這樣的問題: 
          為什么我的客戶端沒有寫權(quán)限? 
          為什么我的權(quán)限沒有起作用?

          總結(jié)他們的配置,發(fā)現(xiàn) 
          都是用svnserve作為服務(wù)器, 
          都在svnserve.conf中使用了authz-db選項

          原因可能如下:

          1,配置authz時,沒有注意svnserve啟動參數(shù)-r所指定的目錄。 
          這里有兩種情況: 
          A:-r直接指定到版本庫(稱之為單庫svnserve方式) 
          比如,有一個庫project1,位于D:/svn/project1 
          使用以下命令啟動svnserve

          [Copy to clipboard] [ - ]CODE: 
          svnserve -d -r D:/svn/project1 
          在這種情況下,一個svnserve只能為一個版本庫工作 
          authz文件如果配置成下面這樣就是錯的,

          [Copy to clipboard] [ - ]CODE: 
          [groups] 
          admin=user1 
          dev=user2 
          [project1:/] 
          @admin=rw 
          @doc=r 
          應(yīng)該配置成

          [Copy to clipboard] [ - ]CODE: 
          [groups] 
          admin=user1 
          dev=user2 
          [/] 
          @admin=rw 
          @doc=r 
          因為[project1:/]表示庫project1的根目錄,而按上面的啟動參數(shù),是沒有庫的概念的。 
          使用類似這樣的URL:svn://192.168.0.1/ 即可訪問project1

          B:-r指定到版本庫的上級目錄(稱之為多庫svnserve方式) 
          同樣,有一個庫project1,位于D:/svn/project1 
          如果使用以下命令啟動svnserve

          [Copy to clipboard] [ - ]CODE: 
          svnserve -d -r D:/svn 
          這種情況,一個svnserve可以為多個版本庫工作, 
          這時如果想限制指定庫的指定目錄,就應(yīng)該指定具體的庫,像這樣

          [Copy to clipboard] [ - ]CODE: 
          [groups] 
          admin=user1 
          dev=user2 
          [project1:/] 
          @admin=rw 
          @doc=r 
          如果此時你還用[/],則表示所有庫的根目錄,同理,[/src]表示所有庫的根目錄下的src目錄 
          使用類似這樣的URL:svn://192.168.0.1/project1 即可訪問project1 
          這樣的URL:svn://192.168.0.1/project2 即可訪問project2

          2,對中文目錄進行權(quán)限控制時,沒有將權(quán)限文件authz改為utf-8格式。

          svn對于非英文文件名和目錄名使用utf-8格式編碼處理,要對中文目錄進行正確控制, 
          應(yīng)該使用無BOM的utf-8格式,如何將默認的文件轉(zhuǎn)為utf-8, 
          我使用的是UltraEdit的菜單"ASCII to UTF-8 (Unicode Editing)"。在UltraEdit的配置中,可以設(shè)置有無BOM  

          posted @ 2011-10-12 17:26 馬航 閱讀(424) | 評論 (0)編輯 收藏

          SIP協(xié)議

           

          SIP協(xié)議過程概念及分析

           

          SIP入門開發(fā)之路(含SIP開發(fā)需要學(xué)習(xí)的資源及網(wǎng)址)

           

          SIP揭密(中文版)

           

          使用Java的SIP Servlet進行SIP開發(fā)

           

           

          Asterisk:

           

          Asterisk安裝及測試

           

          Asterisk十問十答

           

          Asterisk入門教程

           

          Asterisk介紹-Asterisk RealTime SIP

          asterisk配置文件列表及常用指令

           

          asterisk 官方文檔

           

          asterisk目錄及配置說明

           

          Asterisk功能整理

           

          Asterisk使用ODBC實現(xiàn)語音信箱

           

          使用Asterisk實現(xiàn)可視的語音交換

           

           

          OpenSIPS

           

          開源SIP服務(wù)器OpenSIPS應(yīng)用介紹

           

          Opensips 安裝

           

          Opensips 配置文件

           

          Mediaproxy的安裝及其在OpenSIPS中的配置

           

          Opensips文檔之MediaProxy模塊

           

          使用OpenSIPS構(gòu)建電話通信系統(tǒng)-8媒體服務(wù)整合

           

          使用OpenSIPS構(gòu)建電話通信系統(tǒng)-4腳本及路由基礎(chǔ)

           

          Opensips文檔之TM模塊

           

          Opensips文檔之RR模塊

           

          Opensips文檔之TEXTOPS 模塊

           

          Opensips文檔之AVPOPS模塊

           

           

          NAT穿透(即SIP打洞)

           

          使用OpenSIPS構(gòu)建電話通信系統(tǒng)-SIP穿透NAT

           

          NAT穿透問題探討

           

          完美的NAT穿透技術(shù)ICE介紹

           

          ICE-SIP穿透NAT問題的終極解決方案

           

          NAT穿透技術(shù)ICE基礎(chǔ)教程

          posted @ 2011-10-07 20:31 馬航 閱讀(455) | 評論 (0)編輯 收藏

               摘要: Android中有一控件是ExpandableListView,比ListView更高級,ExpandableListView的效果很實用,比如因為需要查看一堆文件的目錄結(jié)構(gòu)或者開發(fā)像QQ好友那樣的界面,就應(yīng)該使用Expandablelistview。 本文最終效果如下: 首先是Activity代碼,實際開發(fā)中數(shù)據(jù)(包括父item,子item及圖片,Expandablelistview...  閱讀全文

          posted @ 2011-10-06 09:37 馬航 閱讀(5471) | 評論 (0)編輯 收藏

          前言:做完了手機全能播放器的項目, 又要告別幾個月來并肩作戰(zhàn),即將去北京發(fā)展的Manager zhu。準備把做過的3GP/FLV/AVI格式整理一遍, 算是對幾個月辛苦成果的總結(jié), 也為后來者提供一些參考。

          1. 概述

          流行的文件格式背后都有大公司的支持。FLV得益于ADOBE公司推動的網(wǎng)絡(luò)視頻分享風潮,而AVI則是MICROSOFT首創(chuàng)的RIFF即視頻和音頻交織在一起同步播放。 3GP/MP4是APPLE提出并得到ISO標準支持作為NOKIA等手機的默認視頻格式。3GP是MP4格式在手機上的簡化版。MP4的codec組合一般是mpeg4 + AAC, 3GP則按版本演進分為3gpp r5(h.263/mpeg4 + AMR-NB/AMR WB), 3gpp r6(增加h.264視頻和aacPlus音頻支持)。

          有人會把MP4和MPEG4搞混, 前者是文件容器(container),后者是視頻編碼格式, 容器的作用是把壓縮編碼后的視頻和音頻數(shù)據(jù)盡可能緊湊的排布,就好像阿甘的巧克力盒子,你并不知道盒子里有什么, 但你可以按照既定的線索解開文件,取出你需要的數(shù)據(jù)。

          文件格式一般包括以下三要素:

          header: 標記文件類型,音視頻碼流的基本屬性信息
          index: 索引表,每個frame有對應(yīng)的offset,size,timestamp.
          stream: 真正的音視頻流數(shù)據(jù)。
          任何文件格式都應(yīng)該有以上3要素。 當然AVI視頻沒有索引也能播放,但不能拖放seek,需要自己重建索引。解析器(demuxer)根據(jù)frame_id找到其在文件中的offset和size,然后讀取出來解碼并播放。

          2. 文件格式分析

          下面來分析一下3GP/MP4文件格式。APPLE的格式有2個特點,1. 排布緊湊幾乎沒有冗余數(shù)據(jù)(AVI則有很多junk數(shù)據(jù)),2.音視頻碼流數(shù)據(jù)可隨意存放而不需按時間順序排布。

          3gp文件由一系列的box(atom)組成。每個box的結(jié)構(gòu)都是4字節(jié)的size,4字節(jié)的type, 還有一些data數(shù)據(jù)。用mp4info查看3gp文件的數(shù)據(jù)排布如下圖:

          如上圖, ftyp是表示文件的版本信息, mdat存放文字,音視頻等數(shù)據(jù)。你可能要問,這些音視頻數(shù)據(jù)怎么找到呢? 是通過moov box里的子box trak,里面存放著音視頻的屬性描述以及每個sample的索引。

          3. 關(guān)于sample atoms

             video和audio的碼流屬性(如視頻width/height,codec id, 音頻采樣率聲道數(shù)等)存放在stsd box里; 下面著重介紹MP4高效壓縮的精華:stts,stss,stsc,stsz,stco五個box。對比AVI的索引表是每個sample都有對應(yīng)的id,flag,offset,size,3GP的高效索引方式可以把AVI轉(zhuǎn)碼成同碼率的MP4后,文件size減小成原來的20-30%!

          1. stts atom(time to sample atoms,見quicktime format 文檔圖2-28 標準文檔點擊下載): 存儲了sample的時間信息。stts能讓很方便的根據(jù)timestamp找到對應(yīng)的sample,或者獲取某個sample對應(yīng)的timestamp. sttstable記錄著有相同duration的sample的數(shù)量count和時長dutation。

          2. stss atom(sync sample atom,見文檔圖2-31): 存儲了每個關(guān)鍵幀的sample id。 stss能讓你很方便的找到當前幀最近的關(guān)鍵幀。

          3. stsc atom(sample to chunk atom): sample存放在chunk里為了允許優(yōu)化的數(shù)據(jù)讀取。比如音頻sample size都很?。╝mr-nb sample size為32字節(jié)), 每次讀取一個sample開銷太大, 可一次性讀所在chunk里一堆sample。

          4. stsz atom(sample size atom): stsz可以描述每個sample的size.

          5. stco atom(chunk offset atoms): stco描述了每個chunk在文件中的絕對偏移位置。該offset可以是32位的

          也可以是64位的,后者用來支持處理超大文件。

          4 .使用sample atoms來處理播放流程

          · 查找sample         

          1.確定時間,相對于媒體時間坐標系統(tǒng)

          2.檢查time-to-sample atom來確定給定時間的sample序號。

          3.檢查sample-to-chunk atom來發(fā)現(xiàn)對應(yīng)該sample的chunk。

          4.從chunk offset atom中提取該trunk的偏移量。

          5.利用sample size atom找到sample在trunk內(nèi)的偏移量和sample的大小。

          例如,如果要找第1秒的視頻數(shù)據(jù),過程如下:

          1. 第1秒的視頻數(shù)據(jù)相對于此電影的時間為600

          2. 檢查time-to-sample atom,得出每個sample的duration是40,從而得出需要尋找第600/40 = 15 + 1 = 16個sample

          3. 檢查sample-to-chunk atom,得到該sample屬于第5個chunk的第一個sample,該chunk共有4個sample

          4. 檢查chunk offset atom找到第5個trunk的偏移量是20472

          5. 由于第16個sample是第5個trunk的第一個sample,所以不用檢查sample size atom,trunk的偏移量即是該sample的偏移量20472。如果是這個trunk的第二個sample,則從sample size atom中找到該trunk的前一個sample的大小,然后加上偏移量即可得到實際位置。

          6. 得到位置后,即可取出相應(yīng)數(shù)據(jù)進行解碼,播放

          ·       查找關(guān)鍵幀      

          查找過程與查找sample的過程非常類似,只是需要利用sync sample atom來確定key frame的sample序號

          確定給定時間的sample序號 
          檢查sync sample atom來發(fā)現(xiàn)這個sample序號之后的key frame 
          檢查sample-to-chunk atom來發(fā)現(xiàn)對應(yīng)該sample的chunk 
          從chunk offset atom中提取該trunk的偏移量 
          利用sample size atom找到sample在trunk內(nèi)的偏移量和sample的大小


          5 .3GP/MP4相關(guān)資源

               quicktime file format specification: 最權(quán)威的格式文檔 點擊下載
               開源的3GP/MP4解析器: ffmpeg, GPAC, helix, google opencore等 

          posted @ 2011-10-03 10:54 馬航 閱讀(696) | 評論 (0)編輯 收藏

          Android開發(fā)又將帶來新一輪熱潮,很多開發(fā)者都投入到這個浪潮中去了,創(chuàng)造了許許多多相當優(yōu)秀的應(yīng)用。其中也有許許多多的開發(fā)者提供了應(yīng)用開 源項目,貢獻出他們的智慧和創(chuàng)造力。學(xué)習(xí)開源代碼是掌握技術(shù)的一個最佳方式。下面推薦幾個應(yīng)用開源項目,這些項目不僅提供了優(yōu)秀的創(chuàng)意,也可以直接掌握 Android內(nèi)核的接口使用:

          1、Android團隊提供的示例項目

          如果不是從學(xué)習(xí)Android SDK中提供的那些樣例代碼開始,可能沒有更好的方法來掌握在Android這個框架上開發(fā)。由Android的核心開發(fā)團隊提供了15個優(yōu)秀的示例項目,包含了游戲、圖像處理、時間顯示、開始菜單快捷方式等。
          地址:http://code.google.com/p/apps-for-android/

          2、 Remote Droid

          RemoteDroid是一個Android應(yīng)用,能夠讓用戶使用自己的無線網(wǎng)絡(luò)使用無線鍵盤、觸摸屏操作手機。這個項目為開發(fā)者提供了如網(wǎng)絡(luò)連接、觸摸屏手指運動等很好的樣例。
          地址:http://code.google.com/p/remotedroid/

          3、 TorProxy和Shadow

          TorProxy應(yīng)用實現(xiàn)了Android手機無線電電傳通訊(TOR),和Shadow應(yīng)用一起使用,可以使用手機匿名上網(wǎng)。從該項目源代碼中,可以掌握socket連接、管理cookie等方法。
          地址:http://www.cl.cam.ac.uk/research/dtg/code/svn/android-tor/

          4、 Android SMSPopup

          SMSPopup可以截獲短信內(nèi)容顯示在一個泡泡形狀的窗口中。從這個項目中可以掌握到如何使用內(nèi)置的短信SMS接口。
          地址:http://code.google.com/p/android-smspopup/

          5、 Standup Timer

          Standup Timer應(yīng)用用于控制站立會議時間,類似秒表倒計時,可以提醒每個人的講話時間已到,從而保證每個與會者使用時間一樣。從該項目的代碼中,可以學(xué)會如何使用時間函數(shù)。另外,這個項目的代碼是采用視圖view、模型model嚴格分離的設(shè)計思路。
          地址:http://github.com/jwood/standup-timer

          6、 Foursquare

          是Foursquare.com的一個客戶端應(yīng)用,該應(yīng)用主要分為兩個模塊:API(com.joelapenna.foursquare)和界面前端 (com.joelapenna.foursquared)兩部分。從該項目代碼中,可以學(xué)會如何同步、多線程、HTTP連接等技術(shù)。
          地址:http://code.google.com/p/foursquared/

          7、 Pedometer

          Pedometer應(yīng)用用于記錄你每天走路步數(shù)的。盡管記錄不一定精準,但是從這個項目中,可以學(xué)習(xí)幾個不同的技術(shù):加速器交互、語音更新、后臺運行服務(wù)等。
          地址:http://code.google.com/p/pedometer/

          8、 OpenSudoku-android

          OpenSudoku是一個簡單的九宮格數(shù)獨游戲。從代碼中可以學(xué)習(xí)到如何在視圖中顯示表格數(shù)據(jù),以及如何和一個網(wǎng)站交互等技術(shù)。
          地址:http://code.google.com/p/opensudoku-android/

          9、 ConnectBot

          ConnectBot是Android平臺的一個客戶端安全殼應(yīng)用。從該項目代碼中,可以學(xué)習(xí)到很多Android安全方面的內(nèi)容,這些是你在開發(fā)應(yīng)用時經(jīng)常需要考慮的安全問題。
          地址:http://code.google.com/p/connectbot/

          10、 WordPress的Android應(yīng)用

          當然在最后不能不提WordPress的Android應(yīng)用了,這是WordPress官方開發(fā)團隊提供的一個項目。從代碼中可以學(xué)習(xí)到XMLRPC調(diào)用(當然還有更多的優(yōu)秀內(nèi)容)。
          地址:http://android.svn.wordpress.org/trunk/

          posted @ 2011-10-03 09:47 馬航 閱讀(482) | 評論 (0)編輯 收藏

          導(dǎo)讀:對于Android開發(fā)者來說,成系列的技術(shù)文章對他們的技術(shù)成長幫助最大。如下是我們向您強烈推薦的主題為Android開發(fā)的第一個系列文章。

          文章皆來自CSDN網(wǎng)友maxleng的專欄,maxleng是名Android愛好者,長期從事嵌入式系統(tǒng)及手機軟件系統(tǒng)研究,自2010年4月起,在CSDN上先后發(fā)表28篇《Android核心分析》系列博文,收到網(wǎng)友們的極高評價。《Android核心分析》整理如下:

          1. 方法論探討之設(shè)計意圖

          2. 方法論探討之概念空間篇

          3. 手機之硬件形態(tài)

          4. 手機的軟件形態(tài)

          5. Android基本空間劃分

          6. IPC框架分析(Binder,Service,Service manager)

          7. Service詳解

          8. Android啟動過程詳解

          9. Zygote Service詳解

          10.Android GWES基本原理篇

          11.Android GWES消息系統(tǒng)篇

          12.Android核心分析之Android GEWS窗口管理基本架構(gòu)篇

          13.Android GWES窗口管理詳解

          14.Android GWES輸入系統(tǒng)篇

          15.Android GWES輸入系統(tǒng)之輸入路徑詳解

          16.Android電話系統(tǒng)-概述篇

          17.Android電話系統(tǒng)之Rild服務(wù)詳解

          18.Android電話系統(tǒng)之GSMCallTracker

          19.Android電話系統(tǒng)之RIL-Java

          20.Android應(yīng)用程序框架之無邊界設(shè)計意圖

          21.Android應(yīng)用框架之AndroidApplication

          22.Android應(yīng)用框架之Activity

          22.Andoird GDI之基本原理及其總體框架

          23.Android GDI之顯示緩沖管理

          24.Android GDI之共享緩沖區(qū)機制

          25.Android GDI之共享緩沖區(qū)機制

          26.Android GDI之SurfaceFlinger

          27.Android GDI之SurfaceFlinger之動態(tài)結(jié)構(gòu)示意圖

          28.Android GDI之Surface&Canvas

          原文地址:http://mobile.csdn.net/a/20110209/291511.html

          posted @ 2011-09-23 15:34 馬航 閱讀(110) | 評論 (0)編輯 收藏

          新手學(xué)堂:嵌入式Linux操作系統(tǒng)學(xué)習(xí)規(guī)劃
          ARM+LINUX路線,主攻嵌入式Linux操作系統(tǒng)及其上應(yīng)用軟件開發(fā)目標:
          (1) 掌握主流嵌入式微處理器的結(jié)構(gòu)與原理(初步定為arm9)
          (2) 必須掌握一個嵌入式操作系統(tǒng) (初步定為uclinux或linux,版本待定)
          (3) 必須熟悉嵌入式軟件開發(fā)流程并至少做一個嵌入式軟件項目。
          從事嵌入式軟件開發(fā)的好處是:
          (1)目前國內(nèi)外這方面的人都很稀缺。這一領(lǐng)域入門門檻較高,所以非專業(yè)IT人員很難切入這一領(lǐng)域;另一方面,是因為這一領(lǐng)域較新,目前發(fā)展太快,大多數(shù)人無條件接觸。
          (2)與企業(yè)計算等應(yīng)用軟件不同,嵌入式領(lǐng)域人才的工作強度通常低一些(但收入不低)。
          (3)哪天若想創(chuàng)業(yè),搞自已的產(chǎn)品,嵌入式不像應(yīng)用軟件那樣容易被盜版。硬件設(shè)計一般都是請其它公司給訂做(這叫“貼牌”:OEM),都是通用的硬件,我們只管設(shè)計軟件就變成自己的產(chǎn)品了。
          (4)興趣所在,這是最主要的。
          從事嵌入式軟件開發(fā)的缺點是:
          (1)入門起點較高,所用到的技術(shù)往往都有一定難度,若軟硬件基礎(chǔ)不好,特別是操作系統(tǒng)級軟件功底不深,則可能不適于此行。
          (2)這方面的企業(yè)數(shù)量要遠少于企業(yè)計算類企業(yè)。
          (3)有少數(shù)公司經(jīng)常要碩士以上的人搞嵌入式,主要是基于嵌入式的難度。但大多數(shù)公司也并無此要求,只要有經(jīng)驗即可。
          (4)平臺依托強,換平臺比較辛苦。
          興趣的由來:
          1、成功觀念不同,不虛度此生,就是我的成功。
          2、喜歡思考,挑戰(zhàn)邏輯思維。
          3、喜歡C
          C是一種能發(fā)揮思維極限的語言。關(guān)于C的精神的一些方面可以被概述成短句如下:
          相信程序員。
          不要阻止程序員做那些需要去做的。
          保持語言短小精干。
          一種方法做一個操作。
          使得它運行的夠快,盡管它并不能保證將是可移植的。
          4、喜歡底層開發(fā),討厭vb類開發(fā)工具(并不是說vb不好)。
          5、發(fā)展前景好,適合創(chuàng)業(yè),不想自己要死了的時候還是一個工程師。
          方法步驟:
          1、基礎(chǔ)知識:
          目的:能看懂硬件工作原理,但重點在嵌入式軟件,特別是操作系統(tǒng)級軟件,那將是我的優(yōu)勢。
          科目:數(shù)字電路、計算機組成原理、嵌入式微處理器結(jié)構(gòu)。
          匯編語言、C/C++、編譯原理、離散數(shù)學(xué)。
          數(shù)據(jù)結(jié)構(gòu)和算法、操作系統(tǒng)、軟件工程、網(wǎng)絡(luò)、數(shù)據(jù)庫。
          方法:雖科目眾多,但都是較簡單的基礎(chǔ),且大部分已掌握。不一定全學(xué),可根據(jù)需要選修。
          主攻書籍:the c++ programming language(一直沒時間讀)、數(shù)據(jù)結(jié)構(gòu)-C2。

          2、學(xué)習(xí)linux:
          目的:深入掌握linux系統(tǒng)。
          方法:使用linux—〉linxu系統(tǒng)編程開發(fā)—〉驅(qū)動開發(fā)和分析linux內(nèi)核。先看深,那主講原理??磶妆楹螅辞榫胺治?,對照深看,兩本交叉,深是綱,情是目。剖析則是0.11版,適合學(xué)習(xí)。最后深入代碼。
          主攻書籍:linux內(nèi)核完全剖析、unix環(huán)境高級編程、深入理解linux內(nèi)核、情景分析和源代。
          3、學(xué)習(xí)嵌入式linux:
          目的:掌握嵌入式處理器其及系統(tǒng)。
          方法:(1)嵌入式微處理器結(jié)構(gòu)與應(yīng)用:直接arm原理及匯編即可,不要重復(fù)x86。
          (2)嵌入式操作系統(tǒng)類:ucOS/II簡單,開源,可供入門。而后深入研究uClinux。
          (3)必須有塊開發(fā)板(arm9以上),有條件可參加培訓(xùn)(進步快,能認識些朋友)。
          主攻書籍:毛德操的《嵌入式系統(tǒng)》及其他arm9手冊與arm匯編指令等。

          4、深入學(xué)習(xí):
          A、數(shù)字圖像壓縮技術(shù):主要是應(yīng)掌握MPEG、mp3等編解碼算法和技術(shù)。
          B、通信協(xié)議及編程技術(shù):TCP/IP協(xié)議、802.11,Bluetooth,GPRS、GSM、CDMA等。
          C、網(wǎng)絡(luò)與信息安全技術(shù):如加密技術(shù),數(shù)字證書CA等。
          D、DSP技術(shù):Digital Signal Process,DSP處理器通過硬件實現(xiàn)數(shù)字信號處理算法。
          說明:太多細節(jié)未說明,可根據(jù)實際情況調(diào)整。重點在于1、3,不必完全按照順序作。對于學(xué)習(xí)c++,理由是c++不只是一種語言,一種工具,她還是一種藝 術(shù),一種文化,一種哲學(xué)理念、但不是拿來炫耀得東西。對于linux內(nèi)核,學(xué)習(xí)編程,讀一些優(yōu)秀代碼也是有必要的。
          注意: 要學(xué)會舉一反多,有強大的基礎(chǔ),很多東西簡單看看就能會。想成為合格的程序員,前提是必須熟練至少一種編程語言,并具有良好的邏輯思維。一定要理論結(jié)合實踐。
          不要一味鉆研技術(shù),雖然擠出時間是很難做到的,但還是要留點余地去完善其他的愛好,比如宇宙,素描、機械、管理,心理學(xué)、游戲、科幻電影。還有一些不愿意做但必須要做的!
          技術(shù)是通過編程編程在編程編出來的。永遠不要夢想一步登天,不要做浮躁的人,不要覺得路途漫上。而是要編程編程在編程,完了在編程,在編程!等機會來了在創(chuàng)業(yè)(不要相信有奇跡發(fā)生,盲目創(chuàng)業(yè)很難成功,即便成功了發(fā)展空間也不一定很大)。
          嵌入式書籍推薦

          Linux基礎(chǔ)
          1、《Linux與Unix Shell 編程指南》
          C語言基礎(chǔ)
          1、《C Primer Plus,5th Edition》【美】Stephen Prata著
          2、《The C Programming Language, 2nd Edition》【美】Brian W. Kernighan David M. Rithie(K & R)著
          3、《Advanced Programming in the UNIX Environment,2nd Edition》(APUE)
          4、《嵌入式Linux應(yīng)用程序開發(fā)詳解》
          Linux內(nèi)核
          1、《深入理解Linux內(nèi)核》(第三版)
          2、《Linux內(nèi)核源代碼情景分析》毛德操 胡希明著
          研發(fā)方向
          1、《UNIX Network Programming》(UNP)
          2、《TCP/IP詳解》
          3、《Linux內(nèi)核編程》
          4、《Linux設(shè)備驅(qū)動開發(fā)》(LDD)

          5、《Linux高級程序設(shè)計》 楊宗德著
          硬件基礎(chǔ)
          1、《ARM體系結(jié)構(gòu)與編程》杜春雷著
          2、S3C2410 Datasheet
          英語基礎(chǔ)
          1、《計算機與通信專業(yè)英語》
          系統(tǒng)教程
          1、《嵌入式系統(tǒng)――體系結(jié)構(gòu)、編程與設(shè)計》
          2、《嵌入式系統(tǒng)――采用公開源代碼和StrongARM/Xscale處理器》毛德操 胡希明著
          3、《Building Embedded Linux Systems》

          4、《嵌入式ARM系統(tǒng)原理與實例開發(fā)》 楊宗德著
          理論基礎(chǔ)
          1、《算法導(dǎo)論》
          2、《數(shù)據(jù)結(jié)構(gòu)(C語言版)》
          3、《計算機組織與體系結(jié)構(gòu)?性能分析》
          4、《深入理解計算機系統(tǒng)》【美】Randal E. Bryant David O’Hallaron著
          5、《操作系統(tǒng):精髓與設(shè)計原理》
          6、《編譯原理》
          7、《數(shù)據(jù)通信與計算機網(wǎng)絡(luò)》
          8、《數(shù)據(jù)壓縮原理與應(yīng)用》

          C語言書籍推薦

          1. The C programming language 《C程序設(shè)計語言》
          2. Pointers on C 《C和指針》
          3. C traps and pitfalls 《C陷阱與缺陷》
          4. Expert C Lanuage 《專家C編程》
          5. Writing Clean Code —–Microsoft Techiniques for Developing Bug-free C Programs
          《編程精粹–Microsoft 編寫優(yōu)質(zhì)無錯C程序秘訣》
          6. Programming Embedded Systems in C and C++ 《嵌入式系統(tǒng)編程》
          7.《C語言嵌入式系統(tǒng)編程修煉》
          8.《高質(zhì)量C++/C編程指南》林銳

          盡可能多的編碼,要學(xué)好C,不能只注重C本身。算法,架構(gòu)方式等都很重要。

          posted @ 2011-09-22 14:25 馬航 閱讀(107) | 評論 (0)編輯 收藏

          網(wǎng)上搜了N多解決方法,但是很多將log級別的,用法的,更多的是如何在logcat中設(shè)置filter進行l(wèi)og的過濾與查看,但是我遇到的問題是,模擬器怎么著都OK,但真機、手機進行開發(fā)調(diào)試的時候卻看不到log信息,這是很惱人的事情(畢竟模擬器跑起來太慢了)。

          剛開始沒有查到好的方法,就用try catch把exception打到一個alertdialog中,但是這樣只能看個大概,繞這個圈子沒用,最后還是在eoe的論壇上看到了解決辦法,恐怕原因是rom本身沒有打開log的開關(guān)

          問題表現(xiàn):連接手機與電腦后,驅(qū)動安裝正確,USB調(diào)試模式打開,在DDMS中可以看到device及其進程的信息,但是logcat中就是沒有信息輸出
          問題原因:一些rom默認關(guān)閉logcat
          問題說明:ddms中設(shè)備名字顯示為問號不影響,即adb get-serialno顯示為問號不影響.
          解決方法:
          1.需要root權(quán)限(部分rom不需要)
          2.打開logcat,并設(shè)置level,執(zhí)行命令如下(android 升級之后 adb 在 platform-tools中,不在tools中)
          adb shell
          echo 1 > /sys/kernel/logger/log_main/enable
          說明:將1寫入日志開關(guān)文件,1為開,0為關(guān)
          echo 2 >/sys/kernel/logger/log_main/priority
          說明:將代表level的2寫入優(yōu)先級文件
          3.重啟adb,如果使用eclipse,先關(guān)閉eclipse,再重啟adb,再啟動eclipse
          adb kill-server
          adb start-server
          4.此時logcat應(yīng)該可以工作了,如果仍舊不工作,則更新adb
          android update adb
          5.重復(fù)第三步,此時logcat應(yīng)該可以工作了,如果仍舊不工作,找到個人主目錄下的android目錄,如C:\Documents and Settings\Administrator\.android
          找到這個目錄下的adb_usb.ini文件,其內(nèi)容默認只有三行,全為注釋,在后面添加一行,內(nèi)容為0x12d1
          6.重復(fù)第三步,此時logcat應(yīng)該可以工作了

          轉(zhuǎn)自:http://www.gobbin.cn/2011/02/16/android-phone-logcat/

          posted @ 2011-09-06 16:10 馬航 閱讀(11242) | 評論 (0)編輯 收藏

          1.          app2sd是什么
          app2sd
          就是把應(yīng)用程序放在SD卡上。有些android手機的用戶數(shù)據(jù)分區(qū)(userdata)比較小(比如G1只有76M),dalvikcache和用戶數(shù)據(jù)就占了大半,使得安裝了幾個軟件后就沒有空間了。為了安裝更多軟件,在SD卡上劃出部分空間用于存在新軟件和數(shù)據(jù),使我們的手機可以使用更多軟件。

          2.          原理
          一般情況下都SD卡都默認分成一個windows可識別的分區(qū)(FAT)。因為有linux系統(tǒng)的權(quán)限問題,為了讓它可以存放軟件,需要把SD卡的一部分劃分成Linux的使用的ext2文件系統(tǒng),然后在開機時把此分區(qū)掛載到某處,并通過鏈接的方法,讓系統(tǒng)從SD卡中讀取軟件

          3.          實現(xiàn)

          1)         SD卡分區(qū)

          a)          使用Linux系統(tǒng)中的工具fdisk,它是命令行工具,很快很簡單

          b)         Windows下的圖形化工具
          具體步驟見http://www.3haoweb.cn/a/digital/mobile/2010/0609/2273.html

          2)         修改boot.img使得新分區(qū)在啟動時被自動掛載

          a)          說明:

                                                 i.              也可以從網(wǎng)上下載帶app2sd功能的update.zip包,升級整個系統(tǒng),但是那樣的話還要備份設(shè)置、數(shù)據(jù)、軟件太麻煩,所以我選擇修改我手機中自帶的boot.img,以最小的修改來實現(xiàn)功能

                                                ii.              修改boot.img中的initrc(系統(tǒng)啟動時運行的腳本,自動掛載SD卡的ext2分區(qū))

          b)         boot.img是什么
          boot.img
          包括了2K的文件頭,后面緊跟著是用gzip壓縮過的內(nèi)核,再后面是一個ramdisk內(nèi)存盤(系統(tǒng)基本目錄結(jié)構(gòu)的鏡像檔),然后緊跟著第二階段的載入器程序(這個載入器程序是可選的,在某些映像中或許沒有這部分)

          c)          修改本機的boot.img

                                                 i.              使用nandroid備份數(shù)據(jù)
          任何對系統(tǒng)的修改都要先備份系統(tǒng)數(shù)據(jù)

                                                ii.              從機器中取出當前的boot.img
          $ export PATH=$PATH:$ANDROID_DIR/out/host/linux-x86/bin/
          $ adb shell
          # cat /proc/mtd/
          查看boot對應(yīng)的mtdx,一般是mtd2
          # cat /dev/mtd/mtd2 > /sdcard/boot.img
          假設(shè)boot對應(yīng)mtd2
          # mkdir /system/sd1
          建立目錄以掛載分區(qū)
          # exit
          $ adb pull /sdcard/boot.img ./                 
          復(fù)制到PC

                                              iii.              解包
          下載工具split_boot.img.pl
          http://cid-f8aecd2a067a6b17.office.live.com/self.aspx/.Public/android/reference/split^_bootimg.zip
          $ ./split_boot.img.pl boot.img                  
          解包,解出內(nèi)核和ramdisk包兩部分
          $ mkdir ramdisk; cd ramdisk
          $ gzip -dc ../boot.img-ramdisk.gz |cpio -i

                                              iv.              修改啟動腳本
          $ vi init.rc 
          如果是亂碼,請使用reset命令恢復(fù)一下
          mount 最后加入
          mount ext2 /dev/block/mmcblk0p2 /system/sd1 rw

                                                v.              重新打包
          $ cd ../
          $ mkbootfs ramdisk |gzip > ramdisk-new.gz
          $ mkbooting --cmdline ‘no_console_suspend=1 console=null’ --kernel boot.img-kernel --ramdisk ramdisk-new.gz -o boot_new.img
          (mkbootfs
          mkbootimg可以android源碼包中取得,和adb在一個目錄)

                                              vi.              燒寫新包到手機
          $ adb push boot_new.img /sdcard
          $ adb shell
          # cat /dev/zero > /dev/mtd/mtd2 (
          可能找錯沒空間,沒關(guān)系)
          # flash_image boot /sdcard/boot_new.im

                                             vii.              驗證是否成功
          然后重啟手機即可,重啟后用以下命令看一下是否分區(qū)是否被掛載
          $ adb shell
          $ df 
          如果看到/system/sd1項就成功了

          3)         做鏈接,使系統(tǒng)從SD卡讀取軟件
          建立只對軟件安裝目錄做修改(/data/app),這樣撥出SD后除了后來安裝的軟件不能使用之外,不影響手機基本功能的使用
          $ adb shell
          # mkdir /system/sd1/data/
          # cd /system/sd1/data/

          # busybox cp -a /data/app ./  
          建議做
          # busybox cp -a /data/app-private ./        
          不建議做
          # busybox cp -a /data/dalvik-cache ./
          不建議做
          # busybox cp -a /data/data ./ 
          不建議做
          # rm -r /data/app
          # ln -s /system/sd1/data/app /data/app

          ……
          其它目錄以此類推
          然后重啟手機即可

          4)         注意
          由于launcher數(shù)據(jù)庫的關(guān)系,可能桌面上看不到原來的那些應(yīng)用了,不過主菜單里是有的,再建一遍快捷方式即可

          4.          參考
          http://kb.cnblogs.com/a/1743704/

          posted @ 2011-09-04 11:15 馬航 閱讀(1028) | 評論 (0)編輯 收藏

            一、 說明

          1.        下載編譯最基本的android源碼,只能在模擬器上使用,無法在真機上使用(不能生成boot.img)。這是因為沒有編譯相關(guān)機型的內(nèi)核和硬件驅(qū)動。以下介紹的是用android源碼編譯出對應(yīng)HTC G1的版本,和燒寫的過程。編譯生成的版本除相機以外,其它功能均正常,穩(wěn)定性不錯,也很順暢。

          2.        以下步驟都經(jīng)過驗證(只驗證G1手機),實驗系統(tǒng)ubuntu8.04,實驗日期2010712

          3.        關(guān)鍵字: android 2.2 froyo g1 源碼編譯

          二、 編譯

          1.        建立android源碼編譯目錄
          $ export ANDROID=/exports/android/android_2.2/
          $ mkdir -p $ANDROID
          $ cd $ANDROID

          2.        源碼下載
          $ repo init -u git://android.git.kernel.org/platform/manifest.git -b android-2.2_r1
          $ vi .repo/local_manifest.xml  #
          新建下載配置文件,用以下載內(nèi)核,編輯內(nèi)容如下

          注意:其中msm是高通芯片組,path指明下載到源碼目錄中的位置,name指明git上的項目名
          $ repo sync           # 開始下載代碼,此時需要等待較長時間

          3.        編譯內(nèi)核及無線網(wǎng)絡(luò)驅(qū)動
          $ cd $ANDROID/kernel
          $ make ARCH=arm CROSS_COMPILE=../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- msm_defconfig          #
          設(shè)定默認的msm配置

          $ make ARCH=arm CROSS_COMPILE=../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- #
          編譯內(nèi)核
          $ cd $ANDROID/system/wlan/ti/sta_dk_4_0_4_32
          $ make ARCH=arm CROSS_COMPILE=$ANDROID/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- KERNEL_DIR=$ANDROID/kerne l       
          #編譯無線網(wǎng)絡(luò)驅(qū)動
          cp $ANDROID/kernel/arch/arm/boot/zImage $ANDROID/device/htc/dream/kernel
          cp $ANDROID/system/wlan/ti/sta_dk_4_0_4_32/wlan.ko $ANDROID/device/htc/dream/wlan.ko

          4.        配置編譯選項
          vi device/htc/dream/AndroidBoard.mk     #若kernel存在,則不重新編譯kernel
          ifeq ($(TARGET_PREBUILT_KERNEL),)        
          TARGET_PREBUILT_KERNEL := $(LOCAL_PATH)/kernel
          endif

          file := $(INSTALLED_KERNEL_TARGET)
          ALL_PREBUILT += $(file)
          $(file): $(TARGET_PREBUILT_KERNEL) | $(ACP)
                  $(transform-prebuilt-to-target)

          5.        編譯android源碼
          $ cd $ANDROID
          $ vi buildspec.mk #
          加入如下內(nèi)容,以支持中文

          CUSTOM_LOCALES:=zh_CN
          $ source build/envsetup.sh
          $ lunch full_dream-userdebug        
          #指定編譯機型
          $ make -j2

          6.        以打補丁的方式加入不提供源碼的庫
          此時的系統(tǒng)可以被燒寫,但電話音樂等基本功能均不正常,需要從系統(tǒng)或其它升級包中提取出源碼中不包含的庫,以支持相應(yīng)功能。
          HTC網(wǎng)站http://developer.htc.com/adp.html
          下載名為signed-dream_devphone_userdebug-ota-14721.zip的包(一個普通的update包),并把它放在$ANDROID目錄下,并將其改名為dreaem_update.zip
          $ mv signed-dream_devphone_userdebug-ota-14721.zip dream_update.zip
          $ cd device/htc/dream
          $ ./unzip-files.sh  
          此時會提示有幾個庫找不后,后面有對應(yīng)解決辦法

          $ cd $ANDROID
          $ vi vendor/htc/dream/device_dream-vendor-blobs.mk
          刪除包含以下內(nèi)容的行,這是由于在update.zip中找不到相應(yīng)庫,為編譯通過,選去掉它們
          libGLES_qcom.so
          liblvmxipc.so
          liboemcamera.so
          libstagefrighthw.so
          $ make
          $ cp device/htc/dream/wlan.ko out/target/product/dream/system/lib/modules/wlan.ko
          #網(wǎng)卡驅(qū)動
          $ make snod        
          重新生成system.img

          三、 把編譯好的軟件燒寫到手機

          usb線連接手機到電腦,按home+power鍵將手機啟動到工程模式,按back鍵準備燒寫
          $ export PATH=$PATH:$ANDROID/out/host/linux-x86/bin        #
          把燒寫工具所在目錄加上路徑
          $ cd out/target/product/dream/
          $ fastboot flash system system.img
          $ fastboot flash boot boot.img
          $ fastboot reboot

          燒寫系統(tǒng)后第一次啟動手機需要幾分鐘,請耐心等

          四、 修改

          1.        安裝中文字體(可以在燒寫前加入,加在此處用以說明在啟動后修改系統(tǒng)的方法)
          $ adb shell
          # su            
          取得root權(quán)限

          # mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system    
          使system分區(qū)可寫
          # chmod 777 /system/fonts     
          使某個目錄有寫權(quán)限
          # exit
          # exit
          $ adb push frameworks/base/data/fonts/DroidSansFallback.ttf /system/fonts/         
          加中文字體
          $ adb reboot

          2.        支持GPRS上網(wǎng)
          添加APN即可上網(wǎng)和發(fā)彩信,詳見http://www.andbeta.com/Basics/678.html

          3.        設(shè)置帳戶
          添加帳戶時,服務(wù)器填寫m.google.com

          五、 參考

          1.        刷寫部分未詳細描述,具體請參考文檔
          http://xy0811.spaces.live.com/blog/cns!F8AECD2A067A6B17!1452.entry

          2.        源碼編譯部分未詳細描述,具體請參考文檔
          http://xy0811.spaces.live.com/blog/cns!F8AECD2A067A6B17!1364.entry


          轉(zhuǎn)自:http://blog.csdn.net/xieyan0811/article/details/5931573

          posted @ 2011-09-04 11:03 馬航 閱讀(409) | 評論 (0)編輯 收藏

          在android的設(shè)計中,谷歌設(shè)計了一套專門為嵌入式設(shè)備使用的bionic C庫,以替換原有的GUN Libc,這個精簡的bionic庫據(jù)說只有200多K,所以如果只想使用這個精簡的C庫像在linux下一樣 開發(fā)C程序,基本是不可能的。當然如果只想讓其在shell中運行還是可以做到的。

          因為編譯完的目標程序是在android下運行,就要使用交叉編譯的工具,在下面地址下載:

          http://www.codesourcery.com/gnu_toolchains/arm/download.html

          下載完之后,bin目錄下的arm-none-linux-gnueabi-gcc就是交叉編譯器了

          #include <stdio.h>
          int main() {
          	printf("nihao a\n");
          	printf("你好 啊\n");
          	return 1;
          }
          

          輸入一下命令:

          ./arm-none-linux-gnueabi-gcc hello.c -o hello -static

          -static選項在這里是必須的,否則會出現(xiàn)”not found”的錯誤。

          然后就可以把編譯好的hello傳到手機上運行了。不過這里有個前提條件,要求android機器必須是root過的,好像簡單的z4root還不行,必須使用更徹底的root方法,關(guān)于如何root,這里就不再贅述了,可以參考相關(guān)root的帖子。

          adb push hello /dev/sample/

          這里要上傳的目錄必須是root用戶所有的。

          然后就是運行程序,可以在adb shell里測試

          adb shell

          cd /dev/sample/

          chmod 777 hello

          ./hello

          或者在手機上安裝超級終端,在終端里運行

          ./hello

          posted @ 2011-09-02 09:43 馬航 閱讀(241) | 評論 (0)編輯 收藏

          http://bbs.hiapk.com/thread-553691-1-1.html

          在ubuntu下adb找不到設(shè)備的解決方法:

          需要在Windows下鎖定端口就好了

          在adb shell中輸入如下命令:

          echo 22>/sys/devices/platform/msm_hsusb_periphera/fixusb 

          posted @ 2011-09-01 17:20 馬航 閱讀(136) | 評論 (0)編輯 收藏

          一、使用git下載android內(nèi)核部分源碼

          首先新建要保存android內(nèi)核源碼的目錄

          mkdir android_kernel

          cd android_kernel

          android kernel的網(wǎng)站http://android.git.kernel.org/

          git clone git://android.git.kernel.org/kernel/common.git

          下載android內(nèi)核源碼,完成之后會看到common目錄,內(nèi)核的源碼就算下載完成了

          如果想下載某一內(nèi)核的版本,可以使用下面幾個命令:

          git branch -a // 顯示所有的分支

          git branch -r // 顯示romote端的分支

          git checkout // 檢出某一分支

          二、設(shè)置交叉編譯環(huán)境

          交叉編譯的環(huán)境在android源碼已經(jīng)存在,源碼的下載可以參考《下載編譯android源碼》。在源碼目錄的android_source/prebuilt/linux-x86/toolchain/,可以看到多個交叉編譯的工具

          mac@mac-desktop:~/works/android_dev/prebuilt/linux-x86/toolchain$ ls -all

          總用量 44

          drwxr-xr-x 9 mac mac 4096 2011-08-28 15:16 arm-eabi-4.2.1

          drwxr-xr-x 9 mac mac 4096 2011-08-28 15:16 arm-eabi-4.3.1

          drwxr-xr-x 10 mac mac 4096 2011-08-28 15:16 arm-eabi-4.4.0

          drwxr-xr-x 10 mac mac 4096 2011-08-28 15:16 arm-eabi-4.4.3

          drwxr-xr-x 10 mac mac 4096 2011-08-28 15:16 arm-linux-androideabi-4.4.x

          drwxr-xr-x 6 mac mac 4096 2011-08-28 15:16 i686-android-linux-4.4.3

          drwxr-xr-x 8 mac mac 4096 2011-08-28 15:17 i686-linux-glibc2.7-4.4.3

          drwxr-xr-x 10 mac mac 4096 2011-08-28 15:17 i686-unknown-linux-gnu-4.2.1

          drwxr-xr-x 6 mac mac 4096 2011-08-28 15:17 sh-4.3.3

          一般使用最新版本。

          三、配置編譯時的config文件

          因為編譯的鏡像是要刷到模擬器運行的,模擬器的處理器架構(gòu)是基于goldfish,所以需要下載有關(guān)goldfishconfig文件。下載方法:

          mac@mac-desktop:~/works/kernel-2.6.29$ git branch -a

          * (no branch)

          android-2.6.29

          android-2.6.36

          remotes/origin/HEAD -> origin/android-2.6.36

          remotes/origin/android-2.6.35

          remotes/origin/android-2.6.36

          remotes/origin/android-2.6.37

          remotes/origin/android-2.6.38

          remotes/origin/android-2.6.39

          remotes/origin/android-3.0

          remotes/origin/archive/android-2.6.25

          remotes/origin/archive/android-2.6.27

          remotes/origin/archive/android-2.6.29

          remotes/origin/archive/android-2.6.32

          remotes/origin/archive/android-gldfish-2.6.29

          remotes/origin/archive/android-goldfish-2.6.27

          remotes/origin/linux-bcm43xx-2.6.39

          remotes/origin/linux-wl12xx-2.6.39

          下載remotes/origin/archive/android-gldfish-2.6.29 版本:

          git checkout origin/archive/android-gldfish-2.6.29

          然后就可以到arch/arm/configs下看到goldfish_defconfig這個文件了。

          goldfish_defconfig文件拷貝到android_kernel目錄,并重命名為.config

          四、make編譯

          首先設(shè)置環(huán)境:

          export PATH=$PATH:~/android_source/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin

          然后修改Makefile

          ARCH = arm #體系結(jié)構(gòu)為arm

          CROSS_COMPILE = arm-eabi- #交叉編譯工具鏈前綴,參考/toolchain/arm-eabi-4.4.3/bin

          然后就可以make編譯了,編譯過程中會連續(xù)提示yes/not,能看懂的多注意幾眼,看不懂的一路狂按Enter,最后如果前面的設(shè)置正確,編譯完整后會看到下面的提示:

          OBJCOPY arch/arm/boot/zImage

          Kernel: arch/arm/boot/zImage is ready

          五、編譯得到zImage,用新內(nèi)核啟動模擬器

          ./emulator -avd android2.1 -kernel ~/kernel-2.6.29/arch/arm/boot/zImage

          在模擬器上查看系統(tǒng)信息:

          posted @ 2011-09-01 14:19 馬航 閱讀(1352) | 評論 (0)編輯 收藏

          現(xiàn)在使用linux的朋友越來越多了,在linux下做開發(fā)首先就是需要配置環(huán)境變量,下面以配置java環(huán)境變量為例介紹三種配置環(huán)境變量的方法。

           

          1.修改/etc/profile文件

          如果你的計算機僅僅作為開發(fā)使用時推薦使用這種方法,因為所有用戶的shell都有權(quán)使用這些環(huán)境變量,可能會給系統(tǒng)帶來安全性問題。

           

          (1)用文本編輯器打開/etc/profile

           

          (2)在profile文件末尾加入:

          JAVA_HOME=/usr/share/jdk1.5.0_05

          PATH=$JAVA_HOME/bin:$PATH

          CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

          export JAVA_HOME

          export PATH

          export CLASSPATH

           

          (3)重新登錄

           

          注解:

          a. 你要將 /usr/share/jdk1.5.0_05jdk 改為你的jdk安裝目錄

           

          b. linux下用冒號“:”來分隔路徑

           

          c. $PATH / $CLASSPATH / $JAVA_HOME 是用來引用原來的環(huán)境變量的值,在設(shè)置環(huán)境變量時特別要注意不能把原來的值給覆蓋掉了,這是一種常見的錯誤。

           

          d. CLASSPATH中當前目錄“.”不能丟,把當前目錄丟掉也是常見的錯誤。

           

          e. export是把這三個變量導(dǎo)出為全局變量。

           

          f. 大小寫必須嚴格區(qū)分。

           

          2. 修改.bashrc文件  

          這種方法更為安全,它可以把使用這些環(huán)境變量的權(quán)限控制到用戶級別,如果你需要給某個用戶權(quán)限使用這些環(huán)境變量,你只需要修改其個人用戶主目錄下的.bashrc文件就可以了。

           

          (1)用文本編輯器打開用戶目錄下的.bashrc文件

           

          (2)在.bashrc文件末尾加入:  

          set JAVA_HOME=/usr/share/jdk1.5.0_05

          export JAVA_HOME

          set PATH=$JAVA_HOME/bin:$PATH

          export PATH

          set CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

          export CLASSPATH

           

          (3)重新登錄

           

          3. 直接在shell下設(shè)置變量

          不贊成使用這種方法,因為換個shell,你的設(shè)置就無效了,因此這種方法僅僅是臨時使用,以后要使用的時候又要重新設(shè)置,比較麻煩。

           

          只需在shell終端執(zhí)行下列命令:

          export JAVA_HOME=/usr/share/jdk1.5.0_05

          export PATH=$JAVA_HOME/bin:$PATH

          export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

          posted @ 2011-09-01 11:21 馬航 閱讀(135) | 評論 (0)編輯 收藏

          剛開始學(xué)著用linux,對vi命令不是很熟,在網(wǎng)上轉(zhuǎn)接了一篇。

          vi編輯器是所有Unix及Linux系統(tǒng)下標準的編輯器,它的強大不遜色于任何最新的文本編輯器,這里只是簡單地介紹一下它的用法和一小部分指 令。由于 對Unix及Linux系統(tǒng)的任何版本,vi編輯器是完全相同的,因此您可以在其他任何介紹vi的地方進一步了解它。Vi也是Linux中最基本的文本編 輯器,學(xué)會它后,您將在Linux的世界里暢行無阻。

          1、vi的基本概念
            基本上vi可以分為三種狀態(tài),分別是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能區(qū)分如下:
              1) 命令行模式command mode)
            控制屏幕光標的移動,字符、字或行的刪除,移動復(fù)制某區(qū)段及進入Insert mode下,或者到 last line mode。
              2) 插入模式(Insert mode)
            只有在Insert mode下,才可以做文字輸入,按「ESC」鍵可回到命令行模式。
              3) 底行模式(last line mode)
            將文件保存或退出vi,也可以設(shè)置編輯環(huán)境,如尋找字符串、列出行號……等。
           
              不過一般我們在使用時把vi簡化成兩個模式,就是將底行模式(last line mode)也算入命令行模式command mode)。
          2、vi的基本操作 
          a) 進入vi
              在系統(tǒng)提示符號輸入vi及文件名稱后,就進入vi全屏幕編輯畫面:
             $ vi myfile
          不過有一點要特別注意,就是您進入vi之后,是處于「命令行模式(command mode)」,您要切換到「插入模式(Insert mode)」才能夠輸入文字。初次使用vi的人都會想先用上下左右鍵移動光標,結(jié)果電腦一直嗶嗶叫,把自己氣個半死,所以進入vi后,先不要亂動,轉(zhuǎn)換到 「插入模式(Insert mode)」再說吧!
           
          b) 切換至插入模式(Insert mode)編輯文件
            在「命令行模式(command mode)」下按一下字母「i」就可以進入「插入模式(Insert mode)」,這時候你就可以開始輸入文字了。
           
          c) Insert 的切換
            您目前處于「插入模式(Insert mode)」,您就只能一直輸入文字,如果您發(fā)現(xiàn)輸錯了字!想用光標鍵往回移動,將該字刪除,就要先按一下「ESC」鍵轉(zhuǎn)到「命令行模式(command mode)」再刪除文字。
           
          d) 退出vi及保存文件
            在「命令行模式(command mode)」下,按一下「:」冒號鍵進入「Last line mode」,例如:
          : w filename (輸入 「w filename」將文章以指定的文件名filename保存)
          : wq (輸入「wq」,存盤并退出vi)
          : q! (輸入q!, 不存盤強制退出vi)

          3、命令行模式(command mode)功能鍵
          1). 插入模式
                 按「i」切換進入插入模式「insert mode」,按"i"進入插入模式后是從光標當前位置開始輸入文件;
            按「a」進入插入模式后,是從目前光標所在位置的下一個位置開始輸入文字;
            按「o」進入插入模式后,是插入新的一行,從行首開始輸入文字。
           
          2). 從插入模式切換為命令行模式
                按「ESC」鍵。
           
          3). 移動光標
            vi可以直接用鍵盤上的光標來上下左右移動,但正規(guī)的vi是用小寫英文字母「h」、「j」、「k」、「l」,分別控制光標左、下、上、右移一格。
            按「ctrl」+「b」:屏幕往"后"移動一頁。
            按「ctrl」+「f」:屏幕往"前"移動一頁。
            按「ctrl」+「u」:屏幕往"后"移動半頁。
            按「ctrl」+「d」:屏幕往"前"移動半頁。
            按數(shù)字「0」:移到文章的開頭。
            按「G」:移動到文章的最后。
            按「$」:移動到光標所在行的"行尾"。
            按「^」:移動到光標所在行的"行首"
            按「w」:光標跳到下個字的開頭
            按「e」:光標跳到下個字的字尾
            按「b」:光標回到上個字的開頭
            按「#l」:光標移到該行的第#個位置,如:5l,56l。
           
          4). 刪除文字
            「x」:每按一次,刪除光標所在位置的"后面"一個字符。
            「#x」:例如,「6x」表示刪除光標所在位置的"后面"6個字符。
            「X」:大寫的X,每按一次,刪除光標所在位置的"前面"一個字符。
            「#X」:例如,「20X」表示刪除光標所在位置的"前面"20個字符。
            「dd」:刪除光標所在行。
            「#dd」:從光標所在行開始刪除#行
           
          5). 復(fù)制
            「yw」:將光標所在之處到字尾的字符復(fù)制到緩沖區(qū)中。
            「#yw」:復(fù)制#個字到緩沖區(qū)
            「yy」:復(fù)制光標所在行到緩沖區(qū)。
            「#yy」:例如,「6yy」表示拷貝從光標所在的該行"往下數(shù)"6行文字。
            「p」:將緩沖區(qū)內(nèi)的字符貼到光標所在位置。注意:所有與"y"有關(guān)的復(fù)制命令都必須與"p"配合才能完成復(fù)制與粘貼功能。
           
          6). 替換
            「r」:替換光標所在處的字符。
            「R」:替換光標所到之處的字符,直到按下「ESC」鍵為止。
           
          7). 回復(fù)上一次操作
            「u」:如果您誤執(zhí)行一個命令,可以馬上按下「u」,回到上一個操作。按多次"u"可以執(zhí)行多次回復(fù)。
           
          8). 更改
            「cw」:更改光標所在處的字到字尾處
            「c#w」:例如,「c3w」表示更改3個字
           
          9). 跳至指定的行
            「ctrl」+「g」列出光標所在行的行號。
            「#G」:例如,「15G」,表示移動光標至文章的第15行行首。

          4、Last line mode下命令簡介
          在使用「last line mode」之前,請記住先按「ESC」鍵確定您已經(jīng)處于「command mode」下后,再按「:」冒號即可進入「last line mode」。

          A) 列出行號

           「set nu」:輸入「set nu」后,會在文件中的每一行前面列出行號。

          B) 跳到文件中的某一行

           「#」:「#」號表示一個數(shù)字,在冒號后輸入一個數(shù)字,再按回車鍵就會跳到該行了,如輸入數(shù)字15,再回車,就會跳到文章的第15行。

          C) 查找字符

           「/關(guān)鍵字」:先按「/」鍵,再輸入您想尋找的字符,如果第一次找的關(guān)鍵字不是您想要的,可以一直按「n」會往后尋找到您要的關(guān)鍵字為止。

           「?關(guān)鍵字」:先按「?」鍵,再輸入您想尋找的字符,如果第一次找的關(guān)鍵字不是您想要的,可以一直按「n」會往前尋找到您要的關(guān)鍵字為止。

          D) 保存文件

           「w」:在冒號輸入字母「w」就可以將文件保存起來。

          E) 離開vi

           「q」:按「q」就是退出,如果無法離開vi,可以在「q」后跟一個「!」強制離開vi。

           「qw」:一般建議離開時,搭配「w」一起使用,這樣在退出的時候還可以保存文件。

          5、vi命令列表
          1、下表列出命令模式下的一些鍵的功能:

          h
          左移光標一個字符

          l
          右移光標一個字符

          k
          光標上移一行

          j
          光標下移一行

          ^
          光標移動至行首

          0
          數(shù)字"0",光標移至文章的開頭

          G
          光標移至文章的最后

          $
          光標移動至行尾

          Ctrl+f
          向前翻屏

          Ctrl+b
          向后翻屏

          Ctrl+d
          向前翻半屏

          Ctrl+u
          向后翻半屏

          i
          在光標位置前插入字符

          a
          在光標所在位置的后一個字符開始增加

          o
          插入新的一行,從行首開始輸入

          ESC
          從輸入狀態(tài)退至命令狀態(tài)

          x
          刪除光標后面的字符

          #x
          刪除光標后的#個字符

          X
          (大寫X),刪除光標前面的字符

          #X
          刪除光標前面的#個字符

          dd
          刪除光標所在的行

          #dd
          刪除從光標所在行數(shù)的#行

          yw
          復(fù)制光標所在位置的一個字

          #yw
          復(fù)制光標所在位置的#個字

          yy
          復(fù)制光標所在位置的一行

          #yy
          復(fù)制從光標所在行數(shù)的#行

          p
          粘貼

          u
          取消操作

          cw
          更改光標所在位置的一個字

          #cw
          更改光標所在位置的#個字


          2、下表列出行命令模式下的一些指令
          w filename
          儲存正在編輯的文件為filename

          wq filename
          儲存正在編輯的文件為filename,并退出vi

          q!
          放棄所有修改,退出vi

          set nu
          顯示行號

          /或?
          查找,在/后輸入要查找的內(nèi)容

          n
          與/或?一起使用,如果查找的內(nèi)容不是想要找的關(guān)鍵字,按n或向后(與/聯(lián)用)或向前(與?聯(lián)用)繼續(xù)查找,直到找到為止。


          對于第一次用vi,有幾點注意要提醒一下:
          1、 用vi打開文件后,是處于「命令行模式(command mode)」,您要切換到「插入模式(Insert mode)」才能夠輸入文字。切換方法:在「命令行模式(command mode)」下按一下字母「i」就可以進入「插入模式(Insert mode)」,這時候你就可以開始輸入文字了。
          2、編輯好后,需從插入模式切換為命令行模式才能對文件進行保存,切換方法:按「ESC」鍵。
          3、保存并退出文件:在命令模式下輸入:wq即可!(別忘了wq前面的:)

          posted @ 2011-09-01 10:34 馬航 閱讀(153) | 評論 (0)編輯 收藏

            google的android很多人都希望在gphone沒有出來之前,把它移植到相關(guān)的硬件平臺上去。網(wǎng)上看了不少文章,總的感覺是:在這一步走得最遠的就是openmoko的一個大師級別的黑客Ben “Benno” Leslie,他曾經(jīng)試圖把目前google發(fā)布的android移植到openmoko的平臺上去,并且做了10000多行代碼的嘗試。最終雖然由于 open moko采用比較老的arm 920t的內(nèi)核,而android采用較新的arm926-ej-s內(nèi)核,而且使用了新的內(nèi)核的一些新特性,導(dǎo)致移植失敗,但是anyway,他已經(jīng)做了足夠多的前期工作了,爾后的宣布成功移植android到real target板子上的人,大多是在他提供的patch的基礎(chǔ)上繼續(xù)走下去做出來的。

          下面是一些有用的參考,希望有助于對此感興趣的開發(fā)人員:
          (1)Ben “Benno” Leslie的關(guān)于andorid移植到openmoko的個人博客地址:
          http://benno.id.au/blog/

          (2)早期宣布成功移植android到zauraus-sl-c760的詳細方法描述的鏈接:
          http://euedge.com/blog/2007/12/06/google-android-runs-on-sharp-zaurus-sl-c760/

          (3)后續(xù)的根據(jù)上述先行者們的工作,成功移植android到zauraus-c3000的方法:
          http://androidzaurus.seesaa.net/article/74237419.html

          (4)本文是參考下面的wiki,接合個人的實踐寫出來的,對原文的作者表示一下感謝:
          http://wiki.droiddocs.net/Compilation_of_Android_kernel

            很羨慕這些人阿!

            不過很可惜,偶的開發(fā)板是s3c2410的,恰好是arm920t的核心的。。。估計移植上去戲不是很大,需要重寫很多代碼,畢竟偶跟benno相差得太遠太遠了,同樣是開發(fā)人員,差距咋就那么大呢?!(畢竟google僅僅開放了kernel的源代碼而已,他們需要開放的東西還很多。)

            在這里把關(guān)于android內(nèi)核編譯方法簡單寫一下,或許對希望移植內(nèi)核的朋友能有些幫助:
          (看了Benno的移植過程以后,覺得即使你能夠編譯google開放出來的內(nèi)核,意義也不是特別大,因為這個內(nèi)核中加入了為了支持qemu的很多東西,而這些代碼似乎對希望移植到真機上的朋友來說,沒有任何意義,反而是一種阻礙)。

            1)從CodeSourcery上面載用于交叉編譯的工具鏈:http://www.codesourcery.com/gnu_toolchains/arm/download.html
          我在這里選擇的是->ARM GNU/Linux,以及IA32-GNU/Linux。有文章說應(yīng)該選擇ARM EABI,我不知道了,沒有測試過,反正我選擇的這個編譯的內(nèi)核也是可以跑起來的:P

            2)下載google的android linux的內(nèi)核源代碼:http://code.google.com/p/android/downloads/list
          主要是這個文件:linux-2.6.23-android-m3-rc20.tar.gz

            3)把下載到的內(nèi)核和交叉編譯工具解壓縮,并最好把工具鏈的路徑放到PATH里面去
          解壓縮內(nèi)核:
           $ mkdir -p android
           $ cd android
           $ tar xzvf ../linux-2.6.23-android-m3-rc20.tar.gz
           會解壓出來一個叫做kernel的目錄,google的android的linux內(nèi)核就在里面了。

          解壓縮交叉編譯工具鏈:
           $ cd /usr/local/
           $ sudo cp ~/arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 .
           $ sudo tar zxvf arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
          此時會解壓出來一個叫做arm2007q3的一個目錄,這里面就是工具鏈了。

          設(shè)置一下環(huán)境變量:
           $ export PATH=$PATH:/usr/local/arm2007q3/bin
          好了,到此,基本的內(nèi)核編譯環(huán)境就搞好了。

            4)現(xiàn)在是要得到android的內(nèi)核編譯參數(shù)的配置文件的時候了,該文件需要從已經(jīng)安裝好的android的模擬器
          中得到才行。所以安裝android的sdk也是必須的,這一步不太明白的朋友可以參考我以前發(fā)的android
          命令行體驗的文章。
          首先啟動android模擬器,然后通過adb得到模擬器中提供的內(nèi)核配置文件:
           $emulator &
           $adb pull /proc/config.gz .
          這時候adb工具會連接模擬器,并從它里面下載一個叫做config.gz的文件到你的當前目錄下。
          把它拷貝到你的kernel目錄:
           $cd ~/android/kernel
           $cp ~/config.gz .
          解壓縮該文件,并重命名為.config,這一步做了就可以跳過make menuconfig之類的內(nèi)核參數(shù)設(shè)置
          動作了。
           $gunzip config.gz
           $mv config .config

            5)修改kernel目錄中的Makefile文件,用emacs或vi打開該Makefile

          修改CROSS_COMPILE變量為:
          CROSS_COMPILE=arm-none-linux-gnueabi-
          這個就是剛剛的下載和解壓的工具鏈的前綴了,旨在告訴make,在編譯的時候要使用我們的工具鏈。

          在Makefile中注釋掉LDFLAGS_BUILD_ID這個變量:
          例如將如下定義:
          LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
                            $(call ld-option, -Wl$(comma)--build-id,))
          修改為:
          LDFLAGS_BUILD_ID=
          #LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
          #                  $(call ld-option, -Wl$(comma)--build-id,))
          把它注釋掉的原因是目前android的內(nèi)核還不支持這個選項。--build-id選項,主要是用于在生成的elf
          可執(zhí)行文件中加入一個內(nèi)置的id,這樣在core dump,或者debuginfo的時候就可以很快定位這個模塊是
          哪次build的時候弄出來的。這樣就可以避免,每次都把整個文件做一遍效驗,然后才能得到該文件的是由
          哪次build產(chǎn)生的。對于內(nèi)核開發(fā)者來說,這是很不錯的想法,可以節(jié)約定位模塊版本和其影響的時間。
          目前,該功能還出于early stage的狀態(tài),未來的android或許會支持,但至少目前的版本是不支持的。
          所以,用#注釋掉即可,或者害怕不保險的話,就加入LDFLAGS_BUILD_ID=空,這樣即使編譯的時候用了,
          也只是一個空格而已。
          對這個--build-id選項感興趣的朋友,可以訪問下面的網(wǎng)址,它的作者已經(jīng)解釋得非常明白了:
          http://fedoraproject.org/wiki/Releases/FeatureBuildId

            6)終于可以開始make了。
           $ make
          不出意外的話,應(yīng)該整個過程都會非常順利,最終會在~/android/kernel/arch/arm/boot目錄下面
          生成一個zImage,這個就是我們要的內(nèi)核映像了。

            7)激動人心的時刻終于到來了,我們可以測試一下剛剛編譯出來的內(nèi)核可以不可以用了。
           $emulator -kernel ~/android/kernel/arch/arm/boot/zImage
          當看到red eye在晃來晃去,最終顯示出來android的界面的時候,一顆懸著的心總算放下了。

          android的proc里面的version如下:
          # cat version
          Linux version 2.6.23 (wayne@wayne) (gcc version 4.2.1 (CodeSourcery Sourcery G++ Lite 2007q3-51)) #1 Sat Jan 19 18:11:44 HKT 2008
          從這里就可以看出,這是自己編譯的kernel,而不是人家sdk里面自帶的kernel-qemu了。

          android自帶的sdk里面的kernel映像的version應(yīng)該是:
          # cat version
          Linux version 2.6.23-gcc3bc3b4 (arve@arvelnx.corp.google.com) (gcc version 4.2.1) #3 Tue Oct 30 16:28:18 PDT 2007
          hoho, 這里不會把這個開發(fā)者的email暴露出來了吧。。。

          android的cpuinfo如下:
          Processor       : ARM926EJ-S rev 5 (v5l)
          BogoMIPS        : 313.75
          Features        : swp half thumb fastmult vfp edsp java
          CPU implementer : 0x41
          CPU architecture: 5TEJ
          CPU variant     : 0x0
          CPU part        : 0x926
          CPU revision    : 5
          Cache type      : write-through
          Cache clean     : not required
          Cache lockdown  : not supported
          Cache format    : Harvard
          I size          : 4096
          I assoc         : 4
          I line length   : 32
          I sets          : 32
          D size          : 65536
          D assoc         : 4
          D line length   : 32
          D sets          : 512

          Hardware        : Goldfish
          Revision        : 0000
          Serial          : 0000000000000000
          不過挺奇怪的,google sdk自帶的內(nèi)核映像的BogoMIPS是3.18的,偶編譯出來的是3.13的。

          posted @ 2011-08-31 09:25 馬航 閱讀(464) | 評論 (0)編輯 收藏

          環(huán)境:

             windows xp+vmware+redhat(ubuntu)

             說明:本篇所述環(huán)境也是Android原生(Native)C(JNI)開發(fā)的環(huán)境

          1,先下載個交叉編譯工具鏈版本

            http://www.codesourcery.com/sgpp/lite/arm/portal/subscription3057 選擇最新版本進入下載頁面后,選擇Advanced Packages的IA32 GNU/Linux TAR下載后文件名為arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

          2,上傳到/usr/local/后解壓tar jxvf arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 到一個arm-2010.09

          3,測試,進入到/usr/local/arm-2010.09/bin目錄下,創(chuàng)建一個main.c文件,

          main.c內(nèi)容

          #include <stdio.h>

          int main()

          {

            int i=0;

            printf("%d\n",i);

            return;

          }

          執(zhí)行./arm-none-linux-gnueabi-gcc main.c 

          無報錯,生成a.out文件

          執(zhí)行 ./arm-none-linux-gnueabi-gcc -v

          顯示版本信息 4.5.1 

          可以啦

          修改/etc/profile文件的PATH,將當前目錄/usr/local/arm-2010.09-50/bin加入到PATH里去

          source /boot/.bashrc 使修改立即生效

          實例測試:

          進入工作目錄 /home/android/jniTest

          創(chuàng)建文件main.c,文件內(nèi)容

          #include <stdio.h>
          int main()
          {
            int i=0;
            printf("hi ym012 %d\n",i);
            return;
          }

          arm-none-linux-gnueabi-gcc -static main.c -o main
          啟動Android模擬器,先創(chuàng)建 /dev/sample目錄,再將編譯好的main上傳上去,最后將main改成可執(zhí)行的。其命令如下

          adb shell mkdir /dev/sample                        //在模擬器下創(chuàng)建一個目錄
          adb push main /dev/sample/main                //將main文件上傳到/dev/sample/main

          adb shell chmod 777 /dev/sample/main      //修改成可執(zhí)行文件

           再進入命令行模式,進入Android的模擬器的/dev/sample目錄執(zhí)行hello:

          adb shell

          #cd /dev/sample

          #./hello                          //執(zhí)行hello

          運行結(jié)果如下:

          hi ym012 0
          _______________

          總結(jié):成功了!

          posted @ 2011-08-31 09:14 馬航 閱讀(571) | 評論 (0)編輯 收藏

              最近不單只是看android開發(fā)與測試相關(guān)知識,也在了解這之外相關(guān)的信息.畢竟,自己的眼界不能太狹窄.今天我在逛一個android論壇上時候看到一個很老的帖子,轉(zhuǎn)了個關(guān)于android被從linux分支樹上移除的新聞.
              以為是假新聞來著,后面上網(wǎng)找了找,還真是搜索出一堆結(jié)果,發(fā)現(xiàn)有些比較大的IT網(wǎng)站上也有.看樣子是假不了了.
              原文上說是linux內(nèi)核開發(fā)者Greg Kroah-Hartman認為android"no one seemed to be working on it"
              想著android系統(tǒng)實際上使用了linux內(nèi)核,而linux講究的是開源,android雖然開源,確實商用的.中間可能有沖突的地方.難道是其中某些沖突引起了這樣的結(jié)果?
              最后在維基百科上android詞條(http://zh.wikipedia.org/wiki/Android)頁面的結(jié)尾部分找到了這么一段:
              "
              Android是執(zhí)行于Linux kernel之上,但并不是GNU/Linux。因為在一般GNU/Linux里支持的功能,Android大都沒有支持,包括Cairo、X11、 Alsa、FFmpeg、GTK、Pango及Glibc等都被移除掉了。Android又以bionic取代Glibc、以Skia取代Cairo、再 以opencore取代FFmpeg等等。Android為了達到商業(yè)應(yīng)用,必須移除被GNU GPL授權(quán)證所約束的部份,例如Android將驅(qū)動程序移到userspace,使得Linux driver與Linux kernel徹底分開。bionic/libc/kernel/ 并非標準的kernel header files。Android的kernel header是利用工具由Linux kernel header所產(chǎn)生的,這樣做是為了保留常數(shù)、資料結(jié)構(gòu)與宏。
              "
              可見,從最直觀上來看,android將linux內(nèi)核拿過來之后去掉了不少功能,然后通過一些手段繞開了GPL授權(quán).它的linux內(nèi)核已經(jīng)和GNU Linux相差的太大了.然而,更具體的情況是什么樣的呢?即android被移出linux分支樹的更具體的說明.

              終于找到了,摘抄在后面(摘自:http://www.ej38.com/showinfo/linux-199996.html)
          -----------------------------------------------------------------------------------------------------------------------------------------------------
              Greg Kroah-Hartman寫了一篇詳細的文章,解釋這個決定。下面就來看看,他是怎么說的,以及Android到底是一個什么樣的系統(tǒng)。
              在這之前,你最好知道Greg Kroah-Hartman是誰。他是目前LinuxKernel的核心開發(fā)人員,負責stable軟件包的發(fā)布。就是說,每一個新版本的 LinuxKernel,都是經(jīng)過他的手流出來的。此外,他還負責硬件驅(qū)動的部署。而他的手機就是HTCG1,每天都在使用。所以,他是絕對有資格談?wù)撨@ 個問題的,他的看法代表了Linux社區(qū)對Android的看法。
              首先,他指出Android和其他的Linux發(fā)行版不一樣:
          “Google has taken the Linux kernel, and nothing else from a "traditional" Linux system. Google只用了kernel,別的東西都沒用。”
              這就是說,與Ubuntu、Debian、Redhat這樣的傳統(tǒng)Linux發(fā)行版相比,只有系統(tǒng)的底層結(jié)構(gòu)是一樣的,其他東西在Android里都不一 樣,尤其是程序員的編程接口是完全不同的。因此,Android應(yīng)用程序都必須重新寫過,現(xiàn)存的Linux程序無法移植上去。所以,從嚴格意義上 說,Android是一種全新的系統(tǒng),它與Linux的距離,比Mac OS與Linux的距離還要遠。
              然后,Greg Kroah-Hartman肯定了Android這樣做的積極意義:
          “Android also solves the problem that the phone manufacturers hadbeen having for many years: a free version of Java and a unifiedapplication layer that programmers can write to that will work on allphone platforms that integrate it.
          它解決了長期令手機制造商頭痛不已的問題:業(yè)界缺乏一個開源的Java虛擬機,以及統(tǒng)一的應(yīng)用程序接口?,F(xiàn)在,程序員只要寫一次程序,就能在各種手機硬件平臺之上使用。”
              這段話解釋了,為什么Android的應(yīng)用程序,都必須用Java語言開發(fā)。因為不這樣做的話,沒法讓程序做到硬件無關(guān)。且慢,這真的是理由嗎?傳統(tǒng)的 Linux系統(tǒng),也并不依賴特定的硬件啊!只要把源代碼根據(jù)不同的平臺,分別編譯一下,同一個程序不也照樣可以在不同的硬件架構(gòu)、不同的Linux發(fā)行版 中使用嗎?那么,Android只采用kernel、只允許用java編程的真正原因,到底是什么?
              臺灣的科技網(wǎng)志MMDays一語道破真相:“Linux kernel 的版權(quán)是 GPL。這下問題來了:如果你是硬件廠商,希望你的硬件能在 Linux kernel 下運作,那么就必須要有驅(qū)動程序。如果驅(qū)動程序的程序代碼公開,等于硬件規(guī)格也公開的差不多了。許多廠商不愿意這么做,所以就提供編好的驅(qū)動程序,但不提 供原始碼。Android 的重點就是商業(yè)應(yīng)用,Google采用了一些手法來繞過這問題。他們把驅(qū)動程序移到"userspace",也就是說,把驅(qū)動程序變成在 Linux kernel 上頭跑,而不是一起跑的東西,這樣就可以避過GPL。然后,在kernel 這邊開個小門,讓本來不能直接控制到硬件的 "userspace" 程序也可以碰得到,這樣只要把"開個小門"的程序代碼公布就行啦。”看明白了嗎?
              這段話的意思是說,Google玩了一個花招,在kernel和應(yīng)用程序之間,自己做了一個中間層,這樣就既不違反GPL許可,又能不讓外界看到廠商的硬件驅(qū)動和應(yīng)用程序的源碼。
              里面的關(guān)鍵在于,Kernel和Android的許可證不一樣,前者是GPL許可證,后者是Apache SoftwareLicense(簡稱ASL)許可證。GPL許可證規(guī)定,對源碼的任何修改都必須開源,所以Android開源了,因為它修改了 Kernel。而ASL許可證規(guī)定,可以隨意使用源碼,不必開源,所以建筑在Android之上的硬件驅(qū)動和應(yīng)用程序,都可以保持封閉。為了得到更多廠商 的支持,Google有意選擇了這樣做,并且特意修改Kernel,使得原本應(yīng)該包括在kernel中的某些功能,都被轉(zhuǎn)移到了userspace之中, 因此得以避開開源。
              這樣做或許有利于推廣Android,吸引廠商和軟件開發(fā)商的加入,但是Google也放棄了構(gòu)建一個真正開源的手機系統(tǒng)的機會,從而也就不能獲得由全世 界程序員提供智慧、分享代碼、推動創(chuàng)新的好處。關(guān)于許可證問題的深入討論,請閱讀Ryan Paul的文章《Why Google chose the Apache Software License over GPLv2 for Android》。
              Google的這種做法,直接后果就是給Linux Kernel帶來了麻煩。Greg Kroah-Hartman清楚地說出了自己的不滿。
          “...any drivers written for Android hardware platforms, can not getmerged into the main kernel tree because they have dependencies on codethat only lives in Google's kernel tree, causing it to fail to build inthe kernel.orgtree.所有為Android寫的硬件驅(qū)動,都不能合并入kernel。因為它們只在Google的代碼里有效,在kernel里 根本沒法用。
              Because of this, Google has now prevented a large chunk of hardwaredrivers and platform code from ever getting merged into the main kerneltree. Effectively creating a kernel branch that a number of differentvendors are now relying on.由于這個原因,Google也從不把大量的硬件驅(qū)動程序和平臺源碼向kernel提交。實際上,它創(chuàng)造出了一個kernel的分支,大量的開發(fā)者都 依賴那個分支。”
              這就是Android干的事情:它修改了Kernel,但是又不提供修改的細節(jié),自己搞了一個封閉的系統(tǒng)。說得難聽一點,它利用了開源社區(qū),要求開源社區(qū)為它做貢獻,卻又不愿提供回報。
              所以,Linux Kernel就把Android踢出去了,真是再正常不過了。
              人們有權(quán)利質(zhì)疑,Android這樣的哲學(xué)是否正確?是否符合Google“不作惡”的口號?如果Android繼續(xù)這樣封閉下去,那么開源社區(qū)為什么要 為它免費制作軟件呢?因為我又不是在為開源社區(qū)服務(wù),而是在為Google服務(wù)。既然這樣的話,那還不如去支持iPhone呢,至少能在軟件商店里多賣一 點錢,而且喬布斯看上去也更酷一點。slashdot上有很多關(guān)于此事的討論。有人指出:“Google自己的網(wǎng)站,與微軟的網(wǎng)站一樣封閉。它開源出來的 東西,都是根據(jù)GPL許可證不得不開源的。”
              好吧,姑且不談Google本身,因為它至少不要求外界提供支持。但是Android不一樣,你不能假裝成開源系統(tǒng),騙取社區(qū)的支持,然后又干著封閉系統(tǒng)的勾當。
              Google必須做出選擇。正如Greg Kroah-Hartman最后的呼吁:
              “I really don't know. Google shows no sign of working to get their code upstream anymore.
          我真的不知道未來。Google看上去沒有任何改變代碼的跡象。
              I do hold out hope that Google does come around and works to fixtheir codebase to get it merged upstream to stop the huge blockage thatthey have now caused in a large number of embedded Linux hardwarecompanies. 我確實希望Google做出改變,把它的代碼合并進我們的代碼,彌補已經(jīng)出現(xiàn)的代碼分裂。
              I've privately offered in the past to help this work get done, andam doing again here publicly. But I need the help of the Googledevelopers to make it happen, without them, nothing can change. 我私底下已經(jīng)說過,我愿意幫助完成這項工作,在這里我再次公開這樣說。但是如果沒有Google程序員的加入,什么也不會發(fā)生。”

          posted @ 2011-08-29 13:39 馬航 閱讀(289) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 红原县| 渑池县| 保山市| 长春市| 河东区| 布尔津县| 武威市| 安宁市| 邳州市| 青海省| 徐水县| 乌海市| 梧州市| 凤冈县| 花莲县| 图片| 河东区| 娄烦县| 珲春市| 定南县| 平舆县| 庆元县| 东台市| 盐池县| 凤山县| 福州市| 红桥区| 云龙县| 修水县| 东阿县| 读书| 香格里拉县| 忻州市| 松桃| 凉山| 丹东市| 苍梧县| 皋兰县| 奉贤区| 河源市| 府谷县|