AllWinner 사에서 만든 프로토타이핑 보드 NanoPi를 이용해 나만의 IoT 서버를 빌드해보자
준비물
- NanoPi NEO
- https://www.friendlyarm.com/index.php?route=product/product&product_id=132
- 세상에! 2만원도 안하는 가격에 (아두이노 정품 보드보다도 훨씬 싸다!) 무려 Quad core ARM 보드를 구할 수 있다.
- 다양한 레퍼런스와 초보자 친화적인 개발환경이 목적이 아니라면 라즈베리파이보다 훨씬 좋은 솔루션이 될 수 있겠다. (HDMI 단자가 없는 것은 함정 :))
- Ubuntu 18.04
- U-boot과 Linux Kernel을 빌드하기 위해서는 리눅스 환경이 필수적이다. 그 중에서도 설치가 가장 쉬운 Ubuntu 최신 버전으로 시작해보자.
- Cross-compiler
- Pre-built compiler (특히 arm 계열의)는 수많은 종류가 있을테고, 취향에 따라서 컴파일러도 자신의 손으로 빌드해보는 재미(?)를 느껴보고 싶다면 옵션은 더욱 다양해진다. 하지만, 누군가가 추천해주신 pre-built compiler가 있다면 수많은 옵션을 테스트해보고 시행착오를 겪는 수고스러움을 건너 뛸 수 있다 :)
- https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/
- 소스코드
- 고맙게도 NanoPi 보드류는 BSP 지원이 굉장히 잘 되고 있는 편이다. Pre-built image도 잘 구비가 되어있고, 소스코드도 Vendor provided BSP 뿐만 아니라 *Mainline 에서도 잘 지원되고 있다.
- [제조사 제공 소스코드 및 가이드]
- http://wiki.friendlyarm.com/wiki/index.php/Building_U-boot_and_Linux_for_H5/H3/H2%2B
- https://github.com/friendlyarm/u-boot
- https://github.com/friendlyarm/linux
- [Pre-built image]
- http://download.friendlyarm.com/nanopineo
환경설정
- 이제 언제 봐도 생소한 linux를 설치했으니 빌드환경 부터 갖춰야겠다.
- 한 줄 인스톨 환경 셋업 스크립트
- 행복한 코딩을 위해 깨알같은 유틸리티 설치도 빼먹지 말자
- 크로스컴파일러 툴체인을 설치한다.
- 위와 같이 입력하고 터미널을 다시 실행하면 번거로운 환경변수 작업이 다 적용되어 편하게 작업할 수 있다.
sudo apt-get install build-essential flex bison swig python-dev python3-dev
sudo apt-get install vim wget
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz
tar xvf gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz
sudo mkdir /opt/toolchains
sudo mv gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf /opt/toolchains/arm-linux-gnueabihf
echo export PATH=\$PATH:/opt/toolchains/arm-linux-gnueabihf/bin/ >> ~/.bashrc
echo export ARCH=arm >> ~/.bashrc
echo export CROSS_COMPILE=arm-linux-gnueabihf- >> ~/.bashrc
컴파일
- U-boot 소스코드를 받고 빌드해보자
- 읭? 끝났네? mainline의 위력을 실감하는 순간이다. 그런데... 너무 공부가 안되는건 함정.
- 그래서 뭐? :( 뭐가 된건지 모르겠다. 나중에 정리해보자.
- 모든 컴파일 작업이 완료되면 u-boot로 시작하는 여러 개의 파일이 생성되는데, 최종 결과물은 u-boot-sunxi-with-spl.bin 파일이다. 이걸 아래의 명령으로 SD 카드의 특정 위치에 기록하면 된다(고 한다).
- Kernel 소스코드를 받고 빌드해보자
wget ftp://ftp.denx.de/pub/u-boot/u-boot-2018.11.tar.bz2
tar xvf u-boot-2018.11.tar.bz2
cd u-boot-2018.11
make nanopi_neo_defconfig
make
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.3.tar.xz
tar xvf linux-4.19.3.tar.xz
cd linux-4.19.3
make sunxi_defconfig
make zImage dtbs
- 아 살짝 당황했다. Kernel에는 neopi가 없다;; 그런데 친절한 friendly arm wiki를 보니 sunxi_defconfig를 사용하면 된다는구나.
- *Device tree 라는 시스템 덕에 같은 CPU family라면 동일한 kernel image로 구동할 수 있다. 보드 마다 다른 설정은 모두 *.dtb라는 파일에 기록되어 있다. 따라서 kernel image는 CPU family에서 공통으로 사용하는 파일을 사용하며, 앞서 살펴본 u-boot image파일과 비슷한 이름의 .dtb 파일을 찾아서 함께 사용하면 된다.
- 이것도 마찬가지로 간단하게 컴파일 작업이 완료(시간은 무척 오래걸린다...)
부팅디스크 만들기
- 우선 파티션을 나눠야한다. 파티션 툴은 아주 오래전 DOS 시절 부터 친숙한 fdisk를 이용한다. 그간 진화한 fdisk의 복잡한 기능을 보니 세월이 느껴진다.
- fdisk의 기능도 하나 하나 익혀보고 싶지만, 당장 필요한 d, n, t, w 기능만 알아보자.
- d: 파티션을 지운다. 별 생각 없이 d <enter>만 하면 차례 대로 선택지를 보여준다.
- n: 파티션을 생성한다. 마찬가지로 단계별 질의에 답하면 된다.
- t: 파티션의 속성(type)을 변경한다. 많은 종류의 타입이 있지만, 우리가 사용할 속성은 6: FAT16 (boot 파티션 커널 이미지가 들어갈 자리) 83: Linux (rootfs, 즉 root file system이 들어갈 자리) 두 가지 뿐이다.
- p: 파티션 구성을 보여준다.
- w: 파티션 구성을 저장한다. (돌이킬 수 없다-)
- TIP
- First/last sector 위치를 물어보는데 하나의 섹터가 512byte이니, 원래 대로라면 원하는 사이즈를 만들기 위해서는 차분히 계산을 해 넣어야겠지만 +100M와 같이 단위와 + 를 조합해 넣어주면 복잡한 계산 없이 간단히 해결된다.
- lsblk명령을 사용하면 나눠진 파티션을 일목요연하게 정리해 보여준다. 좀더 자세한 내용이 필요한 경우 fdisk -l 명령을 사용한다.
- 파티션을 나누고 나면 부트섹터에는 u-boot를, 첫번째 마스터 파티션에는 kernel을, 그리고 마지막 파티션에는 root file system을 차례로 올리면 된다.
- 첫번째. u-boot
- 여기에서는 system disk 하나만 설치되어 있고, 외장형 저장 장치도 MMC card reader 하나만 있을 때의 예를 들었다. 시스템 구성에 따라 /dev/sdc 위치에 설치해야할 수도 있다. MMC카드의 device path를 꼭 확인해보자
- bs: block size, seek: # of blocks from origin -> 따라서 위 명령은 8k위치에서 부터 u-boot image를 기록하겠다는 뜻이다. CPU 구성에 따라 다르다고 하니 다른 시스템 구성에서 사용 할 경우에는 각각의 시스템에 맞는 위치에 기록해야한다.
- 두번째. kernel
- Kernel의 경우 단순한 file system에 몇 개의 이미지 파일을 넣어두면 부트로더에서 읽어서 일련의 과정을 수행해주게 되어있다. FAT16 파일은 윈도우에서도 확인해볼 수 있는데, 어떤 환경에서건 그저 필요한 파일들을 복사해주면 된다. 이를 위해 mkfs.fat 등의 유틸리티를 사용해 포멧을 해주는 것을 잊지 말자.
- 필요한 파일은 zImage (또는 uImage, Image 등의 kernel image file), *.btb 파일이다. 시스템에 맞는 파일만 복사해주면 된다.
- 주)
- 커널의 모듈 업데이트는 다음과 같이 root file system에 파일을 복사하면 된다. 이게 올바른 방법인지는 잘 모르겠다 :(
- 여기에서는 rootfs라는 볼륨이 있다고 가정했는데, 이것도 boot 볼륨과 마찬가지로 포멧하고, 필요한 파일을 적재하고 마운트도 해야한다.
- 세번째. root file system
fdisk /dev/sdb
sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1024 seek=8
sudo sync && eject /dev/sdb
sudo mkfs.fat /dev/sdb1
sudo mkdir /media/boot
sudo mount /dev/sdb1 /media/boot
sudo cp arch/arm/boot/zImage /media/boot/
sudo cp arch/arm/boot/dts/sun8i-*-nanopi-*.dtb /media/boot/
make modules
make modules_install INSTALL_MOD_PATH=/media/rootfs/
sudo dd if=rootfs.ext4 of=/dev/sdb2 bs=1M
sudo sync && eject /dev/sdb
- rootfs.ext4 라는 파일 이름으로 미리 구성된 root file system 이미지가 있다면 위와 같이 간단한 명령만으로 만들 수 있는데... 나만의 새로운 root file system 이미지를 만드는 방법은 다음 기회에 다시 알아보기로 한다.
완료
U-Boot SPL 2018.11 (Nov 29 2018 - 22:56:51 +0900)
DRAM: 256 MiB
Trying to boot from MMC1
U-Boot 2018.11 (Nov 29 2018 - 22:56:51 +0900) Allwinner Technology
CPU: Allwinner H3 (SUN8I 1680)
Model: FriendlyARM NanoPi NEO
DRAM: 256 MiB
MMC: SUNXI SD/MMC: 0
Loading Environment from FAT... *** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: phy interface0
Error: ethernet@1c30000 address not set.
eth-1: ethernet@1c30000
starting USB...
USB0: USB EHCI 1.00
USB1: USB OHCI 1.0
USB2: USB EHCI 1.00
USB3: USB OHCI 1.0
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found /extlinux/extlinux.conf
Retrieving file: /extlinux/extlinux.conf
183 bytes read in 4 ms (43.9 KiB/s)
Boot menu
1: Default
Enter choice: 1: Default
Retrieving file: /zImage
4032528 bytes read in 190 ms (20.2 MiB/s)
append: root=/dev/mmcblk0p2 console=ttyS0,115200n8
Retrieving file: /sun8i-h3-nanopi-neo.dtb
18907 bytes read in 3 ms (6 MiB/s)
## Flattened Device Tree blob at 43000000
Booting using the fdt blob at 0x43000000
EHCI failed to shut down host controller.
EHCI failed to shut down host controller.
Loading Device Tree to 49ff8000, end 49fff9da ... OK
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.19.3 (wsahn@wsahn-vm) (gcc version 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05)) #1 SMP Thu Nov 29 23:42:18 KST 2018
[ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
[ 0.000000] CPU: div instructions available: patching division code
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] OF: fdt: Machine model: FriendlyARM NanoPi NEO
[ 0.000000] Memory policy: Data cache writealloc
[ 0.000000] cma: Reserved 16 MiB at 0x4ec00000
[ 0.000000] psci: probing for conduit method from DT.
[ 0.000000] psci: Using PSCI v0.1 Function IDs from DT
[ 0.000000] random: get_random_bytes called from start_kernel+0xa0/0x3f8 with crng_init=0
[ 0.000000] percpu: Embedded 16 pages/cpu @(ptrval) s34572 r8192 d22772 u65536
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 65024
[ 0.000000] Kernel command line: root=/dev/mmcblk0p2 console=ttyS0,115200n8
[ 0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[ 0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[ 0.000000] Memory: 233228K/262144K available (6144K kernel code, 419K rwdata, 1520K rodata, 1024K init, 242K bss, 12532K reserved, 16384K cma-reserved, 0K highmem)
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[ 0.000000] vmalloc : 0xd0800000 - 0xff800000 ( 752 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xd0000000 ( 256 MB)
[ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[ 0.000000] .text : 0x(ptrval) - 0x(ptrval) (7136 kB)
[ 0.000000] .init : 0x(ptrval) - 0x(ptrval) (1024 kB)
[ 0.000000] .data : 0x(ptrval) - 0x(ptrval) ( 420 kB)
[ 0.000000] .bss : 0x(ptrval) - 0x(ptrval) ( 243 kB)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[ 0.000000] GIC: Using split EOI/Deactivate mode
[ 0.000000] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[ 0.000000] arch_timer: cp15 timer(s) running at 24.00MHz (phys).
[ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x588fe9dc0, max_idle_ns: 440795202592 ns
[ 0.000007] sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 4398046511097ns
[ 0.000018] Switching to timer-based delay loop, resolution 41ns
[ 0.000180] Console: colour dummy device 80x30
[ 0.000230] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000)
[ 0.000243] pid_max: default: 32768 minimum: 301
[ 0.000387] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.000400] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.001011] CPU: Testing write buffer coherency: ok
[ 0.001423] /cpus/cpu@0 missing clock-frequency property
[ 0.001445] /cpus/cpu@1 missing clock-frequency property
[ 0.001464] /cpus/cpu@2 missing clock-frequency property
[ 0.001483] /cpus/cpu@3 missing clock-frequency property
[ 0.001496] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[ 0.001986] Setting up static identity map for 0x40100000 - 0x40100060
[ 0.002134] rcu: Hierarchical SRCU implementation.
[ 0.002811] smp: Bringing up secondary CPUs ...
[ 0.013543] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
[ 0.024366] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
[ 0.035096] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
[ 0.035176] smp: Brought up 1 node, 4 CPUs
[ 0.035198] SMP: Total of 4 processors activated (192.00 BogoMIPS).
[ 0.035204] CPU: All CPU(s) started in HYP mode.
[ 0.035210] CPU: Virtualization extensions available.
[ 0.036036] devtmpfs: initialized
[ 0.040169] VFP support v0.3: implementor 41 architecture 2 part 30 variant 7 rev 5
[ 0.040381] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.040403] futex hash table entries: 1024 (order: 4, 65536 bytes)
[ 0.041241] pinctrl core: initialized pinctrl subsystem
[ 0.042143] NET: Registered protocol family 16
[ 0.043481] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.044480] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers.
[ 0.044493] hw-breakpoint: maximum watchpoint size is 8 bytes.
[ 0.056651] SCSI subsystem initialized
[ 0.057143] usbcore: registered new interface driver usbfs
[ 0.057188] usbcore: registered new interface driver hub
[ 0.057252] usbcore: registered new device driver usb
[ 0.057440] pps_core: LinuxPPS API ver. 1 registered
[ 0.057448] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti
[ 0.057467] PTP clock support registered
[ 0.057676] Advanced Linux Sound Architecture Driver Initialized.
[ 0.058447] clocksource: Switched to clocksource arch_sys_counter
[ 0.065647] NET: Registered protocol family 2
[ 0.066146] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 6144 bytes)
[ 0.066183] TCP established hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.066222] TCP bind hash table entries: 2048 (order: 2, 16384 bytes)
[ 0.066258] TCP: Hash tables configured (established 2048 bind 2048)
[ 0.066366] UDP hash table entries: 256 (order: 1, 8192 bytes)
[ 0.066413] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
[ 0.066600] NET: Registered protocol family 1
[ 0.067089] RPC: Registered named UNIX socket transport module.
[ 0.067101] RPC: Registered udp transport module.
[ 0.067107] RPC: Registered tcp transport module.
[ 0.067113] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 0.068813] workingset: timestamp_bits=30 max_order=16 bucket_order=0
[ 0.075211] NFS: Registering the id_resolver key type
[ 0.075251] Key type id_resolver registered
[ 0.075258] Key type id_legacy registered
[ 0.076230] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 248)
[ 0.076245] io scheduler noop registered
[ 0.076253] io scheduler deadline registered
[ 0.076404] io scheduler cfq registered (default)
[ 0.076413] io scheduler mq-deadline registered
[ 0.076420] io scheduler kyber registered
[ 0.077168] sun4i-usb-phy 1c19400.phy: Couldn't request ID GPIO
[ 0.080857] sun8i-h3-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver
[ 0.082428] sun8i-h3-r-pinctrl 1f02c00.pinctrl: initialized sunXi PIO driver
[ 0.130453] Serial: 8250/16550 driver, 8 ports, IRQ sharing disabled
[ 0.132794] console [ttyS0] disabled
[ 0.152956] 1c28000.serial: ttyS0 at MMIO 0x1c28000 (irq = 35, base_baud = 1500000) is a U6_16550A
[ 0.796602] console [ttyS0] enabled
[ 0.802999] libphy: Fixed MDIO Bus: probed
[ 0.807101] CAN device driver interface
[ 0.811443] dwmac-sun8i 1c30000.ethernet: PTP uses main clock
[ 0.817217] dwmac-sun8i 1c30000.ethernet: No regulator found
[ 0.823276] dwmac-sun8i 1c30000.ethernet: Current syscon value is not the default 148000 (expect 58000)
[ 0.832708] dwmac-sun8i 1c30000.ethernet: No HW DMA feature register supported
[ 0.839936] dwmac-sun8i 1c30000.ethernet: RX Checksum Offload Engine supported
[ 0.847148] dwmac-sun8i 1c30000.ethernet: COE Type 2
[ 0.852118] dwmac-sun8i 1c30000.ethernet: TX Checksum insertion supported
[ 0.858910] dwmac-sun8i 1c30000.ethernet: Normal descriptors
[ 0.864562] dwmac-sun8i 1c30000.ethernet: Chain mode enabled
[ 0.870379] libphy: stmmac: probed
[ 0.874265] dwmac-sun8i 1c30000.ethernet: Found internal PHY node
[ 0.880486] libphy: mdio_mux: probed
[ 0.884073] dwmac-sun8i 1c30000.ethernet: Switch mux to internal PHY
[ 0.890458] dwmac-sun8i 1c30000.ethernet: Powering internal PHY
[ 0.897370] libphy: mdio_mux: probed
[ 0.901286] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.907806] ehci-platform: EHCI generic platform driver
[ 0.913207] ehci-platform 1c1a000.usb: EHCI Host Controller
[ 0.918812] ehci-platform 1c1a000.usb: new USB bus registered, assigned bus number 1
[ 0.926870] ehci-platform 1c1a000.usb: irq 26, io mem 0x01c1a000
[ 0.968437] ehci-platform 1c1a000.usb: USB 2.0 started, EHCI 1.00
[ 0.975260] hub 1-0:1.0: USB hub found
[ 0.979059] hub 1-0:1.0: 1 port detected
[ 0.983600] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[ 0.989815] ohci-platform: OHCI generic platform driver
[ 0.995182] ohci-platform 1c1a400.usb: Generic Platform OHCI controller
[ 1.001821] ohci-platform 1c1a400.usb: new USB bus registered, assigned bus number 2
[ 1.009747] ohci-platform 1c1a400.usb: irq 27, io mem 0x01c1a400
[ 1.083094] hub 2-0:1.0: USB hub found
[ 1.086870] hub 2-0:1.0: 1 port detected
[ 1.094516] sun6i-rtc 1f00000.rtc: rtc core: registered rtc-sun6i as rtc0
[ 1.101326] sun6i-rtc 1f00000.rtc: RTC enabled
[ 1.105922] i2c /dev entries driver
[ 1.110343] sunxi-wdt 1c20ca0.watchdog: Watchdog enabled (timeout=16 sec, nowayout=0)
[ 1.119628] sunxi-mmc 1c0f000.mmc: Linked as a consumer to regulator.2
[ 1.126719] sunxi-mmc 1c0f000.mmc: Got CD GPIO
[ 1.156525] sunxi-mmc 1c0f000.mmc: initialized, max. request size: 16384 KB
[ 1.164723] usbcore: registered new interface driver usbhid
[ 1.170322] usbhid: USB HID core driver
[ 1.175392] NET: Registered protocol family 17
[ 1.179879] can: controller area network core (rev 20170425 abi 9)
[ 1.186141] NET: Registered protocol family 29
[ 1.190596] can: raw protocol (rev 20170425)
[ 1.194863] can: broadcast manager protocol (rev 20170425 t)
[ 1.200536] can: netlink gateway (rev 20170425) max_hops=1
[ 1.206231] Key type dns_resolver registered
[ 1.210590] Registering SWP/SWPB emulation handler
[ 1.224181] ehci-platform 1c1d000.usb: EHCI Host Controller
[ 1.229847] ehci-platform 1c1d000.usb: new USB bus registered, assigned bus number 3
[ 1.238044] ehci-platform 1c1d000.usb: irq 28, io mem 0x01c1d000
[ 1.266176] mmc0: host does not support reading read-only switch, assuming write-enable
[ 1.268438] ehci-platform 1c1d000.usb: USB 2.0 started, EHCI 1.00
[ 1.279662] mmc0: new high speed SDHC card at address aaaa
[ 1.281101] hub 3-0:1.0: USB hub found
[ 1.286843] mmcblk0: mmc0:aaaa SU04G 3.69 GiB
[ 1.289665] hub 3-0:1.0: 1 port detected
[ 1.299097] ohci-platform 1c1d400.usb: Generic Platform OHCI controller
[ 1.301341] mmcblk0: p1 p2
[ 1.305745] ohci-platform 1c1d400.usb: new USB bus registered, assigned bus number 4
[ 1.316708] ohci-platform 1c1d400.usb: irq 29, io mem 0x01c1d400
[ 1.393178] hub 4-0:1.0: USB hub found
[ 1.396971] hub 4-0:1.0: 1 port detected
[ 1.401783] usb_phy_generic usb_phy_generic.0.auto: usb_phy_generic.0.auto supply vcc not found, using dummy regulator
[ 1.412607] usb_phy_generic usb_phy_generic.0.auto: Linked as a consumer to regulator.0
[ 1.421270] sun6i-rtc 1f00000.rtc: setting system clock to 1970-01-01 00:00:09 UTC (9)
[ 1.429492] vcc3v0: disabling
[ 1.432464] vcc5v0: disabling
[ 1.435430] ALSA device list:
[ 1.438391] No soundcards found.
[ 1.450949] EXT4-fs (mmcblk0p2): INFO: recovery required on readonly filesystem
[ 1.458257] EXT4-fs (mmcblk0p2): write access will be enabled during recovery
[ 1.570369] random: fast init done
[ 1.612361] EXT4-fs (mmcblk0p2): recovery complete
[ 1.620771] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[ 1.628929] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.
[ 1.637633] devtmpfs: mounted
[ 1.641765] Freeing unused kernel memory: 1024K
[ 1.646442] Run /sbin/init as init process
[ 1.758717] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
Starting logging: OK
Initializing random number generator... [ 1.874008] random: dd: uninitialized urandom read (512 bytes read)
done.
Suprema Academy
s-academy login:
---
Mainline 이란?
- 오픈소스 운영체제 개발 쪽에서는 메인스트림에 해당하는 오픈소스 브랜치를 메인라인이라고 부르는 듯 하다.
- 코드가 굉장히 정리가 잘 되어 있고, 몇 가지 요건만 갖추면 오류없는 깨끗한 빌드 경험을 할 수 있다.
- [U-boot] http://linux-sunxi.org/Mainline_U-Boot
- [Kernel] http://linux-sunxi.org/Mainline_Kernel_Howto
zImage / Image / uImage ?
- Kernel image는 타겟 이름에 따라 저장 속성이 정해진다. zImage는 압축된 것. 나머지는 차이를 모르겠...
dtb ?
- Device tree blob: 과거의 kernel은 동일한 CPU에 대해 장치 드라이버는 공용으로 사용했지만, 보드마다 구성이 달라 새로운 보드를 개발하면 kernel을 항상 다시 컴파일해야하는 문제가 있었다. --CPU pin을 uart/gpio/spi/i2c 등 앞서 사용한 보드와 다른 목적으로 사용하려면 소스코드에 반영하고 빌드해야 함, 마찬가지 이유로 memory/static storage 증설 시 address mapping을 위해 다시 빌드-- Bootloader 또한 하드웨어에 맞게 다시 빌드해서 사용해야하며, bootloader가 kernel에 하드웨어 정보를 전달하는 데도 유연하지 못한 구조였다. 현대의 kernel system에서는 device tree라는 별도의 구조체를 정의하여 이런 문제를 해결하고자 한다.
- DTB: Device tree blob
- DTC: Device tree compiler
- DTS: Device tree source(specification)
- DTB = DTC(DTS)
- 참고자료
- https://en.wikipedia.org/wiki/Device_tree
- https://elinux.org/images/f/f9/Petazzoni-device-tree-dummies_0.pdf
- http://selfish-developer.com/entry/%EB%94%94%EB%B0%94%EC%9D%B4%EC%8A%A4%ED%8A%B8%EB%A6%ACDevice-Tree
- http://blog.naver.com/PostView.nhn?blogId=ham9627&logNo=220561187536&parentCategoryNo=&categoryNo=30&viewDate=&isShowPopularPosts=true&from=search