About me

Sunday 28 February 2016

Debian based package management

  • Introduction
常使用Debian-based系統的人(像是Ubuntu),常常會碰到一些套件的安裝跟管理,
對初學者來說,這地方會有點複雜,因為還會牽扯到很多相依性的問題。

這篇文章要來了解一下Ububut下的的套件管理系統,先說白一點,
「APT」:全名是Advanced Packaging Tool,也就是套件管理系統的後端,
「apt-get」:套件管理系統的前端,會去幫你注意到相依關係的套件,
「dpkg」:檔案安裝系統,不會去管你的檔案相依性,
aptitude」:有GUI的apt-get,
「dselect」:一系列apt-get script的集合包裝,有更多的功能性。

但是這篇文章我們只focus在「整個套件系統的宏觀」,「apt-get」和「dpkg」,至於其他的可能會稍微提到,
有需要的人就請自行搜尋吧。

Monday 22 February 2016

C Data Type Size

  • Introduction

之前大一時,C的教科書裏面一開始就有許多C的資料型態的介紹,
哪一個佔多少byte,可呈現的數值範圍各是多少,
這東西老師沒有特別講解,也沒有說很重要,
所以一直都以為根本不用去記它,
記它幹嘛? 隨便都可以查的到的東西@@
結果,沒去背它果然吃很多虧,
先不說實用面,就是宣告錯型態會浪費很多記憶體空間,
降低很多效能等等,
至少,很多公司面試都很喜歡考阿!!!

vim - Color Scheme

  • Introduction
大家應該都有類似的經驗,用IDE在開發程式時,背景色,文字顏色,反白跟註解的顏色....
有時候沒設定好的話,會哪個是註解哪個是有效的程式碼常常會看不清楚,
所以一個好的color scheme是很重要的,
如果你覺得本身Distribution的color scheme不合你胃口的話,
就需要套用自己比較習慣的樣式會比較有效率一點。

Sunday 21 February 2016

Samba 簡單設定 [ubuntu]

Introduction

Samba,以windows系統來說,就是設定一個網路上的芳鄰,可以兩台主機分享並修改檔案資料,
這篇文章不是要介紹整個samba概念,因為鳥哥的Linux私房菜已經介紹的很清楚了。
但是因為鳥哥的書裏面是在CentOS底下所實作,
有些細節部份跟我使用的Ubuntu不太一樣,
所以我這邊特別在把兩台電腦(Server & Client)在Ubuntu底下要怎麼設置直接寫步驟。

Wednesday 17 February 2016

u-boot 組態研究- raspberry pi 2


這份文件主要研究當uboot的組態設定成raspberry pi 2時,他的config file開了什麼compile options.


buildRoot study - 建立自己的作業系統


  • Introduction
因為想要了解整個Linux作業系統,從開機到系統穩定的中間流程,到底經歷過哪幾個步驟,
所以想要自己兜「boot-loader」,kernelroot file system
研究過程中發現了,原來早已經有組織在從事類似的專案,像是「Buildroot」,「Yocto/OpenEmbedded」
所以我就想來研究一下Buildroot的架構。

Sunday 14 February 2016

How to Build a GCC Cross-Compiler

  
  How to Build a GCC Cross-Compiler


Introduction

因為最近常用一些cross-compiling的東西,參考到很多文件,為了加深印象,所以自己實作一次。 GCC (GNU Compiler Collection),是一套程式語言編譯器,以GPL和LGPL許可證所發行的自由軟體,也是GNU tool-chain的主要組成元件之一[2]。它並不只是一個編譯器。也是一個可以讓你建立很多種編譯器的Open Source的專案。在編譯之前你可以設定好多東西,像是可以支持Multithreading, shared libraries, 或是multilib等等。 這個文章就來嘗試建立一個RA_PI2的Cross-Compiler。並且使用自己build出來的Cross-Compiler去編譯一個hello_world放到PI2上去跑。 下圖是一個簡單的示意圖: Preparation
Ubuntu 這邊使用的Host OS是Ubuntu。 Docker 使用一個完全乾淨的Container來做這件事[3], 事情會比較單純化,也會加深很多印象。 詳細Docker內容請參考網站。 安裝 sudo apt-get update $ sudo apt-get install docker.io 測試一下是否成功 $ sudo docker info 開啟Docker sudo docker run -t -i ubuntu bash 接下來所有內容都是在Docker裏面執行的。 理論上就算你一直複製貼上,應該不會錯的XD 建立建置資料夾 mkdir /tmp/pi_cross cd /tmp/pi_cross 下載套件 sudo apt-get update sudo apt-get install g++ make gawk -y sudo apt-get install vim wget xz-utils -y 將以下幾個網址存在檔案wget-list裡,有需要的話可以到網站去找最新版的。 ex. http://mirror.pregi.net/gnu/binutils/ 底下會有很多檔案。 可從distrowatch.com找到最新的「gcc」, 「glibc」, 「header」相依性。雖說目前Raspbian的官方版本比我們實作的還要舊。 http://ftpmirror.gnu.org/binutils/binutils-2.24.tar.gz http://ftpmirror.gnu.org/gcc/gcc-4.9.2/gcc-4.9.2.tar.gz https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.17.2.tar.xz http://ftpmirror.gnu.org/glibc/glibc-2.20.tar.xz http://ftpmirror.gnu.org/mpfr/mpfr-3.1.2.tar.xz http://ftpmirror.gnu.org/gmp/gmp-6.0.0a.tar.xz http://ftpmirror.gnu.org/mpc/mpc-1.0.2.tar.gz ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.12.2.tar.bz2 ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz 然後用wget一次下載所有套件 wget --input-file=wget-list --continue --directory-prefix=/tmp/pi_cross 套件說明: binutils : 包含了連結器(Linker),組譯器(assembler),和其他處理物件檔案的工具。 gcc : 內容是GNU compiler collection, 其中包含了C 和 C++編譯器。 linux-4.3 : 由linux kernel API所匯出的表頭檔,是要給Glibc用的。 Glibc : 內容是C的函式庫。 這個函式庫包含了一些記憶體配置, 檔案搜尋,開關讀寫 檔案,字串處理,數值運數等等基本函數。 mpfr : 內容是多精度數值運算的函數。 gmp : 這個套件包含了一些多精度數值運算的函式庫,建立GCC需要用到。 mpc : 也是包含一些多精度運算的函式庫,建立GCC需要用到。 ISL (opt) : cloog (opt) : 使用ISL和cloog這兩個套件可以允許一些編譯的最佳化,但是也可以不用。 套件相依性: 理論上以我的理解是這樣,只是這東西博大精深,可能在挖下去會更複雜,所以先暫時這麼理解,就誰用誰大概知道就好。 套件解壓縮 for f in *.tar*; do tar xf $f; done 取得target平台資訊 因為待回build tool chain需要有target的名字,所以先在數莓派裡下以下指令: gcc -dumpmachine 得到 『arm-linux-gnueabihf』 如果想要知道到底一個套件底下支援多少個平台,有多少的target名稱, 可以爬一下任何一個套件底下的config.sub檔。 設定環境變數 export TARGET=arm-linux-gnueabihf 建立symbolic link 這步驟將build gcc會用到的5個套件,都建立link進去。 $cd gcc-4.9.2 $ln -s ../mpfr-3.1.2 mpfr $ln -s ../gmp-6.0.0 gmp $ln -s ../mpc-1.0.2 mpc $ln -s ../isl-0.12.2 isl $ln -s ../cloog-0.18.1 cloog $cd .. 建立tool-chain路徑 這邊建立我們要放tool-chain的資料夾 $sudo mkdir -p /opt/cross 因為在build的過程中會一直參考到/opt/cross/bin這個路徑,所以記得export到環境中,有需要的話可以寫到~/.bashrc裏面。 $export PATH=/opt/cross/bin:$PATH Build Cross-Compiler
1. Binutils $mkdir build-binutils $cd build-binutils $../binutils-2.24/configure --prefix=/opt/cross --target=$TARGET $make -j32 $make install $cd .. 我們將target系統類別設定為arm-linux-gnueabihf,Binutils的組態腳本會去辨識如果target和Host是不一樣的話,會編譯成cross-assembler和cross-linker。這部份會將工具安裝到/opt/cross/bin/底下。 2. Linux Kernel Headers 這步驟會安裝linux kernel header,用這個tool-chian build出來的程式就可以在目標裝置上,進行系統呼叫。 cd linux-3.17.2 $make ARCH=arm INSTALL_HDR_PATH=/opt/cross/$TARGET headers_install cd .. 接下來的幾個步驟就是GCC和Glibc的安裝,但是這兩個套件都互相有一些相依性,所以不能一次就build完,會一部份一部份的跳著處理,如下圖所示。
3. C/C++ Compilers 這步驟會建置並且安裝GCC的 C 和 C++ Cross-compiler,並且安裝到 /opt/cross/bin 底下。 $mkdir -p build-gcc $cd build-gcc $../gcc-4.9.2/configure --prefix=/opt/cross --target=$TARGET --enable-languages=c,c++ $make -j32 all-gcc $make install-gcc $cd .. 這步驟因為我們有--target=arm-linux-gnueabihf,所以腳本就會去尋找我們step 1 所建立的Binutils cross-tools,以arm-linux-gnueabihf為前置字串(prefix)的部份(ex. arm-linux-gnueabihf-as)。而這個部份所建立出來的C/C++也會以arm-linux-gnueabihf為prefix(還是講prefix比較不會怪怪的XD)。 這邊使用--enable-languages=c,c++ ,主要是限定,因為這樣就不會去compile其他的語言的套件,像是Fortran, Java... 4. Standard C Library Headers and Startup Files 這步驟有以下重點: a. 安裝Glibc的標準C函式庫標頭檔到/opt/cross/arm-linux-gnueabihf/include。 b. 使用C編譯器(from step 3)去編譯startup file並且安裝到/opt/cross/arm-linux-gnueabihf/lib。 c. 產生libc.so和stubs.h,這己的檔案都會在step 5用到,並且再step 6被取代掉。 $mkdir -p build-glibc $cd build-glibc $../glibc-2.20/configure --prefix=/opt/cross/$TARGET --build=$MACHTYPE --host=$TARGET --target=$TARGET --with-headers=/opt/cross/$TARGET/include libc_cv_forced_unwind=yes $make install-bootstrap-headers=yes install-headers $make -j32 csu/subdir_lib $install csu/crt1.o csu/crti.o csu/crtn.o /opt/cross/$TARGET/lib $TARGET-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /opt/cross/$TARGET/lib/libc.so $touch /opt/cross/$TARGET/include/gnu/stubs.h $cd .. 『--prefix=/opt/cross/arm-linux-gnueabihf』 選項告訴組態檔應該到哪裡安裝標頭檔和函式庫。 這邊我們定義了--build, --host和--target,其實有點怪,但是資料說是官方定義的,所以照用... $MACHTYPE是一個預先定義的環境變數,主要描述目前跑這個腳本的機器。 --build=$MACHTYPE,這個選項宣告主要是step 6會用到。 這邊的--host也是個怪定義。 再Glibc的組態,--host和--targer都是描述Glibc函式庫將會再哪個系統上跑。 我們手動安裝了crtl.o, crti.o和crtn.o。 5. Compiler Support Library a. 這邊使用step 3的cross-compilers去編譯一些函式庫。 裏面包含了一些C++的例外處理。 b. 這些函式庫依賴於step 4 所建立的startup 檔案。 c. 這步驟所建立出來的函式庫會在step 6用到。 d. 這個步驟不需要重新run GCC的組態,只要直接以相同組態加上一些其他的target就好了。 $cd build-gcc $make -j32 all-target-libgcc $make install-target-libgcc $cd .. 兩個靜態函式庫 libgcc.a和 libgcc_eh.a會被安裝到/opt/cross/lib/arm-linux-gnueabihf/4.9.2/底下 一個動態函式庫libgcc_s.so會被安裝到/opt/cross/arm-linux-gnueabihf/lib底下。 6. Standard C Library 輸出靜態函式庫為libc.a,動態函式庫為libc.so。 $cd build-glibc $make -j32 $make install $cd .. 7. Standard C++ Library 終於到最後一步了,完成GCC的建置。安裝標準C++函式庫到/opt/cross/arm-linux-gnueabihf/lib/底下。這步驟也是依賴於step 6的C函式庫。 輸出靜態函式庫為libstdc++.a,動態函式庫為libstdc++.so $cd build-gcc $make -j32 $make install $cd .. Dealing with Build Errors 如果中間有一些errors的話,有可能是底下幾個原因: 1. 有缺少某個套件。 2. build的順序錯誤,別忘記這個的相依性很重要! 3. 有時候套件之間的版本組合也很重要,並不是全部拿最新的就可以用(尤其是kernel的版本!!)。 在build的時候要用log,像是 $make 2>&1 | tee build.log 這樣有error才可以參考。 GCC支援很多的組態,但是有些比較冷門的可能也還沒有人去弄過,所以就有可能有問題。 Testing the Cross-Compiler 如果一切都成功了,接下來我們就可以來測試一下。 簡單來個hello world,編譯完以後丟到raspberry pi 2上跑,並且反組看看。 ref
1.http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/ 2.Wiki-GCC 3.Docker實作入門 4. LFS Manual 5. http://wiki.osdev.org/GCC_Cross-Compiler#Deciding_on_the_target_platform