Raspberry Pi Compute Module 4 (CM4) I/O Board RTC 사용하기

환경

사용 방법

/etc/rc.local

#!/bin/bash

# Enable RTC device of Raspberry Pi CM4 module
echo "Loading kernel module for PCF85063 RTC module ..."
echo "pcf85063 0x51" > /sys/class/i2c-adapter/i2c-10/new_device
modprobe rtc-pcf85063

# Sync hardware clock to system clock
echo "Reading from HW clock ..."
hwclock --hctosys
echo "Done."

/lib/systemd/system/rc-local.service

...
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

[Install]
WantedBy=multi-user.target

/etc/rc.local 권한 설정

sudo chmod +x /etc/rc.local

crontab

...
0 2 * * 6 /bin/bash -c 'service ntp stop; ntpd -gq; if [ "$?" -eq "0" ]; then hwclock --set --date="$(date "+%m/%d/%y %H:%M:%S")"; fi; service ntp start'

재부팅 후 dmesg로 결과 확인

...
[   15.200054] i2c i2c-10: new_device: Instantiated device pcf85063 at 0x51
[   15.262737] rtc-pcf85063 10-0051: registered as rtc0
[   15.264656] rtc-pcf85063 10-0051: setting system clock to 2022-03-17T06:13:33 UTC (1647497613)
...

참고자료

Windows 11 안드로이드 어플리케이션 구동하기

얼마전 Windows 11이 출시되기 이전, 초기 버전에서는 안드로이드 앱 구동 지원이 안될 것이라는 뉴스가 있었습니다. 실제로 얼마전 출시된 Windows 11 정식 버전에서는 해당 지원이 빠져 있었습니다.

하지만 바로 몇 시간전, Windows Insider Preview 버전에서 안드로이드 어플리케이션을 구동할 수 있도록 베타 지원이 시작되었습니다. 아직 정식버전은 아니지만, 쓸만한 것일지 한번 설치해보고, 어플리케이션이 잘 열리는지 아주 간단히 테스트해보았습니다.

키워드: Windows 11 안드로이드, 윈도우11 안드로이드, Windows Subsystem for Android, WSA

요구 사항

아래 적힌 요구사항 중 “미국이어야 함” 조건은, Windows Store에서 앱을 다운로드하는데 필요한 조건입니다. 어플리케이션을 수동으로 설치하는 방법을 이용하면 미국으로 바꾸지 않으셔도 됩니다. 여기서는 국가가 한국인 설정 상태에서 미국으로 바꾸지 않고 진행하겠습니다. (그러면 어플리케이션은 adb를 이용해 수동으로 설치해야 합니다.)

  • Windows 11 Insider Preview (Build 22000.xxx) // 22000.282에서 테스트 완료
  • UEFI BIOS에서 가상화 기능 활성
  • PC의 지역이 미국이여야 하며 미국 Amazon 계정이 있어야 함
    → 이 부분의 경우 안드로이드 어플리케이션을 Microsoft Store에서 다운로드하는데만 필요함!
  • Windows 11 Insider Preview가 Beta 채널에 있어야 함 // Preview 채널에서 테스트 완료

먼저 Microsoft Store를 업그레이드하자(버전 22110.1402.6).

1. 먼저 Windows Store를 업그레이드하기 위해 MsixBundle 파일을 다운로드받아야 합니다.

2. 아래 사이트에 접속합니다.

https://store.rg-adguard.net/

3. 우측 드롭다운 메뉴의 “Slow“를 선택합니다.

4. 아래 Microsoft Store 링크를 입력하고 체크 표시를 클릭하여 검색합니다.
아래 링크는 “Microsoft Store” 앱을 설치할 수 있는 Microsoft Store 링크입니다. 재귀함수

https://www.microsoft.com/store/productId/9WZDNCRFJBMP

5. 검색 결과 리스트 아이템들 중 맨 아래에 있는 msixbundle 확장자의 파일을 다운로드합니다.
(미러도 제공해드립니다!)

맨 아래에 있는 76.02 MB의 msixbundle 파일.

6. 해당 파일을 설치하기 위해서 Powershell을 관리자 권한으로 Open합니다.

7. 다운로드받은 폴더를 C:\Users\jungin500\Downloads라고 했을 때, 아래와 같이 명령어를 입력하여 설치를 시작합니다.

> cd C:\Users\jungin500\Downloads\
> Add-AppxPackage .\Microsoft.WindowsStore_22110.1402.6.0_neutral___8wekyb3d8bbwe.Msixbundle

8. 마지막 명령어를 통해 설치가 시작됩니다.

다음으로 안드로이드 구동 패키지를 설치하자.

1. 이전 챕터와 비슷한 과정을 한번 더 진행합니다. 이번에는 1.2GB짜리 Msixbundle 파일을 설치합니다. 패키지에 들어있는 앱 이름은 “Windows Subsystem for Android™” 입니다.

안드로이드 구동을 위해 설치해야 하는 Windows App 패키지.
이렇게 생겼습니다.

2. 다운로드 위치는:

https://store.rg-adguard.net/

3. 그리고 Windows Store 링크는:

https://www.microsoft.com/store/productId/9P3395VX91NR

4. 마찬가지로 다운로드받아 아래 파일을 얻을 수 있습니다(Slow로 바꾸는 부분도 중요합니다!)(미러!)

MicrosoftCorporationII.WindowsSubsystemForAndroid_1.7.32815.0_neutral_~_8wekyb3d8bbwe.msixbundle

5. 동일하게 Powershell (관리자 실행)로 설치합니다. 그러면 시작 메뉴에 새로운 어플리케이션이 설치됩니다.

Android Studio는 제가 따로 설치한 것이니 무시해주세요.
안은 이렇게 생겼습니다.

사용법은?

사실상 저 안을 들여다보면 어디에도 어플리케이션을 구동할 수 있는 것이 있어 보이지는 않습니다. 여기서부터, 안드로이드 어플리케이션 설치 방법이 두 가지로 나뉩니다.

  1. 지역이 미국이라면 Windows Store 안에서 Amazon Store 로그인 후 Android 어플리케이션을 다운로드받으실 수 있으실 것입니다 (아마도… 테스트해보지는 않았습니다.)
  2. adb를 이용해서 수동으로 어플리케이션을 설치합니다.

사실상 아직까지는 adb를 이용하는 방법밖에 없는 것 같습니다. 추후에 더 좋은 방법을 찾을 수도 있을것 같습니다. 이제 adb를 이용해서 apk 파일 하나를 설치 진행해보도록 하겠습니다.

adb로 어플리케이션 설치하기

먼저 설치할 어플리케이션의 apk가 필요합니다. apk는 각종 다운로드받는 사이트들에서 찾을수 있지만, 불법인곳도 많고 정식 apk인줄 알고 받았는데 알고보니 멜웨어… 일수도 있으니, 실제 스마트폰에 설치된 apk를 가져오는게 더 안전할듯 합니다.

저는 원신 apk를 준비했습니다.

apk 파일 설치에 앞서, 먼저 adb를 구합니다. adb는 Android Studio를 설치하고 Android SDK의 platform-tools를 설치하면 그 안에 있습니다.. 여기에 관련된 내용이 소개되어 있습니다.

아까 Windows Subsystem for Android™ 앱을 들어가면 “개발자 모드”가 있습니다. 이부분을 활성화 시켜줍니다. 그리고 바로 아래 “개발자 설정 관리”에 들어감과 동시에 Android가 부팅됩니다.

ADB 주소가 같이 뜹니다. 어차피 켤때마다 바뀔테니, 공개해도 괜찮겠죠.

이 주소로 adb를 연결해봅니다. 아래 명령어를 이용해 네트워크를 이용한 ADB 연결을 진행합니다. (마치 이 과정은 안드로이드 스마트폰을 USB에 연결하는 것과 비슷합니다.)

adb connect 127.0.0.1:58526

분명 포트는 다를테니, 한번 꼭 확인해보세요. 저 명령어로 연결이 되면 connected to 127.0.0.1:58526 라고 표시됩니다. 이제부터는 adb install이나 adb shell 같은 명령어를 사용할 수 있게 됩니다. 어플리케이션을 설치하려면 apk 파일이 있는 곳으로 이동하여 아래와 같이 입력합니다.

adb install "Genshin Impact 2.2.0.apk"

이 명령어가 잘 실행되었다면, 무려 윈도우 시작 메뉴에 Android 어플리케이션 바로가기가 나타납니다.

와! Android 원신이다!

결론

실제로 실행되는 어플리케이션이 대부분이겠지만, 아직은 베타니까 안되는 경우도 많을 것입니다. 원신의 경우도 계속 튕겨서 재시도해봤는데, 세번째로 켜니까 이제 되네요. 이것저것 한번 테스트해볼수 있을 것 같습니다.

안드로이드 어플리케이션이 윈도우에서 구동 가능하다면 이점들이 많을것 같습니다. 당장 생각나는건 게임뿐이지만, 생산성 관련한 어플리케이션 등을 설치해서 다양하게 활용할 수 있을것 같습니다.

문제점이 있거나 더 좋은 방식이 있다면 댓글로 남겨 주세요.

참고자료

[DSM 7.0] Synology DSM Docker에서 Docker-in-Docker (dind) 실행하기

서론

Docker-in-Docker는 이미 존재하는 Docker Daemon에서 새로운 Container를 구동하고, 그 안에서 새로운 Daemon을 구동하는 기법이다.

기존에는 docker:dind 이미지와 --privileged 플래그를 이용하여 새로운 컨테이너를 생성하면 바로 가능한 간단한 문제였으나, Synology DSM 7.0에서는 기본 dockerstorage-driveraufs로 설정되어 있고 overlay2 드라이버를 지원하지 않으므로 이러한 기본적인 접근방식은 불가능하였다.

해결 방법

기존에는 아래와 같이 dind 컨테이너를 생성하였다.

docker run \
   --name jenkins-docker \
   --rm \
   --detach \
   --privileged \
   --network jenkins \
   --network-alias docker \
   --env DOCKER_TLS_CERTDIR=/certs \
   --volume jenkins-docker-certs:/certs/client \
   --volume jenkins-data:/var/jenkins_home \
   --publish 2376:2376 \
   docker:dind \
   --storage-driver overlay2

위 명령어는 jenkins 컨테이너를 위한 dind 컨테이너 생성 명령어(링크)다. 이 마지막 부분에 보면 --storage-driver 인자가 있는데, 이 부분만 aufs로 바꿔주면 바로 문제가 해결된다.

docker run \
   --name jenkins-docker \
   --rm \
   --detach \
   --privileged \
   --network jenkins \
   --network-alias docker \
   --env DOCKER_TLS_CERTDIR=/certs \
   --volume jenkins-docker-certs:/certs/client \
   --volume jenkins-data:/var/jenkins_home \
   --publish 2376:2376 \
   docker:dind \
   --storage-driver aufs

[해결됨] WSL2 CUDA undefined symbol: devicesetgpcclkvfoffset 문제 해결하기

[추가] 현재는 Fix된 이슈임

Windows 11 Insider Preview Build 22000.51이 나온 뒤에는 해결된 문제입니다. 아래 환경에서 테스트하였으니 apt 패키지와 드라이버를 업데이트 해보시기 바랍니다.

  • OS: Windows 11 Insider Preview Build 22000.51
  • Driver: NVIDIA 470.76
  • APT Package Version List
Inst libnvidia-container1 (1.4.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Inst libnvidia-container-tools (1.4.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Inst nvidia-container-toolkit (1.5.1-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Inst nvidia-container-runtime (3.5.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Inst nvidia-docker2 (2.6.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [all])
 Conf libnvidia-container1 (1.4.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Conf libnvidia-container-tools (1.4.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Conf nvidia-container-toolkit (1.5.1-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Conf nvidia-container-runtime (3.5.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Conf nvidia-docker2 (2.6.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [all])

Environment: Windows 10 Insider Preview Build 21376.1
WSL2 Ubuntu release: 20.04
NVIDIA Forum Links: https://forums.developer.nvidia.com/t/nvidia-container-cli-error/177403/2?u=ji5489

문제 제기

if I run sudo nvidia-container-cli -k -d /dev/tty info

I got this error
where is ‘devicesetgpcclkvfoffset’ symbol?

– WARNING, the following logs are for debugging purposes only –
I0509 06:20:58.858216 1009 nvc.c:372] initializing library context (version=1.4.0, build=704a698b7a0ceec07a48e56c37365c741718c2df)
I0509 06:20:58.858281 1009 nvc.c:346] using root /
I0509 06:20:58.858287 1009 nvc.c:347] using ldcache /etc/ld.so.cache
I0509 06:20:58.858293 1009 nvc.c:348] using unprivileged user 65534:65534
I0509 06:20:58.858311 1009 nvc.c:389] attempting to load dxcore to see if we are running under Windows Subsystem for Linux (WSL)
I0509 06:20:58.891385 1009 dxcore.c:226] Creating a new WDDM Adapter for hAdapter:40000000 luid:1e946dc
I0509 06:20:58.917427 1009 dxcore.c:267] Adding new adapter via dxcore hAdapter:40000000 luid:1e946dc wddm version:3000
I0509 06:20:58.917515 1009 dxcore.c:325] dxcore layer initialized successfully
W0509 06:20:58.918854 1009 nvc.c:397] skipping kernel modules load on WSL
I0509 06:20:58.919404 1010 driver.c:101] starting driver service
E0509 06:20:58.950931 1010 driver.c:168] could not start driver service: load library failed: /usr/lib/wsl/drivers/nv_dispi.inf_amd64_43efafcd74b2efc9/libnvidia-ml.so.1: undefined symbol: devicesetgpcclkvfoffset
I0509 06:20:58.951399 1009 driver.c:203] driver service terminated successfully
nvidia-container-cli: initialization error: driver error: failed to process request

해결방법

I’m currently installing WSL2 Ubuntu 20.04 within Windows 10 Insider Preview Build 21376.1, and faced same issue like below.

# sudo nvidia-container-cli -k -d /dev/tty info

-- WARNING, the following logs are for debugging purposes only --

I0512 07:05:58.485519 5592 nvc.c:372] initializing library context (version=1.4.0, build=704a698b7a0ceec07a48e56c37365c741718c2df)
I0512 07:05:58.485581 5592 nvc.c:346] using root /
I0512 07:05:58.485601 5592 nvc.c:347] using ldcache /etc/ld.so.cache
I0512 07:05:58.485604 5592 nvc.c:348] using unprivileged user 65534:65534
I0512 07:05:58.485659 5592 nvc.c:389] attempting to load dxcore to see if we are running under Windows Subsystem for Linux (WSL)
I0512 07:05:58.502183 5592 dxcore.c:226] Creating a new WDDM Adapter for hAdapter:40000000 luid:185673b
I0512 07:05:58.512924 5592 dxcore.c:267] Adding new adapter via dxcore hAdapter:40000000 luid:185673b wddm version:3000
I0512 07:05:58.512956 5592 dxcore.c:325] dxcore layer initialized successfully
W0512 07:05:58.513266 5592 nvc.c:397] skipping kernel modules load on WSL
I0512 07:05:58.513404 5593 driver.c:101] starting driver service
E0512 07:05:58.521931 5593 driver.c:168] could not start driver service: load library failed: /usr/lib/wsl/drivers/nv_dispi.inf_amd64_43efafcd74b2efc9/libnvidia-ml.so.1: undefined symbol: devicesetgpcclkvfoffset
I0512 07:05:58.522047 5592 driver.c:203] driver service terminated successfully
nvidia-container-cli: initialization error: driver error: failed to process request

and I found out that apt-get experimental repository and stable one is mixed out – failing to install WSL2 one (which is available in experimental repository). as stable package is released, experimental(=WSL2) package should be released, but It wasn’t. see apt-cache madison result below.

# apt-cache madison libnvidia-container1
libnvidia-container1 |    1.4.0-1 | https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64  Packages
libnvidia-container1 |    1.3.3-1 | https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64  Packages
libnvidia-container1 | 1.3.3~rc.2-1 | https://nvidia.github.io/libnvidia-container/experimental/ubuntu18.04/amd64  Packages
libnvidia-container1 | 1.3.3~rc.1-1 | https://nvidia.github.io/libnvidia-container/experimental/ubuntu18.04/amd64  Packages
libnvidia-container1 |    1.3.2-1 | https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64  Packages
libnvidia-container1 |    1.3.1-1 | https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64  Packages

The point is, we should install libnvidia-container1=1.3.3~rc.2-1 version rather than libnvidia-container1=1.4.0-1. but normal apt-get install nvidia-docker2 command would install 1.4.0-1 version, and It mostly like to fail in WSL2 environment.

I successfully installed older (WSL2-exclusive) packages via apt-get install command below:

apt-get install \
    libnvidia-container1=1.3.3~rc.2-1 \
    libnvidia-container-tools=1.3.3~rc.2-1 \
    nvidia-container-toolkit=1.4.1-1 \
    nvidia-container-runtime=3.4.1-1 \
    nvidia-docker2=2.5.0-1

Those commands will install older packages, and after sudo service docker stop and sudo service docker start, CUDA will work inside docker.

[PyTorch] Windows에서 num_workers로 데이터로더 성능 높이기

RuntimeError: cuda runtime error (801): operation not supported at ..\torch/csrc/generic/StorageSharing.cpp:247

num_workers와 DataLoader에서 GPU 복사를 구현할 경우 발생하는 문제

기존 PyTorch로 학습을 진행하다가, single-thread로 동작하는 DataLoader의 bottleneck때문에 GPU를 최대한 활용하지 못하는 문제점이 있었습니다. 다만, PyTorch에서 기본적으로 제공하는 DataLoader의 num_workers를 설정하려고 하니, 이런 문제가 발생합니다.

데이터로더에서 이미 CUDA로 복사한 데이터를 넘겨주게 되면, Multiprocessing에 문제가 발생합니다.

각종 레퍼런스들을 찾다가, 이러한 내용을 발견했습니다.

그래서 생각을 해보니, Dataset에서는 CPU Tensor를 전달해주고, DataLoader를 순회하는 Training Time에 데이터를 CUDA에 복사하면 될 것 같았습니다. 그래서, 해당 방식을 이용해서 Dataset에는 CPU만을 이용하여 데이터를 로드하도록 해보았습니다.

상단의 데이터셋은 제가 Custom으로 작성한 torch.utils.data.Dataset의 상속 클래스입니다. OpenCV를 이용해 데이터를 CPU로만 로드하도록 하였습니다. 그리고 난 뒤, 아래와 같이 데이터로더 순회 후에 모델의 입력 직전에 GPU로 복사하도록 했습니다.

위 방법을 쓰니, 더이상 num_workers에 관련한 이슈는 발생하지 않아서 좋은 해결법이 되었습니다….!!

Raspberry Pi × LTE Hat – Raspberry Pi 4 Model B에 LTE Hat (SIM7600E-H 4G HAT)을 추가해서 LTE를 써보자!

※ 원본은 여기(링크)에 써놓고 이 게시물보다 더 주기적으로 업데이트합니다. 참고해주세요.

라즈베리파이에서 사용할 수 있는 LTE Cat-4 Hat으로 모바일 데이터를 사용해보자!‌

준비물

  • Raspberry Pi 4 Model B with 4GB RAM
  • USB Power Supply (5V 2.1A is sufficient)
  • SD Card (class 10 or more required for your mental health safety)
  • LTE Hat: SIM7600E-H LTE Cat.4 Hat
    • You should select specific model, because SIM7600X-series chipset varies by your country’s LTE wireless bandwidth. I’m currently testing it at South Korea, so I would use SIM7600E-H. See here

1단계 – Raspberry Pi OS 설치

  • Raspberry Pi OS 설치는 매우 간단하다. 여기를 참고해서 SD 카드에 Raspberry Pi OS 32bit를 설치하도록 하자. (일반 PC에 설치할 수 있는 Raspberry Pi OS도 있다! 헷갈리지 말자.)
  • 설치가 완료된 뒤에는, SIM7600E-H의 포장을 뜯어보도록 하자.

2단계 – SIM7600E-H HAT 장착

  • Raspberry Pi의 전원을 끄고 분리한다.
  • SIM카드 슬롯에 Full-Size SIM을 삽입한 뒤 SIM7600E-H Hat을 Raspberry Pi에 장착한다. (이 때, Raspberry Pi에 고정해버리면 SIM카드를 빼기 힘드므로 유의하자)
  • 같이 동봉된 짧은 USB Cable를 Raspberry Pi와 SIM7600E-H Hat의 ‘USB’ 포트에 연결한다.
  • 장착한 뒤 Raspberry Pi를 켠다.

3단계 – Raspberry Pi 세팅

  1. 라즈베리파이 내의 UART를 Disable한다.
[1] raspi-config를 실행한다.
[2] 세번째 “Interface Options”를 선택한다.
[3] “P6 Serial Port”를 선택한다.
[4] No를 선택한다.

4단계 – SIM7600E-H RNDIS 세팅

  • Raspberry Pi나 Jetson Nano 자체에 커널 모듈을 빌드하고 물리기 쉬운 일이 아니다. 머나먼 과정을 거치면 되긴 하지만 귀찮기 때문에, 모뎀을 RNDIS 모드로 변경해보도록 하자.
  • 모뎀을 RNDIS 모드로 변경하면, Android 스마트폰에서 USB 테더링을 연결하듯이 간단하게 작동시킬 수 있다.
  1. 먼저 Raspberry Pi가 SIM7600E-H와 잘 연결되었는지 확인하자. USB 디바이스 목록을 확인하여 ttyUSB가 연결되었는지 본다.
  2. 연결된 디바이스 네이밍이 어디에 매칭되는지 아래 정보에서 확인해보자. (출처: https://simcom.ee/documents/SIM5360/How%20to%20use%20linux%20driver.pdf)
  3. 이제 socat을 이용하여 ATCOM interface (줄여서 AT interface)에 연결해서 각종 명령어를 보내보자. 실질적으로 SIM7600E-H 보드와 통신하기 위해서는 AT Interface를 이용한다. 해당 인터페이스는 짧은 AT 명령어들로 통신하는 인터페이스이다.
  4. AT라는 테스트 명령어를 치고 Enter를 누르면 OK라고 뜬다. 정상적으로 연결되었다는 의미이다.
  5. 이제 아래와 같이 RNDIS 인터페이스 활성화 명령어를 입력한다. AT+CUSBPIDSWITCH=9011,1,1 > OK
  6. 이제 socat이 종료되고 칩셋이 재시작된다. 이를 조금만 더 기다리고 다시 시작하면 ip link를 했을때 아래처럼 usb 인터페이스가 뜬다. (보통은 usb0으로 뜨지만, 본인이 쓰는 Jetson Nano에는 usb0이 이미 있어서 usb1으로 할당되었다.)

5단계 – APN 설정

  • 사실 APN은 자동 설정이 가능하다. 여기서는 APN을 기지국으로부터 자동으로 가져오고 이를 사용해 LTE 네트워크에 연결하는 방법을 기술한다.
  1. 4-3단계와 같이 AT Interface에 연결한다.
  2. AT+CGDCONT? 명령어로 현재 사용되는 APN 프로필 리스트를 확인한다.
  3. +CGDCONT: 11은 프로필 ID를 나타낸다. 1부터 6까지 존재하는데, 여기서는 프로필 1번(셀룰러 네트워크 등록 과정에서 사용)과 프로필 6번(RNDIS 연결 과정)
  4. 기지국에서 APN을 자동으로 가져올 수 있도록 AT+CGDCONT=1,"IPV4V6","" 명령어와 AT+CGDCONT=6,"IPV4V6",""를 각각 입력하여 프로필을 비운다.
  5. AT+CGAUTH? 명령어로 현재 APN 인증 프로필을 확인한다.
  6. 마찬가지로 AT+CGAUTH=1,0, AT+CGAUTH=6,0 명령어로 인증 프로필을 비운다.
  7. 마지막으로 AT+CFUN=0 명령어로 SIM 카드를 껐다가, AT+CFUN=1 명령어로 다시 켠다.
  8. 이 뒤에는 인터넷이 정상 연결될 것이다. (다만 IP를 아직 받아오지 못한 상태이다.) 위 4, 5번 단계에 설정한 값들은 보드 자체의 NVRAM에 저장되므로 재시작하여도 RNDIS 모드나 APN 설정들을 다시 해줄 필요는 없다.

6단계 – DHCP 설정 및 Ping 테스트‌

  • 여기서는 1회성 DHCP를 설정해보도록 하자. 간단하다.‌
  1. dhclient -v usb0 (USB 디바이스명)으로 DHCP 클라이언트를 돌려서 IP를 할당한다.
  2. 이제 IP가 할당되었다. 이 후에 원하는대로 사용하면 될 것이다.
  3. 한번 ping 테스트를 해보자. ping -I usb0 명령어로 USB 인터페이스로 Ping을 날릴 수 있다. 통신사마다 다르겠지만, LGU+ 기준으로는 Ping이 잘 작동한다.
  4. 이제 이 위에 우리가 원하는 각종 Application을 얹어보자. 어디서든 인터넷 환경이 되기 때문에 가능성이 무궁무진하다(?)

Miscellaneous

각 통신사별 APN 설정 (출처)

[SKT 3G APN 설정] APN: web.sktelecom.com MMSC: http://omms.nate.com:9082/oma_mms MMS 프록시: smart.nate.com MMS 포트: 9093 MCC: 450 MNC: 05

[SKT LTE APN 설정] APN: lte.sktelecom.com MMSC: http://omms.nate.com:9082/oma_mms MMS 프록시: lteoma.nate.com MMS 포트: 9093 MCC: 450 MNC: 05

[KT 3G APN 설정] APN: alwayson.ktfwing.com MMSC: http://mmsc.ktfwing.com:9082 MMS 포트: 9093 MCC: 450 MNC: 08

[KT LTE APN 설정] APN: lte.ktfwing.com MMSC: http://mmsc.ktfwing.com:9082 MMS 포트: 9093 MCC: 450 MNC: 08

[LG U+ LTE APN 설정] APN: internet.lguplus.co.kr MMSC: http://omammsc.uplus.co.kr:9084 MMS 포트: 9084 MCC: 450 MNC: 06

[튜토리얼] Docker로 apt-mirror 미러서버를 구축해보자

결과 확인해보기: https://mirror.limenas.ml

미러 서버는 , 데비안 계열 리눅스에서(Debian, Ubuntu),
시스템에 설치할 수 있는 deb 패키지들을 가지고 있는 서버이며,
이 서버에 빠르게 접근할 수 있도록 서버를 통째로 복제해둔 로컬 서버입니다.

Raspberry PiJetson Nano와 같은 SBC(Single Board Computer)를 사용하다 보면, 같은 Ubuntu/Debian 계열 Linux임에도 불구하고, CPU 아키텍쳐가 ARM이라는 이유로 카카오에서 제공하는 빠른 미러서버를 사용하기 어려워집니다.(이 미러서버에는 ARM 아키텍쳐의 바이너리들을 미러링을 하지 않습니다!) 저는 주로 한국에서 가장 빠른 mirror.kakao.com를 주 미러 서버로 사용하는데, 위의 문제 때문에 카카오 미러서버는 PC나 워크스테이션에만 한정하여 사용합니다.

사실 ports.ubuntu.com 라는 곳에서, 우분투 (반)공식으로 비-인텔 CPU(ARM, ARM64, MIPS 등등)에서 사용할 수 있는 패키지를 배포하긴 합니다. 다만, 서버는 영국에 있어서 경우에 따라서는 매우 느려서 속이 터집니다(한국인).

개인적으로, 라즈베리파이와 Jetson Nano를 모두 사용하고 있고, 연구 목적으로도 사용하고 있어서, 미러 서버를 구축하게 되었습니다.

1단계: apt-mirror-downloader Docker 이미지를 만들어보자

이 튜토리얼에서는 도커를 이용해서, 미러를 수행하는 Downloader를 실행합니다. 아래 Dockerfile을 이용해서 도커 이미지를 생성할 수 있습니다.

Dockerfile이라는 이름(확장자 없음)의 파일을 생성하여, 아래 내용을 저장합니다.

FROM ubuntu:latest

RUN sed -i "s|archive.ubuntu.com|mirror.kakao.com|g" /etc/apt/sources.list &&\
    apt -qq update && apt -y --no-install-recommends -qq install wget curl git make ca-certificates &&\
    rm -rf /var/lib/apt/lists

RUN git clone https://github.com/Stifler6996/apt-mirror.git && cd apt-mirror &&\
    make install && cd .. && rm -rf apt-mirror

ENTRYPOINT apt-mirror

위 파일을 저장한 뒤, 아래 명령어를 실행하여 이미지를 빌드합니다 (물론 이미지 이름이나 태그는 원하는 것으로 변경하면 됩니다).

Ubuntu에서 패키지로 배포하는 apt-mirror의 경우 c-n-f(Content-Not-Found)나 dep11(Dependency 관련)과 같은 특수 태그를 지원하지 않습니다. 이 튜토리얼에서는, 해당 최신 태그를 지원하도록 패치한 apt-mirror 버전인 Stifler6996/apt-mirror를 사용하여 진행합니다.

docker build . -t jungin500/apt-mirror:arm64

이미지를 만들었다면, 이제 미러링 설정 파일을 생성해줍니다. 어떤 사이트를 미러링할지, 쓰레드 수는 얼마나 줄 것인지 등을 설정하는 과정입니다. mirror.list라는 파일을 새로 만들어, 아래 내용을 저장합니다.

####### config
#
set base_path    /var/spool/apt-mirror
#
#set mirror_path  $base_path/mirror
#set skel_path    $base_path/skel
#set var_path     $base_path/var
#set cleanscript $var_path/clean.sh
#set defaultarch  
#set postmirror_script $var_path/postmirror.sh
#set run_postmirror 0
set nthreads     20
#set _tilde 0
#
####### end config

# Begin Raspberry Pi (Debian 10) ARM32/ARM64 configuration
deb [arch=armhf,arm64] http://archive.raspberrypi.org/debian buster main
# deb-src http://archive.raspbian.org/debian buster main
# End Raspberry Pi (Debian 10) ARM32/ARM64 configuration

위쪽 config 파트에서는 디렉토리나 thread수를 결정할 수 있습니다. 이 뒤부터는 보통 사용하는 sources.list와 동일합니다. 다만, 아키텍쳐를 [arch=armhf,arm64] 지시어로 지정합니다. 여기서는 armhf(32비트 ARM Hard Float)와 arm64(64비트 ARM) 두 가지 아키텍쳐에 해당하는 패키지만 다운로드한다는 의미입니다.

이런 식으로, 추가로 mirror.kakao.com나 ftp.kr.debian.org 등의 미러링이 가능합니다. 사용하고 있는 배포판에서 /etc/apt/sources.list를 뜯어서, 그 내용을 그대로 이 파일의 맨 아래에 넣어주면 됩니다. 다만, 아키텍쳐는 기본이 amd64로 지정되므로 위 내용 [arch=armhf,arm64]와 같이 explicit하게 지정해줘야 합니다!

다음으로는 두 번째 설정 파일입니다. 이 스크립트는 미러링이 끝난 뒤 ls-lR.gz 파일을 생성합니다. apt-get으로 패키지 메타데이터를 다운로드하게 되는데, ls-lR.gz는 이 때 필요한 파일입니다. 아래 스크립트를 postmirror.sh 라는 파일로 저장합니다.

#!/bin/bash
# ls-lR Creator Postscript for apt-mirror
# LimeOrangePie [email protected]

MIRROR_ROOT=/var/spool/apt-mirror
cd $MIRROR_ROOT/mirror

IFS=$'\n'
MIRRORS=( $(ls -1) )

for mirror_item in "${MIRRORS[@]}"
do
    cd $MIRROR_ROOT/mirror/$mirror_item
    DISTRIBUTIONS=( $(ls -1) )

    for dist_name in "${DISTRIBUTIONS[@]}"
    do
        cd $MIRROR_ROOT/mirror/$mirror_item/$dist_name
        rm -f ls-lR.gz
        ls -lR > ls-lR
        gzip ls-lR
    done
done

위 두 파일을 준비했다면, 다음으로, 만든 이미지를 이용해서 미러링을 수행합니다. 미러링을 할 디렉토리는 300GB 이상의 여유 공간이 있는 것이 좋습니다. 4개 서버를 미러링했더니 500GB정도가 나오네요. STORAGE_PATH를 변경하여 미러링할 대상 폴더를 지정해주세요.

DOCKER_WORKDIR=pwd
STORAGE_PATH=/mirror-storage
docker run \
         -it \
         --name apt-mirror-downloader \
         -v $DOCKER_WORKDIR/mirror.list:/etc/apt/mirror.list:ro \
         -v $DOCKER_WORKDIR/postmirror.sh:/var/spool/apt-mirror/var/postmirror.sh:ro \
         -v $STORAGE_PATH:/var/spool/apt-mirror:rw \
         --entrypoint apt-mirror \
         --rm \
         jungin500/apt-mirror:arm64

미러링은 3시간에서, 길면 반나절까지 걸립니다. 백그라운드로 돌리려면 docker 명령어에 -d 플래그를 붙여두고 기다리시면 됩니다.

다음 게시물에서는 만든 미러서버를 제공(Serve)하는 방법을 소개해 드리겠습니다. 지금까지 미러링한 서버를 실제로 다른 사람들이 쓸 수 있도록 간단한 웹 서버를 만들어서 배포합니다.