첫 번째 부팅 스크립트를 만들려면 /boot/cmdline.txt를 사용하십시오.


11

네트워크에서 Pi를 찾는 방법에 대한 많은 질문이있었습니다 . 나 자신을 포함한 다른 사람들은 신선한 파이를 배치하려고 할 때 시간이 많이 걸리는 문제가 있습니다.

사용자 지정 이미지를 만드는 것이 이러한 문제에 대한 해결책이 될 수 있지만 다른 해결책이 있는지 궁금합니다.

(전용)으로 /boot의 접근을위한 오픈 디렉토리 일반 기계 (승 / OSX), 그것을 사용하는 것이 가능할 것이다 /boot/cmdline.txt, bash는 스크립트에 파이프 문자로 실행하고 나중에 그것을 삭제 하시겠습니까?


1
이 질문은 메타대해 논의 중입니다 . 가능하다면 당신의 의견을 듣고 싶습니다. 감사.
Thomas Weller

답변:


6

이 요구를 해결하기 위해 약간 수정 된 Raspberian-light 버전을 만들었습니다. 처음 부팅 할 때 사용자 정의 /boot/firstboot.sh 스크립트를 실행합니다.

https://github.com/nmcclain/raspberian-firstboot


감사! OP 4 년 후 마침내 좋은 해결책이 있습니다. 특히 로켓 과학은 직접 제작하지는 않지만 새로운 버전이 출시 될 때마다 여러 시간 동안 사용됩니다. IMHO 이것은 주 펌웨어에 추가되어야합니다.
EDP

3

FAT32 부팅 파티션에 스크립트 만 포함 된 솔루션을 선호하는 사람들을위한 방법은 다음과 같습니다. [ 편집 : 이제 파일을 pi-boot-script 프로젝트에서 사용할 수 있습니다 .]

다른 답변에서 언급했듯이 Linux 커널이 시작되는 명령 줄 인수가 포함됩니다. 이러한 인수는 /boot/cmdline.txt에 있습니다.

나는 이것을 Raspbian Buster (v10.1) 2019-09-26에서 테스트했습니다. 새로 플래시 된 SD 카드 또는 다운로드 한 .img 디스크 이미지에서 작동하며, SD 카드 를 원하는 수만큼 플래시 할 수 있습니다.

1. 커널 인수를 편집하십시오

텍스트 파일 /boot/cmdline.txt를 열고 init=부분을 제거한 후 줄 끝에 추가하십시오.

init=/bin/bash -c "mount -t proc proc /proc; mount -t sysfs sys /sys; mount /boot; source /boot/unattended"

이 줄의 마지막 단어는 커널이 / sbin / init 대신 첫 번째 프로세스 (PID = 1)로 실행할 스크립트 이름입니다 . 커널 인수 도움말 페이지는 단지 인수없이 말한다 .스크립트가 호출 할 수 있도록 초기화 실행에 전달받을 unattended.sh 같은 또는 일.

2. 부팅 파티션에 스크립트를 넣습니다

다음을 부트 파티션에 / unattended (명령 줄에 입력 한 이름) 로 저장하십시오 .

# 1. MAKING THE SYSTEM WORK. DO NOT REMOVE
mount -t tmpfs tmp /run
mkdir -p /run/systemd
mount / -o remount,rw
sed -i 's| init=.*||' /boot/cmdline.txt

# 2. THE USEFUL PART OF THE SCRIPT
# Example:
[[ -d /boot/payload/home/pi ]] && sudo -u pi cp --preserve=timestamps -r\
 /boot/payload/home/pi /home/ && rm -rf /boot/payload/home/pi              # A
[[ -d /boot/payload ]] && cp --preserve=timestamps -r /boot/payload/* /\
 && rm -rf /boot/payload                                                   # B
ln -s /lib/systemd/system/one-time-script.service\
 /etc/systemd/system/multi-user.target.wants/                              # C

# 3. CLEANING UP AND REBOOTING
sync
umount /boot
mount / -o remount,ro
sync
echo 1 > /proc/sys/kernel/sysrq
echo b > /proc/sysrq-trigger
sleep 5

이 스크립트는 필요한 준비 (1 장), 수행하려는 작업 (2), 정리 및 재부팅 (3)을 수행합니다. 2 아래의 항목을 실행하려는 명령으로 바꾸십시오.

일부 구성 작업의 경우 네트워킹 및 기타 서비스를 제공하기 위해 일반 부팅이 필요할 수 있으므로이 버전의 예제 (아래 설명)는 Pi가 재부팅 될 때 적절한 스크립트를 실행할 준비 만합니다.

3. 스크립트에 필요한 다른 파일을 부팅 파티션에 넣습니다.

...명백하게.

스크립트와 함께 부트 파티션에 폴더 payload / 를 넣었습니다 .이 파티션에는 Linux 파티션으로 이동하려는 파일이 들어 있습니다. 위의 무인 스크립트 에서

  • A 행은 파일을 pi 사용자의 디렉토리로 이동시킵니다. 예를 들어 payload / home / pi / .bashrc/home/pi/.bashrc 와 같이 루트 파일 시스템으로 이동합니다 .
  • 를 포함하여 리눅스 파티션에 선 B의 이동 루트 소유의 파일을 페이로드 / usr / 지방 / 빈 / one-time-script.sh 가되는 /usr/local/bin/one-time-script.sh 및 유사 페이로드 / lib / systemd / system / one-time-script.service ;
  • C 행은 마지막 파일에 대한 심볼릭 링크를 생성하므로 다음 부팅시 구성 스크립트 one-time-script.sh 가 실행됩니다.

이 스크립트는 내가 좋아하는 다양한 사용자 정의를 수행합니다. 다른 FAT32 파티션을 작성하고 포맷하고 / etc / fstab에 추가 하여 pi 사용자가 응용 프로그램 로그 등을 쓸 수 있도록합니다. ext4 파티션 및 파일 시스템의 크기를 SD 카드의 나머지 크기로 조정합니다. 로케일, 시간대, 호스트 이름 (CPU 일련 번호 기반), WiFi 국가를 변경합니다. WiFi 네트워크 및 암호를 설정합니다. SSH를 켭니다. SSH 세션의 언어 설정 문제를 해결합니다. 자동 로그인없이 콘솔로 부팅하도록 구성합니다. 시스템에 대한 일부 데이터를 부팅 파티션의 파일에 씁니다. 물론 해당 심볼릭 링크를 제거하여 부팅시 다시 실행되지 않습니다.

대부분의 사용자는이를 불필요하게 생각하고 PiBakery , pi-init2 또는 사용자 지정 ext4 이미지 를 사용하는 것을 선호합니다 . 이는 훌륭한 솔루션입니다. 나는 그것을 완전히 이해할 수 있고 다른 소프트웨어를 실행할 필요가 없기 때문에 이것을 선호합니다. 그리고 그것은 또한 작동합니다 : 스크립트를 넣은 .img 파일을 사용하면 SD 카드를 모두 플래시하고 Pi에 넣는 + + 자체 구성을 실행하는 데 6 분이 걸립니다.

소스 리눅스 파티션의 크기를 조정하기 위해 기본적으로 실행되는 init_resize.sh 스크립트 에서 스크립트에 대한 아이디어와 init=커널 인수로 mount작동하는 데 필요한 명령을 발견했습니다 .


2

커널 명령 행을 망쳐 서 코드를 실행할 수 있습니다. 가장 확실한 방법은 init를 다른 것으로 바꾸는 것입니다. 가장 일반적인 응용 프로그램은 부팅 프로세스 초기에 쉘을 매우 일찍 시작하는 것입니다. 일반적으로 무언가를 수정해야하거나 다른 모든 것이 매우 손상되어 다음과 같습니다.

init=/bin/bash

부팅 과정에서이 시점에서 파일 시스템은 모두 읽기 전용으로 마운트되어 있습니다. 또한 제대로 작동하지 않는 많은 것들이 있습니다. 실제 초기화가 실행되지 않기 때문에 종료 및 재부팅이 작동하지 않습니다. reboot -f예를 들어 루트 파일 시스템을 읽기 전용으로 수동으로 다시 마운트하고 재부팅을 호출 해야합니다.

이 방법으로 인수를 bash에 전달할 수 있는지 모르겠습니다. 나는 한번도 시도한 적이 없다. 이론적 -c으로 bash에 전달할 수 있다면 bash 프로세스가 무엇이든하도록 지시 할 수 있습니다. 그러나 그것은 상당히 긴 논쟁으로 변할 수 있으며, 커널이 그러한 것들을 허용할지 모르겠습니다.

두 번째로 할 수있는 일 초기 램프 (initramfs)를 파일 시스템에 복사하고 부트 로더에서이를 사용하도록 구성 할 수 있습니다 config.txt. 특별한 일을하기 위해 스크립트를 initramfs로 가져 오는 방법에는 여러 가지가 있습니다. 이 목적을 위해 특별한 initramfs를 준비해야합니다 (initramfs-tools (8) 참조). 이것이 커스텀 이미지보다 더 나은 해결책인지 확실하지 않습니다.

스크립트를 / boot에 포함시킬 수 있습니다 ( "일반적인"머신에 대한 제안을 비웃었지만이 머신에서 액세스 할 수있는 비트 일 것입니다). 커널 init 라인을 사용하여 해당 파일을 시작하려고 시도하지만 dos 파일 시스템의 파일은 전체 파일 시스템에 대해 작성하지 않으면 실행 파일이 아닙니다.

그것이 나이라면 dhcp를 사용하여 네트워크를 구성하고 부팅시 실행되는 사용자 정의 스크립트를 포함하는 사용자 정의 이미지를 만들 것입니다. 이 스크립트는 플래그 역할을하는 특정 파일을 확인합니다. 파일이 존재하면 아무것도하지 마십시오. 그렇지 않은 경우 구성한 다음 플래그 파일을 작성하십시오.

구성 스크립트는 http 서버에서 실제 항목을 가져올 수도 있습니다. 즉, 무언가를 조정해야 할 경우 새 이미지를 만들 필요가 없습니다.

가장 스트레스가 적은 솔루션이어야합니다.

마지막 가능성은 "비정규"머신에서이 작업을 수행해야한다는 것입니다. :-) ext4 파일 시스템을 루프 장치에 마운트하고 먼저 sdcard에 쓰지 않고 파일을 복사 할 수 있습니다. 표준 Raspbian Jessie 이미지의 경우 다음과 같습니다.

sudo losetup /dev/loop0 /tmp/gw.img -o 62914560
sudo mount /dev/loop0 /mnt
sudo cp /my/superduper/script.sh /mnt
sudo umount /dev/loop0
sudo fsck -f /dev/loop0 # This is optional
sudo losetup -d /dev/loop0

이미지를 만들기 전에 파일 시스템에서 강제 fsck를 수행하고 싶습니다. 첫 번째 부팅시 마운트 수를 0으로 설정합니다. :-)

편집 : 몇 개월 및 더 많은 경험 후. u-boot를보고 싶습니다. 부트 로더를 u-boot로 교체하십시오. 이는 "일반 기계"에서 수행 할 수 있습니다. 일단 u-boot를 설치하면, sd-card를 쉽게 플래시 할 수있는 배포판을 네트워크 부팅하거나 이론 상으로는 카드를 직접 플래시 할 수 있습니다.

본질적으로 u-boot는 자체적으로 지원하지 않는 Raspberry Pi에 네트워크 부팅을 제공합니다.


그 단계에서 파일 시스템은 읽기 전용입니다. 무엇에 대해 init=script & init? init가 정상적으로 시작되는 동안 스크립트는 백그라운드에서 실행됩니다. 스크립트는 처음에 조건 점검이 필요하며, 예를 들어 init가 작업을 마치면 계속합니다.
Thomas Weller

1
&를 사용하여 무언가를 배경 화하는 것은 쉘 일입니다. 커널이 작동하지 않는 쉘에서 특정 명령 (예 : bash -c "일부 명령 및 다른 명령")을 실행하도록 명령하지 않으면 이미 이것이 나쁜 생각이라고 생각합니다. 그러나 나는 대답을 확장하고 최근에 발견 한 u-boot 옵션을 추가했습니다.
izak

1
시도 ;-) 아니 그냥 완료, 정말 작동하지 않습니다
토마스 웰러

1

부트 영역에서 (이외의 config.txt) 다른 작업을 수행하는 것에 대한 자세한 이해가 없다면 터치하지 않는 것이 좋습니다 . cmdline.txtRPi가 시작될 때 작동하도록 설계되지 않았습니다. 부팅시 Linux 커널에 매개 변수를 전달하는 데 사용됩니다.

SSH를 통해이 작업을 수행하는 것이 좋습니다. 데스크탑의 스크립트는 bash / python / java / c / 모든 프로그램을 RPi에 푸시하고 실행 한 다음 완료되면 삭제할 수 있습니다. 데스크탑의 스크립트에 스레딩을 추가하면 동시에 원하는만큼 많은 장치로 보낼 수 있습니다.


1
이것이 우리가 지금하는 방법이지만 더 쉬운 해결책을 찾고 있습니다.
EDP

1
읽기 : 서버 시작이 아닌 클라이언트 시작 설정 실행
EDP

@EDP : 부팅 위치를 편집하여 원하는 것을 얻을 수있는 방법이 없습니다. RPi의 첫 부팅시 서버에서 파일을 가져 오는 스크립트를 작성한 다음 해당 프로그램이 시작 스크립트를 제거하도록 할 수 있습니다. 그러기 위해서는 커스텀 이미지를 사용해야합니다.
Jacobm001

1
"데스크탑의 스크립트"-데스크탑에있는 스크립트는 무엇입니까? 첫 부팅시 데스크탑에는 스크립트가 없습니다. "SSH를 통해이 작업을 모두 수행"-처음 부팅 할 때 Pi에 올바른 이더넷 또는 WLAN 설정이 없을 수 있습니다.
토머스 웰러

스레딩이 필요하지 않으므로 패브릭 프로젝트를 확인하십시오. IIRC의 유일한 rewuirement는 SSH입니다
Steve Robillard

1

처음 부팅 할 때 스크립트를 자동으로 실행하도록 이미지를 수정해도 괜찮 으면 스크립트와 같은 방식으로 이미지를 수정 한 다음 해당 SD 카드를 이미지 파일에 저장하고 플래시에 사용할 수 있습니다. 새로운 RPis와 함께 사용할 SD 카드. 예를 들어, 모든 RP에 특정 항목 이 포함되도록하려면 수정 작업을 수행하는 스크립트를 작성하는 대신 자체 /etc/fstab수정 /etc/fstab을 수행하면됩니다.

당신이 절대적으로 (각 이미지는 다른 방식으로 수정해야합니다 예를 들어 경우) 스크립트 작업을해야 할 경우, 당신은 당신의 움직일 수 /etc/rc.local에을 /etc/rc.bak하고있는 스크립트를 넣어 /etc/rc.local자신을 대체하는 /etc/rc.bak마지막 명령을. 해당 스크립트는 첫 번째 부팅 작업 자체를 수행하거나 /boot원하는 경우 파티션 에서 특정 스크립트를 호출 할 수 있습니다.

여기에/boot 설명 된대로 커널에 특수 부트 램 디스크 이미지를 제공 하여 파티션 만 터치하여 자동 실행을 수행 할 수 있습니다 . 이 이미지에는 루트 파티션을 수정 한 다음에서 자체 삭제하는 스크립트가 포함됩니다 config.txt. 그래도 문제의 가치가 있는지 확실하지 않습니다.


-2

내 프로젝트 Nard를보고 싶을 수도 있습니다.

1) 각 SD 카드에는 http://www.arbetsmyra.dyndns.org/nard/#devsettingsid에 설명 된대로 일반 Windows PC에서 고유 한 ID를 할당 할 수 있습니다
.

2) 모든 Pis의 전원을 켜십시오

3) 가능하면 PC 방화벽을 비활성화하십시오

4) DOS 프롬프트 창을 열고 서브넷 브로드 캐스트 주소를 ping하십시오.

5) Windows 명령 "arp -a"를 사용하여 ARP 테이블을 나열하십시오. 이 목록에는 근처의 모든 Raspberry Pi의 MAC 및 IP 주소가 있습니다.

6) 텔넷을 사용하여 각 장치에 연결하십시오 (일반적으로 Windows에서도 사용 가능). 환영 문구는 1 단계에서 할당 된 ID를 표시합니다.


아마도 내 초기 설명은 충분히 명확하지 않았습니다. 나는 Pi를 식별하는 방법을 특별히 찾고 있지 않습니다. 나는 이미 그것을 다뤘다. 내가 찾고있는 것은 /boot/cmdline.txt 파일을 변경하여 하나 이상의 bash 명령을 실행하는 것입니다. 이 모든 것은 ssh를 통해 한 번만 로그인 할 필요가 없습니다.
EDP

아마도 '서브넷 브로드 캐스트 주소를 ping'할 수 없을 것입니다. 스머프 공격은 일반적으로 방지됩니다.
CrackerJack9
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.