Prologue

참고로, 이 글은 오래전에 쓴 글인데, 실패한 작업이기에 비공개로 놓아 두었다가, 똑같은 작업을 하고 있는 분들에게 조금이라도 도움(?)을 줄 수 있지 않을까라는 생각에 뒤늦게 공개 전환을 합니다.

BBB에 안드로이드 Pre-image를 쉽게 올려서 성공한 글은 바로 밑에 글을 참고하세요~~~!!!

2019/12/02 - [안드로이드 임베디드/Android for the BeagleBone Black] - Beaglebone Black에 Android 이미지 올리기

 

Beaglebone Black에 Android 이미지 올리기

비글본 블랙에 안드로이드 이미지를 올리겠다. 이 이미지는 http://bbbandroid.sourceforge.net/에서 다운 받을 수 있다. 참고로 첨부 파일로 공유한다. BBBAndroid: A custom Android OS for the BeagleBone Blac..

decdream08.tistory.com

 

BeagleBone Black 안드로이드 Pre-image 올리기 (실패...)

안드로이드 소스를 컴파일 하기 전에, 이미 만들어져 있는 안드로이드 Pre-image를 올려보려고 한다.

http://processors.wiki.ti.com/index.php/BeagleBone-Android-DevKit_Guide#Preparation_of_SD_card

 

BeagleBone-Android-DevKit Guide - Texas Instruments Wiki

What is BeagleBone The BeagleBone is a low-cost, high-expansion hardware-hacker focused BeagleBoard. It is a bare-bones BeagleBoard that acts as a USB or Ethernet connected expansion companion for your current BeagleBoard and BeagleBoard-xM or works stand-

processors.wiki.ti.com

위의 문서를 차근 차근 따라서하면 쉽게 이미지를 얻을 수 있다.

BeagleBone Black용 pre-image는 http://software-dl.ti.com/dsps/dsps_public_sw/sdo_tii/TI_Android_DevKit/TI_Android_GingerBread_2_3_4_DevKit_2_1_1/exports/BeagleBone.tar.gz 

를 통해서 얻을 수 있다.

그렇게 받은 압축 파일을 다음과 같이 압축해제 한 후, mkmmc-android.sh 파일을 실행하면 파티션을 3개로 만든 후 

  1. boot - Boot Images (Boot Loaders, Boot Script and Kernel)
  2. rootfs - File system (Android GingerBread 2.3.4)
  3. data - Media Clips (Audio, Video and Images)

위의 3가지 이미지를 각각의 파티션에 복사하는 일을 한다.

그에 대한 명령어는 다음과 같다.

$ tar -xzvf BeagleBone.tar.gz

$ cd BeagleBone

$ sudo ./mkmmc-android.sh /dev/sd<device>

여기서 <device>는 MicroSD 카드를 끼웠다가 뺐을때 "lsblk" 명령어를 써서 다른 부분을 체크하여 MicroSD에 맞는 device 이름을 넣어주면 된다.

참고로, 본인은 MicroSD 카드가 sdb로 인식이 되기 때문에 다음과 같이 명령어를 완성하여 입력하였다.

$ sudo ./mkmmc-android.sh /dev/sd<device>

그런데 mkmmc-android.sh 파일을 실행할때 다음과 같은 문제점이 발생한다는 것이다.

Error의 내용을 보니 파티션이 제대로 나눠지지 않아서 발생하는 문제이다.

참고로, TI 홈페이지에 본인과 동일한 문제점을 갖고 있던 사람이 Q&A를 한 내용이 있어서 발췌를 해본다.

BegleboardXM용 sh 파일을 사용하여 문제가 해결되었다고 하는데, 나는 왜 안될까? 아마도 SD 카드에 따라서 문제가 발생하는거 같다.

https://e2e.ti.com/support/legacy_forums/embedded/android/f/509/t/72783

 

[Resolved] mkmmc-android.sh invoking error to prerare SD card - Android Forum (Read-Only Archived) - Android (Read-Only) - TI E2

 

e2e.ti.com

그래서 해결점은 단 하나. 직접 MicroSD 카드 파티션을 3개로 나누는 것이다.

각 파티션의 용량은 각 파티션에 들어갈 파일 크기 보다 크게만 잡을 것이다.

다운로드 받은 후 압축을 해제했던 준비된 파일의 용량을 다음과 같이 확인했다.

그리고 이미지를 만들때 사용할 mkmmc-android.sh 파일의 아래 내용을 참고하면 각각의 파티션 sdb1/sdb2/sdb3에 어떤 파일이 적재될 것인지를 판단 할 수 있어서, 그것을 참고로 파티션의 크기를 결정한다.

위의 내용을 통해서 $S2가 Boot_Images/MLO, $S3가 Boot_Images/u-boot.... 임을 확인할 수 있다.

이것을 참고로 mkmmc-android.sh 파일의 하기 내용도 파악하기가 쉽다.

mkmmc-android.sh 파일을 분석하여 다음과 같이 정리가 가능하다.

  1. sdb1 - MLO / u-boot.img / uImage / uEnv.txt 그리고 START_HERE가 저장 되며 전체 용량은 4.7MB이다.
  2. sdb2 - $6(Filesystem/rootfs*)이 추가 되는데 tar jxvf로 압축을 풀고 추가가 된다. 압축해제 후 용량은 88.2MB이다.
  3. sdb3 - Media_Clips가 추가되며 전체 용량은 137.1MB이다.

Window에서 DISKPART를 이용하여 MicroSD 카드의 READONLY 속성을 해제하고 기존에 있던 Partition을 모두 지웠다.

그 다음 Ubuntu에서 CParted라는 프로그램을 이용하여 다음과 같이 MicroSD 카드의 파티션을 나누었다.

작업을 마친후 Terminal에서 lsblk 명령어를 이용하여 다시 한번 확인을 해본다.

정상적으로 MicroSD 내부가 sdb1/sdb2/sdb3... 로 파티션이 잘 나눠진것을 확인 할 수 있다.

이제 mkmmc-android.sh 파일에서 파티션을 나누는 부분과 파일 시스템을 만드는 부분을 삭제하고 실행해 본다.

 

다시 경로를 변경한 후에 sh 파일을 다음과 같이 실행을 하면 정상적(?)으로 copy가 되는 것을 확인 할 수 있다.

위의 umount error는 크게 신경쓰지 않아도 될것 같다.

lsblk 명령어를 이용하여 확인을 해보면 sdb1/sdb2/sdb3이 각각 /media/mskim/boot, /media/mskim/rootfs/, /media/mskim/data로 마운트 되어있다.

실제 해당 폴더로 이동하여 파일이 있는지를 다음과 같이 확인했고, 정상적으로 이미지가 다 들어 있는 것을 확인 했다.

자... 이제 운명의 시간이다.

Beaglebone Black에 MicroSD 카드를 삽입하여 확인을 할 것이다.

그 전에, UART 통신을 하기 위해서 케이블을 보드에 삽입하고, 그 다음 Micro HDMI 케이블을 보드와 TV에 연결을 했다.

MicroSD 카드를 삽입하고 나서 보드 전원을 공급하기 위해 Micro USB 케이블을 PC와 보드사이에 연결을 했다.

 

아니 이게 웬걸... 아무리 기다려도 정상적으로 부팅이 되지 않는다. 그동안 이 작업을 위해 많은 시간을 투자 했건만, 한마디로 실패다.

그나마 배운게 있다면 안드로이드 image는 아래와 같이 구성된다는거..

  1. boot - Boot Images (Boot Loaders, Boot Script and Kernel)
  2. rootfs - File system (Android GingerBread 2.3.4)
  3. data - Media Clips (Audio, Video and Images)

2번까지가 유의미한 것이고, 3번은 테스트를 위해 필요한 데이터들이라고 보면 되겠다.

무엇이 잘못된 것인지 시간이 있을 때 다시 한번 일련의 작업들을 찬찬히 들여다 봐야겠다.

이상한 점이 있다면 #1의 Boot쪽에 Kernel 사이즈가 너무 작다는 거...

 

- 끝.

아래 글에 대한 원문은 아래 링크임을 먼저 밝혀 둡니다.

https://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree/overview

 

Introduction to the BeagleBone Black Device Tree

The BeagleBone Black uses the Device Tree to describe the hardware for the system. It also uses it in user-space for accessing GPIO's, PWM, UART, SPI and more in real-time by using device tree overlays.

learn.adafruit.com

위 원문 내용을 간략하게 필요한 부분만 추려서 정리하였습니다.


Overview

Device Tree(DT) 그리고 Device Tree Overlay(DTO)는 하나의 시스템에서 하드웨어를 설명하는 하나의 방법이다. 이에 대한 예는 그 시스템이 UART와 어떻게 인터페이스 하는지, 그 핀들이 어떻게 Mux 되는지, 어떻게 그 디바이스를 enable하는지 그리고 어떻게 그 드라이버를 사용하는지를 설명하는 것이다.

참고로, 원래 BeagleBone은 DT를 사용하지 않았지만, 그 이후 출시된 BeagleBone Black(이하 BBB)이 Linux Kernel 3.8을 사용하면서 DT를 사용하게 되었다.

다음 내용으로 부터 그 개념들을 분석 하려고 시도할 것이고, 어떻게 그리고 왜 우리가 DT를 사용하기 원하는지에 대한 예제들을 보여 줄 것이다.

Device Tree Background

ARM component들을 둘러싼 리눅스 커널 안에서 과거 몇년 동안 리눅스를 사용한 ARM 시스템에서는 많은 혼동과 갈등이 있었고 이는 ARM 보드 파일들을 대체하는 평면 Device Tree를 사용하는 새로운 ARM 보드를 이끌어 냈다.

DT와 관련해 밝혀진 하나의 이슈는 DT가 run-time 동안 그 시스템(muxing pins, enabling devices 등등)을 수정이 필요한 Open embedded system으로 디자인 되지 않았다는 것이다. 그래서 Pantelis Antoniu는 하나의 솔루션을 구현 했는데, 이것은 device tree overlay들과 cape manager를 사용하는 것이다. 그 이후, Grant Likely는 user-space로 부터 run-time 동안 DT의 수정을 허용하는 것 "존재하는 dtb data format으로 부터 직접 확장"이었던 새로운 device tree overlay format에 대해 허용하는 시스템을 제안했다.

이에 대해 더 자세한 역사는 하기를 참고.

https://github.com/jadonk/validation-scripts/tree/master/test-capemgr
https://docs.google.com/document/d/17P54kZkZO_-JtTjrFuVz-Cp_RMMg7GB_8W9JK9sLKfA/pub

 

Beaglebone and the 3.8 Kernel

Beaglebone and the 3.8 Kernel Pantelis Antoniou <panto@antoniou-consulting.com> Additional content by Tom King <ka6sox@gmail.com> Matt Porter <matt.porter@linaro.org> v1.0 Introduction The Beaglebone Black is the new addition to the Linux ARM development b</matt.porter@linaro.org></ka6sox@gmail.com></panto@antoniou-consulting.com>

docs.google.com

 

Device Tree Overlays

아래는 BBB의 UART1 device에 대한 device tree overlay이다. 이것은 P9_24와 P9_26 핀들 위의 UART1을 알맞게 enable하기 위해 필요한 알아야 할 것들 모든것을 kernel에게 말하고 있다.

한 가지 확실히 해둘것은, register offset들과 mux mode들을 밝힐 수 있는 최신 데이터를 사용하고 있는지를 확실히 해둬야 한다. 참고로, 이 링크에서 좋은 reference가 될 수 있는 BoneScript pin reference를 찾을 수 있다. https://github.com/jadonk/bonescript/blob/master/src/bone.js

 

jadonk/bonescript

Scripting tools for BeagleBone and PocketBeagle. Contribute to jadonk/bonescript development by creating an account on GitHub.

github.com

- BBB UART1 Device Tree Overlay

/*
 * Copyright (C) 2013 CircuitCo
 *
 * Virtual cape for UART1 on connector pins P9.24 P9.26
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/dts-v1/;
/plugin/;
 
/ {
   	compatible = "ti,beaglebone", "ti,beaglebone-black";
 
        /* identification */
        part-number = "BB-UART1";
        version = "00A0";
 
        /* state the resources this cape uses */
        exclusive-use =
                /* the pin header uses */
                "P9.24",        /* uart1_txd */
                "P9.26",        /* uart1_rxd */
                /* the hardware ip uses */
                "uart1";
 
        fragment@0 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        bb_uart1_pins: pinmux_bb_uart1_pins {
                                pinctrl-single,pins = <
                                        0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX) */
                                        0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX) */
                                >;
                        };
                };
        };
 
	fragment@1 {
                target = <&uart2>;	/* really uart1 */
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <&bb_uart1_pins>;
                };
        };
};

위에 표시된 overlay는 "tree structure of nodes and properties"이다.

이제 위의 oevlay를 하나씩 세분화하여 분석해본다.

첫 번째 섹션은 단지 옵션인 코멘드이지만, 주로 copyright/license 정보에 대한 그리고 이 코드가 무엇을 제안하는지를 이해하기 쉽게 하는 부분이다.

/*
 * Copyright (C) 2013 CircuitCo
 *
 * Virtual cape for UART1 on connector pins P9.24 P9.26
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

그 다음 두개 라인들은 dts 파일의 버젼과 그것을 플러그인을 설명해 준다.

/dts-v1/;
/plugin/;

그 다음 라인은 DT의 root node의 시작을 설명해 준다.

/ {

"compatible" 라인이 설명하는 것은 호환성이 가장 낮은 것 부터 시작하는, 함께 작업하기 위해 디자인된 DT overlay이다. 여기에 언급되지 않은 어떤 플랫폼들은 로드가 실패할 것이기 때문에, 우리가 지원하고 싶은 모든 플랫폼의 이름을 여기에 기입하는 것은 중요하다.

compatible = "ti,beaglebone", "ti,beaglebone-black";

다음 섹션인, part-number와 version은 알맞은 DT overlay가 로드 될 수 있게 보장하는 추가 안전 장치이다.

/* identification */
part-number = "BB-UART1";
version = "00A0";

exclusive-use 속성은 우리가 필요로 하는 자원들과 다른 어떤 overlay들이 그런 자원들을 사용하는 것을 피하기위해 기입을 하는 것이다. 이 경우, 우리는 P9.24과 P9.26을 UART1 디바이스로 사용하고 있다.

/* state the resources this cape uses */
        exclusive-use =
                /* the pin header uses */
                "P9.24",        /* uart1_txd */
                "P9.26",        /* uart1_rxd */
                /* the hardware ip uses */
                "uart1";

그 다음으로는 device tree fragment들이다. 이것들은 overlay할 타겟을 설명하고 그리고 나서 각각의 fragment는 mux pin들 이거나 또는 enable device들로 사용자 지정 할 것이다. 아래 fragment는 복잡해 보이지만 그렇게 나쁘진 않다. 첫 번째는 이 fragment의 Target이 overlay 될 예정이라는 것을 우리가 설정하고 있다는 것이다. 이 경우, pinctrl-single 드라이버와 호환되는 am33x_pinmux 이다. 어떻게 이 드라이버를 사용하지에 대한 예제들은 pinctrl-single documentation page에서 찾을 수 있다.

그 다음 라인은 __overlay__ node 그 자신이다. 해당 노드 내부에 그 첫 번째 속성은 다음 fragment(bb_uart1_pins)에 사용 될 것이고, pinctrl-single 드라이버에 의해 조정되는 그 핀들 muxing에 대한 정의를 포함한다. 우리는 그 documentation page의 설명을 통해 어떻게 설정 할지를 알 수 있다.

  • pinctrl-single에 대한 pin configuration node들은 pinctrl register offset과 pinctrl-single,pins에 사용되는 value 쌍으로서 지정된다. 오직 pinctrl-single,function-mask에 지정된 비트들만이 업데이트 된다. 예를 들어, 디바이스 하나에 대한 핀 한개 설정은 pinctrl-single,pins=<0xdc 0x118>;로 완료될 것이다.여기서 0xdc는 그 디바이스 pinctrl register에 대한 pinctrl register base address로부터의 offset이고, 0x118은 pinctrl register의 희망하는 값을 포함한다.

pinctrl-single, pins 값 블럭 내부에서, 값들의 두 행은 UART1 디바이스를 위해 그 핀들을 설정하고 있다. 이 경우, MODE0로써 P9_24는 OUTPUT(Tx)가 될 것이다. 마찬가지로 MODE0로써 P_26은 INPUT(RX)가 될 것이다. 그 pin reference for BoneScript croos-referencing에 의해 P9_24를 0x184로 설정 할 필요가 있다고 말할 수 있다.

 

fragment@0 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        bb_uart1_pins: pinmux_bb_uart1_pins {
                                pinctrl-single,pins = <
                                        0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX)  */
                                        0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX)  */
                                >;
                        };
                };
        };

마지막 fragment는 그 uart device를 활성화 한다. overlay에 대한 그 target은 uart2(실제로 uart1으로 주석처리 됨)이다. 또한 이전 프래그먼트 속성 (bb_uart1_pins)을 참조하여 pinctrl 드라이버로 활성화 된 핀을 uart 장치에 매핑합니다.

	fragment@1 {
                target = <&uart2>;	/* really uart1 */
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <&bb_uart1_pins>;
                };
        };

이것은 매우 압도적이며 실제로 모호한 것처럼 보일 수 있다. 원하는 작업에 대한 새 오버레이를 만드는 가장 쉬운 방법은 이미 수행하려는 작업에 가까운 오버레이로 시작하는 것이다. 이것을 찾기 위한 가장 좋은 장소는 /lib/firmware (Angstrom)이며, 사용을 위해 이미 만들어진 오버레이를 잘 살펴보면 된다.

Exporting and Unexporting an Overlay

다음의 예제는 디폴트 Angstrom distribution을 사용한 데모이다.

먼저, 디폴트로 이용 가능한 모든 device tree를 보기위해 /lib/firmware를 확인해라.

root@beaglebone:~# cd /lib/firmware
root@beaglebone:/lib/firmware# ls -ltr
total 888
...

여기서 몇몇의 이용 가능한 overlay들을 볼 수 있다. 그 소스(dts) 그리고 컴파일된 파일(dtbo)는 해당 디렉토릭 안에 있다.

그 내용을 보기 위해 소스파일들 중에 하나를 열어 본다. 그 overlay 그들 자신은 잘 묘사되어 있고 잘 설명되어 있다.

자 이제 이전 페이지를 통해 살펴 봤던 BB-UART1-00A0.dts 파일을 사용한다.

우리는 .dts 파일을 볼 수 있었지만, 우리는 그것이 포함한 것을 이미 알고 있다. 그곳에 우리가 이용 가능한 이미 컴파일된 .dtbo 파일이 있다는 그 사실의 이점을 이용해 보자. 미래 섹션에서 우리가 소유한 것 중 하나를 빌드하고 컴파일 할 것이다.

자, bone cape manager에 의해 활성화 된 overlay들을 볼 수 있는 곳으로 이동하자.

root@beaglebone:/lib/firmware# cd /sys/devices/bone_capemgr.*

우리가 그 숫자가 무엇인지 알 수 없으므로 위의 *가 필요하다. 그 것은 부팅 순서에 의존한다. /sys/devices/bone_capemgr.8/slots뿐만 아니라 /sys/devices/bone_capemgr.9/slots 경로를 본적이 있다. 특정 경로가 무엇인지 확인해야 한다.

다음은 그 슬롯 파일의 그 내용들을 cat 한다.

root@beaglebone:/sys/devices/bone_capemgr.8# cat slots

Anstrong installation을 매우 많이 조작해 본적이 없다면, 이것처럼 보일 것이다.

0: 54:PF--- 
1: 55:PF--- 
2: 56:PF--- 
3: 57:PF--- 
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI

BeagleBone docementaion에 의하면 최초 3 슬롯들은 그 cape들 위에서 EEPROM ID들로 할당되었다. 그 다음 2개는 boot시 로드되는 overlay들이다. 숫자 4는 Angstrom 배포판으로 부터 부팅할 가능성이 높게 빌트된 EMMC memory이다. 그 다섯번째 overlay는 HDMI component 활성화에 대한 것이다.

우리의 선호하는 UART1의 overlay처럼, 이제 또 다른 overlay를 내보낸다면, 숫자 6과 같이 리스트된 새로운 옵션을 볼 수 있을 것이다. 그 UART1 dtbo 파일 내보내기를 시도해 보자.

root@beaglebone:/sys/devices/bone_capemgr.8# echo BB-UART1 > slots

에코 출력인 "BB-UART1"을 취하고 있고, 그것을 slots 파일에 쓰고 있다. 왜냐하면, 그 overlay를 사용한 UART1에 대해 그 드라이버들과 디바이스 활성하기 위해서이다. 이제 그 overlay가 알맞게 로드되었는지 확인해 보자.

root@beaglebone:/sys/devices/bone_capemgr.8# cat slots

이제 UART1 device를 로드 하고, 준비가 됐다.

0: 54:PF--- 
1: 55:PF--- 
2: 56:PF--- 
3: 57:PF--- 
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
6: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART1

이제 우리는 UART1 디바이스 사용하기를 완료 했고, 다른 무언가에 대해 그런 핀들이 필요하다고 말해보자.

그 overlay를 제거하기 위한 하나의 방법은 BBB를 재시동 거는 것이다. 다른 방법은 overlay를 내보내는 것을 취소 하는 것이다.

다음 command를 실행하는 것으로 overlay를 내보내기 할 수 있다.

root@beaglebone:/sys/devices/bone_capemgr.8# echo -6 > slots

우리는 6번째로 리스트된 옵션을 가졌고, 그 이전에 '-'를 입력한다. 그리고 그 slots 파일에 쓴다.

한 가지 알아 두어야 할 것은 Angstrom의 6-20-2013 릴리즈에서 다양한 overlay들의 언로딩은 커널 패닉을 야기할 수 있고, capemgr를 예상할 수 없게 만들면서 ssh 세션을 잃는 것을 야기 한다. 이 문제가 해결 될때 까지 overlay들을 unload하기 위해 system을 재시동하는 것을 권장한다. 

이제 우리는 시스템 재시동은 overlay들을 unload하는 것을 야기할 것이라는 걸 알고있다. 시스템이 부트 업될때, 어떻게 하면 우리는 overlay들을 로드할 수 있을까?

이건 정말 간단한 문제이다. 우리가 필요로 하는 모든 작업은 BBB에 작은 FAT 파티션 안에 uEnv.txt에서 overlay들을 참조하는 것이다.

다음 과정은 UART1 overlay에 대해 이것을 어떻게 진행하는지 보여준다.

mkdir /mnt/boot
mount /dev/mmcblk0p1 /mnt/boot
nano /mnt/boot/uEnv.txt
#append this to the end of the single line of uEnv.txt (not on a new line):
capemgr.enable_partno=BB-UART1

 

Compiling an Overlay

이제 우리는 메뉴얼로 하나의 overlay를 활성화했다. SPI0 디바이스와 버스를 활성화하기에 대한 Adafruit BBIO 파이썬 라이브러리 안에 사용된 그리고 생성된 하나의 overlay를 취해보자. the Adafruit Github repository for Adafruit_BBIO에서 이 overlay의 최신 복사본을 찾을 수 있다.

아래는 우리가 컴파일 그리고 활성화에 사용할 SPI0에 대한 overlay 복사본이다.

/dts-v1/;
/plugin/;
 
/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";
 
    /* identification */
    part-number = "ADAFRUIT-SPI0";
 
    /* version */
    version = "00A0";
 
    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            spi0_pins_s0: spi0_pins_s0 {
                pinctrl-single,pins = <
                  0x150 0x30 /* spi0_sclk, INPUT_PULLUP | MODE0 */
                  0x154 0x30 /* spi0_d0, INPUT_PULLUP | MODE0 */
                  0x158 0x10 /* spi0_d1, OUTPUT_PULLUP | MODE0 */
                  0x15c 0x10 /* spi0_cs0, OUTPUT_PULLUP | MODE0 */
                >;
            };
        };
    };
 
    fragment@1 {
        target = <&spi0>;
        __overlay__ {
             #address-cells = <1>;
             #size-cells = <0>;
 
             status = "okay";
             pinctrl-names = "default";
             pinctrl-0 = <&spi0_pins_s0>;
 
             spidev@0 {
                 spi-max-frequency = <24000000>;
                 reg = <0>;
                 compatible = "spidev";
             };
             spidev@1 {
                 spi-max-frequency = <24000000>;
                 reg = <1>;
                 compatible = "spidev";
             };
        };
    };
};

위의 오버레이를 빠르게 살펴보면, UART1에 대한 오버레이와 같이, 동일한 패턴을 따르는 것을 볼 수 있다. 그곳에는 두 개의 fragment들이 있으며 첫 번째것은 pinctrl-single 드라이버를 사용하여 핀을 mux합니다. 우리는 SPI0 핀 중 4 개를 사용하고 모든 것을 Mode 0으로 설정한다. 그런 다음 fragment@1은 적절한 핀들로 spi0 device를 대상으로하며 그리고 'spi-max-frequency'와 같은 spi device를 사용하는 것에 특수한 다양한 parameter들을 설정한다. spi-bus documentation에서 사용 가능한 옵션을 볼 수 있다.

Home 디렉토리로 이동하고 복사 그리고 새로운 파일을 붙여 넣기 하기 위해 nano를 연다. 아래와 이름과 마찬가지로 정확하게 저장해야 한다.

root@beaglebone:/tmp# cd ~
root@beaglebone:~# nano ADAFRUIT-SPI0-00A0.dts

다음으로, 우리는 device tree overlay 컴파일된 포맷(.dtdo)안에 이 파일을 컴파일 하기 위해 명령어를 실행한다.

dtc -O dtb -o ADAFRUIT-SPI0-00A0.dtbo -b 0 -@ ADAFRUIT-SPI0-00A0.dts

컴파일은 거의 즉각적이어야하며 새롭게 컴파일 된 파일로 끝나야 한다.

root@beaglebone:~# ls -ltr
...
-rw-r--r-- 1 root root 1255 Jul 29 14:33 ADAFRUIT-SPI0-00A0.dts
-rw-r--r-- 1 root root 1042 Jul 29 14:35 ADAFRUIT-SPI0-00A0.dtbo

오버레이를 컴파일하는 데 사용되는 옵션을 분석해 보자.

우선, device tree compiler (dtc)를 사용한다. DT overlay를 컴파일하는 데 요구되는 모든 것이 최신 Angstrom 배포판에 포함되어 있다.

  • -O dtb는 출력 형식이다. device tree binaries를 출력하고 있다.
  • -o는 출력 파일 이름이다.
  • -b 0은 physical boot CPU를 설정한다. (0)
  • -@은 overlay의 동적 DT 로딩의 일부로 하나의 심볼 노드를 생성한다.

컴파일러가 누락 된-@ 플래그에 대해 complain할 경우 충분히 새로운 dtc 버전이 없는지 알 수 있다. 다음을 실행하여 dtc 업그레이드를 시도 할 수 있다 (현재 우분투에서 수행해야 할 수도 있음).

wget -c https://raw.githubusercontent.com/RobertCNelson/tools/master/pkgs/dtc.sh
chmod +x dtc.sh
./dtc.sh

Beaglebone Black(이하 BBB) 회로도는 다음 사이트에 링크가 되어 있다.

https://github.com/beagleboard/beaglebone-black/blob/master/BBB_SCH.pdf

 

beagleboard/beaglebone-black

Design and Document files for the BeagleBone Black from BeagleBoard.org - beagleboard/beaglebone-black

github.com

여기에서 미리보기 및 다운로드가 가능하다.

다운로드는 하기 그림의 빨간색 네모 안에 Download를 입력하면 된다.

 

                             

 

 

안드로이드 소스 컴파일을 하기 위한 예비 작업 중에 하기 내용 중 #3/4번을 실행할 차례이다.

  1. Python 2.5 or 2.7
  2. Java JDK 설치
  3. 빌드도구들과 git, repo 설치
  4. 안드로이드 소스 다운로드

3. 빌드도구들과 git, repo 설치

4. 안드로이드 소스 다운로드

Beglebone Black용 안드로이드 소스 다운로드를 하는 방법은 대부분 다음과 같이 www.gitorious.org/rowboat repository를 통해 소스코드를 받으라고 되어 있다.

하지만, 불행히도 해당 서버에서 더 이상 지원을 하지 않기 때문에 이 방법은 사용할 수 없다.

그래서 2가지 방법을 찾아냈다.

그 첫번째는 아래 웹에서 말하는 방법을 따르는 것이고, 다른 하나는 우리가 사용하는 Beaglebone Black에 사용하는 Main SoC인 AM3559의 chip maker인 TI 홈페이지에서 DevKit용 안드로이드 Source 코드를 받는 방법이다.

첫번째 방법을 이용하기 위해서 아래 웹페이지를 따른다.

https://adinpro.tistory.com/34

 

Beaglebone Black 보드의 안드로이드 포팅

1.개발 목표 beagleboneblack의 android를 포팅하고 이름을 자신의 영문이름으로 올바르게 포팅 되었는지 beagleboneblack을 통해 확인해 봅니다. 2. 개발 환경 window 7 home premium K, VMware Workstation11, U..

adinpro.tistory.com

http://linux.hoseo.edu/ 에서 android_source.tar.xz를 다운 받은 후 그 웹페이지에 설명되어 있는 대로 차근차근 따라가다가 한 군데에서 막혀 버렸다.

make TARGET_PRODUCT=beagleboneblock OMAPES=4.x droid -j8

위의 명령어를 시작하자 make version 문제가 발생한 것이다.

그래서 make Downgrade 하는 방법을 찾아 보았더니 다음과 같은 방법이 있다.

https://m.blog.naver.com/PostView.nhn?blogId=chandong83&logNo=220766613564&proxyReferer=https%3A%2F%2Fwww.google.com%2F

 

make 다른 버전 설치

현재 Ubuntu 16.04LTS를 사용 중이다. 그러다 보니 오래된 소스를 빌드 하려고 하면 문제가 많이 발생...

blog.naver.com

그 내용은 다음과 같다.

아래의 사이트에서 원하는 버전을 다운로드한다.

http://ftp.gnu.org/gnu/make/

다운로드한 파일을 압축을 푼 후

>tar zxvf make-3.81.tar.gz

>cd make-3.81

make-3.81>./configure 

make-3.81>make

make-3.81>sudo make install

하지만 make 명령어를 실행하게 되면 다음과 같은 Error가 발생한다.

이 Error에 대해서 검색을 해보니 다음과 같은 웹페이지를 찾을 수 있었다.

https://stackoverflow.com/questions/51675200/install-older-version-of-gnu-make-in-ubuntu-18-04

 

Install older version of gnu-make in Ubuntu 18.04

I want to install make 3.81 on Ubuntu 18.04. So I download this version of make and run ./configure and then make. But when compiling it gives me this error: ./glob/glob.c: In function ‘glob’: ....

stackoverflow.com

언급된 해법과 같이 다음 구문을 변경해 주었다.

  • Before
# include  <gnu-versions.h>

# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
  • After
# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION

수정 후 make와 make install을 실행하면 정상적으로 실행이 되고 /usr/loc/bin/ 에서 install된 make 파일을 확인 할 수 있다.

새로 설치된 make file의 이름을 다음과 같이 변경한다.

sudo mv /usr/local/bin/make /usr/local/bin/make-3.81

그리고 기존 설치된 make file의 이름도 다음과 같이 변경한다.

sudo mv /usr/bin/make /usr/bin/make-4.1

쉽게 변경할 수 있도록 update-alternatives에 추가한다.

mskim@ubuntu:~$ sudo update-alternatives --install /usr/bin/make make /usr/bin/make-4.1 1

update-alternatives: using /usr/bin/make-4.1 to provide /usr/bin/make (make) in auto mode

 

mskim@ubuntu:~$ sudo update-alternatives --install /usr/bin/make make /usr/local/bin/make-3.81 2

update-alternatives: using /usr/local/bin/make-3.81 to provide /usr/bin/make (make) in auto mode

이제 사용하고 싶은 버전을 update-alternatives --config로 변경한 다음 사용하면 된다.

 

드디어 컴파일을 다시 시작 했다.

헌데...

또 무엇인 문제인지... 어렵군 어려워...

 

 

 

그래서 안드로이드 홈페이지를 방문하여 Android 2.3.x(Gingerbread)에서 필요로 하는 Ubuntu version은 12.04(Precise)로 확인 할 수 있다.

https://source.android.com/setup/build/older-versions

 

Supporting Older Versions  |  Android Open Source Project

이 다음은 나중에 시간될때 다시 정리를 해보겠다...

To be continue...

Overview

안드로이드 소스를 컴파일 하기 위해서는 아래와 같은 준비 사항이 필요하다.

  1. Python 2.5 or 2.7
  2. Java JDK 설치
  3. 빌드도구들과 git, repo 설치
  4. 안드로이드 소스 다운로드

 

1. Python 2.5 or 2.7 설치

Ubuntu를 설치하면 기본적으로 Python이 깔려 있다.

Jave -version 명령어로 현재 Ubuntu에 깔려있는 Java 버젼을 확인 할 수 있다.

 

2. Java JDK 설치

TI에서 제공하는 BeagleBone-Android-DevKit Guide에 다음과 같이 언급되어 있다.

Android Gingerbread (2.3.4) needs Java 6 on ubuntu, whereas the previous version FroYo (2.2) was using Java 5.

http://processors.wiki.ti.com/index.php/BeagleBone-Android-DevKit_Guide#Developing_with_source_code

 

BeagleBone-Android-DevKit Guide - Texas Instruments Wiki

What is BeagleBone The BeagleBone is a low-cost, high-expansion hardware-hacker focused BeagleBoard. It is a bare-bones BeagleBoard that acts as a USB or Ethernet connected expansion companion for your current BeagleBoard and BeagleBoard-xM or works stand-

processors.wiki.ti.com

우선 Java 6를 받아 보도록 하겠다.

그런데 위와 같이 문제가 있다.

여러 웹을 돌아다니며 자료를 찾아보면서 귀한 자료를 통해 Oracle에서 이전 버젼의 JDK를 받을 수 있는 것을 확인 하였다.

그 귀한 자료는 아래와 같다.

https://naltaengi.tistory.com/42

 

도커]Ubuntu Container 에 oracle java 6 설치하기

이번 글에서는 우분투 이미지를 올린 Container 에 Oracle java6 환경을 구축해 보도록 하겠습니다. 기존 sun사의 java에서 oracle로 변경 되면서 java 설치 방법이 변경되었고, 기본 패키지로 설치가 불가능합니..

naltaengi.tistory.com

 

그리고 Oracle에서 JDK6를 받을 수 있는 곳은 아래 링크이다.

https://www.oracle.com/java/technologies/javase-java-archive-javase6-downloads.html

 

Java Archive Downloads - Java SE 6

No results found Your search did not match any results. We suggest you try the following to help find what you're looking for: - Check the spelling of your keyword search. - Use synonyms for the keyword you typed, for example, try “application” instead of

www.oracle.com

위의 홈피를 보면 JDK6에 대한 여러 가지 버젼이 존재한다.

여기서는 아래로 내려가다 보면 발견할 수 있는 jdk-6u38-linux-i586.bin을 Ubuntu에 설치하기 위해 다운로드 받는다.

아래와 같이 Ubuntu Downloads 폴더에 해당 파일을 확인 할 수 있다.

Download한 폴더로 이동을 한다.

압축파일을 풀기 전에 해당 파일에 대한 실행 권한을 부여한다.

bin 파일에 대한 압축 풀기를 실시한다.

... 중략 ...

압축 풀은 폴더를 /usr/lib/jvm/로 옮긴다.

압축을 해제한 파일들을 이용하여 /usr/lib/jvm/jdk1.6.0_38/bin/ 폴더에 JDK 설치를 시작할 것이다.

update-alternatives 명령어를 이용해 JDK를 설치한다.

sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_38/bin/javac 1

sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_38/bin/java 1

sudo update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.6.0_38/bin/javaws 1

설치한 자바가 디폴트로 사용되도록 다음과 같이 명령어를 추가한다.

sudo update-alternatives --config javac

sudo update-alternatives --config java

sudo update-alternatives --config javaws

Verify the symlinks all point to the new java location을 위해 다음 명령어를 실행한다.

그리고 Enable Java plugin을 실행 한다. 그리고 나서 자바 버젼을 확인하면 다음과 같이 확인이 가능하다.

환경변수 설정을 통해 JAVA_HOME을 다음과 같이 정의한다.

명령어를 실행하면 environment 화면이 아래와 같이 뜨고, JAVA_HOME=/usr/lib/jvm/jdk1.6.0_38을 입력하면 된다.

왼쪽 상단의 Save를 누르고 창을 닫는다. 그런데, 하기와 같이 경고 메세지가 뜨는군...

그 다음 java -v 를 입력하면 java version을 확인 할 수 있다.

 

# Install Kernel and Root File System

지금까지 SD 카드에 Boot 로더를 올린 후 파티션을 나누고 포맷을 진행 그리고 임의의 디렉토리에 마운트를 진행했다.

이제부터는 커널과 루트 파일 시스템을 Install 하는 과정이다. 

우선 커널버젼에 대한 환경변수를 설정을 해야하는데, 기존 리눅스 소스를 다운받은 bb-kernel 포더에서 kenel_version 파일을 통해 커널버젼을 다음과 같이 확인이 가능하다.

현재 사용하고 있는 커널버젼은 "4.19.72-bone-rt-r40"임을 확인 할 수 있다.

따라서 다음과 같이 환경변수 설정을 할 수가 있다.

export kernel_version=4.19.72-bone-rt-r40

 

1. Copy Root File System

루트 파일 시스템을 복사하는 과정은 다음과 같다.

~/ (루트폴더에서)

sudo tar xfvp ./*-*-*-armhf-*/armhf-rootfs-*.tar -C /media/rootfs/

sync

sudo chown root:root /media/rootfs/

sudo chmod 755 /media/rootfs/

첫번째 명령어는 기존에 우리가 "ubuntu-180.04.2-minimal-armhf-2019-02-16" 폴더에 다운로드한 우분투 파일시스템 압축 파일을, MicroSD 카드를 마운트한 /media/rootfs/ 폴더에 압축해제 하는 것이다.

...중략...

그 다음 위에 언급된 명령어들을 순차적으로 다음과 같이 진행 한다.

- sync : 메모리에 저장되어 있는 작업내용을 디스크에 저장을 한다.

- sudo chown root:root /media/rootfs/ : /media/rootfs/ 내부의 owner/group을 root로 바꾼다.

- sudo chmod 755 /media/rootfs/ : 파일의 권한을 755로 하겠다는 의미로 숫자가 각각 의미하는 것은 백/십/일의 자리는 각각 2진수 3자리로 xxx(x는 1 or 0)으로 구성이 되며, 2진수의 가장 왼쪽 자리는 읽기(Reading)로 이것이 1이 되면 10진수로 4가 되며, 2진수의 중간 자리는 쓰기(Writing)로 이것이 1이 되면 10진수로 2가 되며, 2진수의 마지막 자리는 실행(Executing)으로 이것이 1이 되면 10진수로 1이 된다. 따라서 파일 권한을 755로 하는 것에서 7이 의미하는 것은 쓰기/읽기/실행의 권한을 모두 준다는 의미이며, 5의 의미는 읽기/실행에 대해서만 권한을 준다는 것이다. 또한 755에서 백/십/일의 자리가 각각 의미하는 것은 소유자권한/그룹사용자권한/기타사용자권한을 의미한다. 결과적으로 755의 의미는 소유자권한은 읽기/쓰기/실행의 모든 권한을 부여하며, 그룹사용자권한/기타사용자권한은 읽기/실행의 권한을 부여한다는 것이다.

2. 부트이미지 이름설정

~/ (루트폴더에서)

sudo sh -c "echo 'uname_r=${kernel_version}' >> /media/rootfs/boot/uEnv.txt"

uEnv.txt 파일에서 uname_r을 설정을 한다.

3. Copy Kernel Image

~/ (루트폴더에서)

sudo cp -v ./bb-kernel/deploy/${kernel_version}.zImage /media/rootfs/boot/vmlinuz-${kernel_version}

위의 명령어는 기존에 linux kernel을 컴파일 한 zImage 파일을 MicroSD 카드에 복사를 하는 것이다.

 

4. Copy Kernel Device Tree Binaries

~/

sudo mkdir -p /media/rootfs/boot/dtbs/${kernel_version}/

sudo tar xfv ./bb-kernel/deploy/${kernel_version}-dtbs.tar.gz -C /media/rootfs/boot/dtbs/${kernel_version}/

하기와 같이 MicroSD 카드에 폴더를 만들고 기존에 다운로드했던 bb-kernel의 폴더 안의 deploy 폴더에서 디바이스 트리 바이너리 압축파일을 MicroSD 카드에 새로 만든 폴더에 압축을 푼다.

참고로, ARM에서 디바이스 트리 바이너리는 x86 계열에서의 BIOS라고 보면된다.

부트로더가 커널을 시작시키기 전에 디파이스 트리 바이너리(DTB)를 메모리 영역에 Copy를 한 후 커널을 시작한다고 한다.

하기 웹사이트에서 정보를 좀 더 자세히 볼 수 있다.

https://limit0.tistory.com/entry/%EB%94%94%EB%B0%94%EC%9D%B4%EC%8A%A4-%ED%8A%B8%EB%A6%AC%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B0%84%EB%9E%B5%ED%95%9C-%EC%84%A4%EB%AA%85

 

디바이스 트리에 대한 간략한 설명

ARM 리눅스에서 x86과 같은 bios 역할을 해 주는 것이 device tree 이다. device tree(DT) = open firmware(OF) = flattened device tree(FDT) 로 불리기도 한다. ㅇ 동작 bootloader는 kernel을 시작시키기 전에..

limit0.tistory.com

5. Copy Kernel Modules

~/ (루트폴더에서)

sudo tar xfv ./bb-kernel/deploy/${kernel_version}-modules.tar.gz -C /media/rootfs/

bb-kernel 폴더 내의 deploy 폴더에 기존에 다운로드 받았던 modules을 MicroSD카드에 압축을 해제합니다.

... 중략...

6. File Systems Table (/etc/fstab)

sudo sh -c "echo '/dev/mmcblk0p1  /  auto  errors=remount-ro  0  1' >> /media/rootfs/etc/fstab"

위의 명령어를 사용하여 파일시스템 테이블 정보를 생성한다.

7. Networking

네트워크 정보를 생성한다.

Edit: /etc/network/interfaces

sudo nano /media/rootfs/etc/network/interfaces

Add:

/etc/network/interfaces

auto lo

iface lo inet loopback

  

auto eth0

iface eth0 inet dhcp

 

8. Remove microSD/SD card

sync

sudo umount /media/rootfs

 

#1에서 SD 카드에 부트로더+리눅스커널+루트파일시스템을 넣을 준비를 모두 마쳤다.

이제 SD 카드 작업을 순차적으로 실시해보자.

 

1. DISK 환경 변수 설정

lsblk 명령어를 사용해서 현재 블럭 장치에 대해서 확인을 한다.

그 다음 SD카드를 삽입하고 동일하게 lsblk 명령어를 사용해서 다른 부분을 확인한다.

다른 부분은 보시다시피 sdb가 되겠다. sdb1이 SD카드 임을 확인 할 수 있다.

그래서 다음과 같이 환경 변수를 설정한다.

export DISK=/dev/sdb

 

2. MicroSD 카드 포맷

MicroSD 카드를 다음 명령어로 파티션을 지우고 포맷한다.

sudo dd if=/dev/zero of=${DISK} bs=1M count=10

 

3. Boot loader Install

~/ (루트폴더에서)

sudo dd if=./u-boot/MLO of=${DISK} count=1 seek=1 bs=128k

sudo dd if=./u-boot/u-boot.img of=${DISK} count=2 seek=1 bs=384k

u-boot 폴더안에서 MLO와 u-boot.img 파일의 크기를 보면 각각 92.6kB와 476.5kB 이다.

따라서 첫번째 행의 명령어를 하기와 같이 실행하면,

그 결과로, u-boot 폴더에 있는 MLO 파일이 이전에 환경 변수를 설정한 DISK위치 즉 MicroSD에 128k 크기 만큼 복사를 한다(MLO 파일이 92.6kB이므로 충분히 커버가 됨).

두번째 행의 명령어를 하기와 같이 입력.

그 결과로, u-boot 폴더에 있는 u-boot.img 파일이 위에 설명했던 내용과 동일하게 MicroSD에 384k*2 크기 만큼 복사를 한다.

4. 파티션 생성

부팅로더가 들어간 부분과 그렇지 않은 부분에 대해서 파티션을 생성해야 하는데, util-linux 버젼 별로 상이하다고 한다.

따라서 다음과 같이 먼저 버젼을 확인할 필요가 있다.

내가 사용하는 util-linux 버젼은 2.31.1이다.

아래와 같이 버젼에 따라 명령어가 다르다.

sfdisk >= 2.26.x

sudo sfdisk ${DISK} <<-__EOF__

4M,,L,*

__EOF__

sfdisk <= 2.25.x

sudo sfdisk --unit M ${DISK} <<-__EOF__

4,,L,*

__EOF__

 

sfdisk >= 2.26x를 사용해야 하므로 다음과 같이 명령어를 실행한다.

5. 파티션 포맷

mkfs.ext4에 대한 버젼을 확인 후 파티션 포맷을 실행한다.

버젼에 따라 명령어가 다른데, 현재 내가 사용하는 버젼은 1.44.1이다.

mkfs.ext4 >= 1.43

for: DISK=/dev/mmcblk0

sudo mkfs.ext4 -L rootfs -O ^metadata_csum,^64bit ${DISK}p1

  

for: DISK=/dev/sdX

sudo mkfs.ext4 -L rootfs -O ^metadata_csum,^64bit ${DISK}1

mkfs.ext4 <= 1.42

for: DISK=/dev/mmcblkX

sudo mkfs.ext4 -L rootfs ${DISK}p1

  

for: DISK=/dev/sdX

sudo mkfs.ext4 -L rootfs ${DISK}1

 

그래서 첫번째 방법을 이용하여 명령어를 다음과 같이 수행한다.

MicroSD 카드를 사용하기 위해서는 임의의 폴더를 만들고, 그곳에 마운트를 시켜야지만 MicroSD카드를 이용 가능하다.

따라서, 여기서는 /media/rootfs/ 라는 폴더를 만든 다음, SDcard에 mount한다.

sudo mkdir -p /media/rootfs/

  

for: DISK=/dev/mmcblkX

sudo mount ${DISK}p1 /media/rootfs/

  

for: DISK=/dev/sdX

sudo mount ${DISK}1 /media/rootfs/

다음과 같이 실행을 해보았다.

lsblk 명령어를 사용하여 실제 MicroSD 카드가 Mount된 이름(/media/rootfs/)을 다음과 같이 확인 할 수 있다. 

 

아래 BeagleBone Black을 이용한 이미지 만들기 가이드 설명을 참고로 만들면 된다.

https://www.digikey.com/eewiki/display/linuxonarm/BeagleBone+Black

 

BeagleBone Black - Linux on ARM - eewiki

This is a page about TI's Cortex-A8 based; BeagleBone Black. Availability Boards: BeagleBone Black at Digi-Key BeagleBone Green at Digi-Key Embest BeagleBone Black at Digi-Key BeagleBone Black Wireless at Digi-Key BeagleBone Green Wireless at Digi-Key Powe

www.digikey.com

리눅스 이미지를 BeagleBone Black에 올리기 위해서는 3가지가 필요하다.

첫째로는 부트로더(U-Boot 사용), 둘째로는 리눅스 커널(linux org 배포판), 마지막으로는 루트 파일시스템(Ubuntu 사용)이다.

# ARM Cross Compiler: GCC 설치하기

하기와 같이 wget을 이용하여 gcc를 설치한다.

그 다음 압축 파일을 풀기 위해 아래 명령어를 실행한다.

ls 명령어를 사용하여, 위와 같이 압축 파일과 압축 파일을 해제한 폴더를 확인 할 수 있다.

그 다음 컴파일러 경로를 다음과 같이 설정 한다.

여기에서 주의 할 점은 `pwd`에서 ``는 키보드에서 홑따옴표가 아닌, 물결무늬(~)라는 것이다.

컴파일러 경로를 확인하기 위해 다음과 같이 입력을 한다.

${CC}gcc --version

입력 후 아래와 같이 메세지가 출력이되면 정상적으로 경로가 입력된 것을 확인할 수 있다.

1. 부트로더(U-Boot) 다운로드 및 컴파일(빌드)

부트로더란 운영체제가 시동되기 전 실행되는 최초의 시스템 프로그램으로, 하드웨어 초기화 및 검사등의 기초적인 작업으로 커널이 올바르게 실행되기 위한 작업을 하는 프로그램이다.

U-Boot는 요즘 임베디드 시스템에서 가장 많이 쓰이는 부트로더이다.

먼저 git을 깔아야 한다. 그래서 아래 창에서 설명된 것과 같이 "sudo apt install git"을 실행하여 git을 먼저 다운로드 받는다.

ㅣㄷㅁㄱ

그리고 Y를 눌러서 install이 완료되면 하기와 같은 화면이 뜰것이다.

그 다음 U-Boot Download가 필요하다.

~/ (루트 폴더에서)

git clone https://github.com/u-boot/u-boot

cd u-boot/

git checkout v2019.04 -b tmp

하기 붉은 색 명령어들을 순차적으로 실시

여기까지 잘 따라 왔다면, 하기와 같이 u-boot 폴더에 파일이 존재하는 것을 확인 할 수 있다.

그 다음 과정은 Patch를 설치하는 과정이다.

~/u-boot (u-boot 폴더에서)

wget -c https://github.com/eewiki/u-boot-patches/raw/master/v2019.04/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch

wget -c https://github.com/eewiki/u-boot-patches/raw/master/v2019.04/0002-U-Boot-BeagleBone-Cape-Manager.patch

  

patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch

patch -p1 < 0002-U-Boot-BeagleBone-Cape-Manager.patch

위의 명령어들을 아래와 같이 순차적으로 실행.

먼저 패치를 두번 받고....

패치를 설치한다.

그 다음 작업은 설정 및 컴파일(빌드)이다.

컴파일을 하기 이전에 하기 패키지들을 install 해주어야 한다.

sudo apt install build-essential

sudo apt install bison

sudo apt install flex

그다음, make 명령어를 입력한다..

~/u-boot (u-boot 폴더에서)

make ARCH=arm CROSS_COMPILE=${CC} distclean   #1. Clean하는 작업

make ARCH=arm CROSS_COMPILE=${CC} am335x_evm_defconfig #2. Configuration 작업

make ARCH=arm CROSS_COMPILE=${CC} #3. 컴파일 작업

위의 make 명령어를 #1 ~ #3 단계까지 순차적으로 다음과 같이 입력을 한다.

#1. Clean 하는 작업

#2. Configuration 작업

#3. 컴파일 작업

중략...

컴파일까지 모두 완료가 되었다면, u-boot 폴더에 MLO와 u-boot.img 가 생성된다.

각각을  first 부트로더 second 부트로더라고 하는데, 그 이유로는 초기화 안된 초기 하드웨어의 가용할 수 있는 rom용량이 작아서 first부트로더가 second 부트로더를 올릴수 있게 최소한의 하드웨어 초기화를 하고, 초기화가 된 ram에 second 부트로더를 올려 나머지 초기화를 진행하기 때문이다.

 

2. Linux Kernel

여기에서는 kernel, module, device tree binaries를 빌드하고 deploy 폴더에 카피하는 일을 할 것이다.

Mainline>

Linux커널 다운로드:

~/ (루트폴더에서)

git clone https://github.com/RobertCNelson/bb-kernel

cd bb-kernel/

하기와 같이 명령어를 실행한다.

그 다음으로 커널 체크 아웃을 하는데, am33x-rt-v4.19 버젼을 이용할 것이다.

~/bb-kernel/

git checkout origin/am33x-rt-v4.19 -b tmp

위의 체크아웃 과정까지 거치면 bb-kernel 폴더에는 하기와 같이 파일 및 폴더가 Download 되었음을 확인 할 수 있다.

커널을 컴파일 하기 전에 다음 패키지를 install 해야 한다.

sudo apt install lzop

sudo apt-get update

sudo apt-get install lzma pkg-config libmpc-dev u-boot-tools

그 다음 커널을 컴파일(build)한다.

커널 Build:

~/bb-kernel/

./build_kernel.sh

 

중략...

중략...

위의 메세지 중에 "Your display is too small to run Menuconfig!"라는 메세지가 있다.

따라서, 컴파일을 진행하는 터미널 창을 더욱 키운 다음(최대화 후) 다시 ./build_kernel.sh를 실행하면 이상없이 잘 컴파일이 된다.

그런데, Menuconfig라는 파란색 GUI 창이 뜨며 설정을 요구한다. 다른 글에서 보니 이 설정들은 build_kernel.sh에서 잘 설정을 해 줄거라고 한다. 나중에 확인이 필요해 보인다.

여튼 정상적으로 컴파일이 완료되고 하기와 같이 마무리가 된다.

참고로 컴파일 할때 걸린 시간은 대략 2시간 정도 걸린거 같다. 정확하진 않다.

컴파일이 완료되면, kernel이라는 폴더가 생성된 것을 확인할 수 있다.

 

3. 루트 파일시스템 설치

이제 SD 카드에 이미지를 넣기 전에 마지막 단계인 루트 파일시스템 설치이다.

파일 시스템은 여러 가지(데비안, 우분투, Anstrom... 등등)가 존재하는데, 여기서는 우분투를 사용하기로 한다.

Ubuntu 18.04 LTS

User / Password : ubuntu / temppwd

먼저 Ubuntu를 다운로드한다.

Download:

~/ (루트폴더에서)

wget -c https://rcn-ee.com/rootfs/eewiki/minfs/ubuntu-18.04.2-minimal-armhf-2019-02-16.tar.xz

그 다음 단계는 Verify 단계로 다운 받은 압축 파일에 문제가 없는지를 체크 한다.

Verify:

~/ (루트폴더에서)

sha256sum ubuntu-18.04.2-minimal-armhf-2019-02-16.tar.xz

299f278ff446f0e427cb1a6650d1fa5d42d6744fff627c804f0afc918129b6b6  ubuntu-18.04.2-minimal-armhf-2019-02-16.tar.xz

이제 마지막 단계로 압축 파일을 압축 해제 하는 일이다.

Extract:

~/ (루트폴더에서)

tar xf ubuntu-18.04.2-minimal-armhf-2019-02-16.tar.xz

압축을 해제 한 후, 다음과 같이 ls 명령어로 파일 폴더 내용을 보면, ubuntu-18.04.2-minimal-armhf-2019-02-16 폴더가 생성되어 있음을 확인 할 수 있다.

다음 편에서 계속.....

+ Recent posts