İlk önyükleme komut dosyası oluşturmak için /boot/cmdline.txt dosyasını kullanın


11

Pi'mi ağımda nasıl bulacağım hakkında birçok soru soruldu . Kendim de dahil olmak üzere diğerlerinin bir grup taze Pi'yi dağıtmaya çalışırken zaman alıcı sorunları var.

Özel görüntülerin oluşturulması bu sorunlar için bir çözüm olabilirken, başka çözümler olup olmadığını merak ediyorum.

(Sadece) /bootdizin normal makinelerde (Win / OSX) erişim için açıkken , /boot/cmdline.txtmetni bir bash komut dosyasına bağlamak, çalıştırmak ve daha sonra silmek mümkün müdür ?


1
Bu soru Meta üzerinde tartışılmaktadır . Mümkünse fikrinizi duymak isterim. Teşekkürler.
Thomas Weller

Yanıtlar:


6

Raspberian-light'ın bu ihtiyacı karşılayan hafifçe değiştirilmiş bir sürümünü oluşturdum - ilk önyüklemede özel /boot/firstboot.sh komut dosyanızı çalıştırır:

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


Teşekkürler! OP'den 4 yıl sonra nihayet iyi bir çözüm var. Kendinizi inşa etmek için özellikle roket bilimi değil, her yeni sürümde saatlerce varsınız. IMHO bu ana bellenime eklenmelidir.
EDP

3

Yalnızca FAT32 önyükleme bölümüne bırakılan komut dosyalarını içeren bir çözümü tercih edenler için, bunu nasıl yapacağınız aşağıda açıklanmıştır. [ Düzenle: Dosyalar artık bir proje pi-boot-script dosyasında mevcut .]

Diğer cevaplarda belirtildiği gibi, Linux çekirdeğinin başlatıldığı komut satırı argümanlarını içerir. Bu argümanlar /boot/cmdline.txt dizinindedir .

Bunu Raspbian Buster (v10.1) 2019-09-26'da test ettim. Yeni yanıp sönen bir SD kartta veya indirilen .img disk görüntüsünde çalışır, daha sonra istediğiniz sayıda SD karta yanıp sönebilirsiniz.

1. Çekirdek bağımsız değişkenlerini düzenleyin

/Boot/cmdline.txt metin dosyasını açın , herhangi bir init=parçayı kaldırın ve satırın sonuna ekleyin:

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

Bu satırdaki son sözcük, çekirdek tarafından / sbin / init yerine ilk işlem olarak (PID = 1) çalıştırılacak bir komut dosyasının adıdır . Çekirdek argümanlar yardım sayfası sadece argümanlar olmadan diyor .komut dosyası çağrı yapamazsınız, init yürütülebilir geçirilen olsun unattended.sh böyle ya şeyler.

2. Komut dosyasını önyükleme bölümüne yerleştirin

Aşağıdakileri önyükleme bölümüne / unattended (komut satırına koyduğunuz ad) olarak kaydedin :

# 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

Bu senaryo gerekli bazı hazırlıkları yapar (bölüm 1), sonra yapmak istediğiniz her şey (2) ve ardından temizleme ve yeniden önyükleme (3). 2 altındaki öğeleri çalıştırmak istediğiniz komutlarla değiştirin.

Bazı yapılandırma görevleri için, ağ ve diğer hizmetleri getirmek için normal bir önyüklemeye ihtiyacınız vardır, bu nedenle bu sürümdeki örnek (aşağıda açıklanmıştır) yalnızca Pi yeniden başlatıldığında çalışacak uygun bir komut dosyasına hazırlanır.

3. Komut dosyanızın gerektirdiği diğer dosyaları önyükleme bölümüne yerleştirin

... belli ki.

Misal

Komut dosyamla birlikte , Linux bölümüne taşımak istediğim dosyaları içeren bir önyükleme bölümüne bir klasör yükü / koydum . Yukarıda katılımsız komut dosyasında ,

  • A satırı, dosyaları pi-kullanıcının dizinine taşır. Örneğin , loadload / home / pi / .bashrc /home/pi/.bashrc olarak kök dosya sistemine taşınır ;
  • dahil Linux bölümünün, içine hattı B hamle kök sahip olduğu dosyaları yük / usr / local / bin / one-time-script.sh hale geldiği /usr/local/bin/one-time-script.sh ve benzer yük / lib / systemd / system / bir kerelik-script.service ;
  • C satırı daha sonra bu son dosyaya bir sembolik bağlantı oluşturur, bu nedenle yapılandırma betiğim one-time-script.sh bir sonraki önyüklemede çalıştırılır.

Bu komut dosyası benim gibi çeşitli özelleştirmeler yapar: başka bir FAT32 bölümü oluşturur ve biçimlendirir ve pi kullanıcı (uygulama günlükleri vb. İçin) yazabilir böylece / etc / fstab ekler ; ext4 bölümünü ve dosya sistemini SD kartın geri kalanına yeniden boyutlandırır; yerel ayarı, saat dilimini, ana bilgisayar adını (CPU seri numarasına göre), WiFi ülkesini değiştirir; WiFi ağını ve parolasını ayarlar; SSH'yi açar; SSH oturumları için bir dil ayarları sorununu giderir; otomatik oturum açmadan bir konsolda önyüklemeyi yapılandırır; sistemle ilgili bazı verileri önyükleme bölümündeki bir dosyaya yazar; ve elbette bu symlink'i kaldırır, böylece önyükleme sırasında tekrar çalışmaz.

Çoğu kullanıcı bunu gereksiz bulur ve harika çözümler olan PiBakery , pi-init2 veya özel bir ext4 görüntüsü kullanmayı tercih eder . Bunu tercih ederim çünkü tam olarak anlayabiliyorum ve başka bir yazılım çalıştırmak zorunda değilim. Ve ayrıca çalışır: komut dosyalarımı koyduğum .img dosyasıyla, tüm SD kartı yanıp sönüyor + Pi + 'ya koyarak kendisini yapılandırması için 6 dakika sürüyor.

Kaynak Komut dosyası fikrini init=çekirdek argümanı olarak ve mountçalışmasını sağlamak için gerekli komutları Linux bölümünü yeniden boyutlandırmak için varsayılan olarak çalışan init_resize.sh komut dosyasında buldum .


2

Çekirdek komut satırını karıştırarak kod yürütülmesine neden olabilirsiniz. En belirgin yöntem init'i başka bir şeyle değiştirmektir. Bunun en yaygın uygulaması, genellikle bir şeyi düzeltmeniz gerektiğinden veya diğer her şeyin çok kötü bir şekilde kırılmış olması nedeniyle, önyükleme işleminin çok erken bir döneminde bir kabuk başlatmaktır:

init=/bin/bash

Önyükleme işleminin bu noktasında, dosya sistemlerinin hala salt okunur olarak bağlandığını unutmayın. Buna ek olarak, düzgün çalışmayan bir sürü şey var. Gerçek bir init'iniz olmadığından, kapatma ve yeniden başlatma çalışmaz. Kök dosya sistemini salt okunur olarak yeniden monte etmeniz ve reboot -förneğin yeniden başlatmak için çağırmanız gerekir.

Bu şekilde bash'a argümanlar aktarabileceğinize dair hiçbir fikrim yok. Hiç denemedim. Teoride, eğer -cbash'a geçebilirseniz , bash sürecine bir şey yapmasını söyleyebilirsiniz. Ama bu oldukça uzun bir tartışmaya dönüşebilir ve çekirdeğin bu tür şeylere izin verip vermeyeceğini bilmiyorum.

Yapabileceğiniz ikinci şey. İlk ramfs'i (initramfs) dosya sistemine kopyalayabilir ve önyükleyiciyi içinde kullanmak üzere yapılandırabilirsiniz config.txt. Özel şeyler yapmak için komut dosyalarını bir initramf içine almanın birkaç yolu vardır. Yine de bu amaç için özel bir initramfs hazırlamak zorunda kalacaksınız (bakınız initramfs-tools (8)), bu yüzden bunun özel bir görüntüden daha iyi bir çözüm olup olmadığından emin değilim.

Komut dosyasını / boot içine dahil edebilirsiniz ("normal" makineler hakkındaki önerinize güldüm, ancak bu makinelerden erişebileceğiniz bir bit olacaktır) ve çekirdek init satırını kullanarak başlatmayı deneyin, ancak dos dosya sistemlerindeki dosyalar aren tüm dosya sistemi için bunu yapmazsanız çalıştırılamaz.

Ben olsaydım, ağı yapılandırmak için dhcp kullanan ve önyüklemede çalışan özel bir komut dosyası içeren özel bir görüntü yaparım. Bu komut dosyası, bayrak görevi gören belirli bir dosyayı denetler. Dosya varsa hiçbir şey yapmayın. Değilse, şeyleri yapılandırın ve ardından bayrak dosyasını oluşturun.

Yapılandırma komut dosyanız gerçek şeyi bir http sunucusundan bile alabilir. Bu, bir şeyi düzeltmeniz gerekiyorsa yeni bir resim yapmanız gerekmediği anlamına gelir.

Bu en az stresli çözüm olmalıdır.

Son bir olasılık, ancak bunu "normal olmayan" bir makinede yapmanız gerekecek :-) Ext4 dosya sistemini bir döngü aygıtına bağlayabilir ve dosyaları önce sdcard'a yazmadan kopyalayabilirsiniz. Standart bir Raspbian Jessie görüntüsü için şöyle bir şey olurdu:

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

Görüntü oluşturmadan önce dosya sistemlerimde zorla bir fsck yapmayı seviyorum. İlk açılışta montaj sayısını sıfıra ayarlar :-)

EDIT : aylar sonra ve daha fazla deneyim. U-boot'a bakmak istiyorsunuz. Boot-loader'ı u-boot ile değiştirin. Bu bir "normal makineden" yapılabilir. Bir kez u-önyükleme yaptıktan sonra, sd kartını kolayca flaş edebileceğiniz bir dağıtımı ağdan önyükleyebilir veya teorik olarak kartı doğrudan flaş edebilirsiniz, ancak bunun ne kadar zor olacağını bilmiyorum.

Temelde u-boot, kendi kendine desteklemediği bir şey olan Raspberry Pi'ye ağ önyüklemesi getirir.


Tamam, dosya sistemi bu aşamada salt okunur. Ne olmuş init=script & init? Başlangıç ​​normal olarak başlatılırken komut dosyası arka planda çalışır. Komut dosyasının başında bazı durum denetimleri gerekir ve örneğin init işini bitirdiğinde devam eder.
Thomas Weller

1
& Öğelerini arka planda kullanmak kabuk bir şeydir. Çekirdeğe bir kabukta belirli bir komut çalıştırmasını söylemediğiniz sürece (örneğin: bash -c "bazı komutlar ve başka bir komut") ve bunun zaten kötü bir fikir olduğunu düşünüyorum. Ama cevabımı uzattım ve son zamanlarda keşfettiğim u-boot seçeneğini ekledim.
izak

1
Denemeyi yeni bitirdim ;-) Hayır, gerçekten işe yaramıyor
Thomas Weller

1

config.txtBu şeylerin ne yaptığını ayrıntılı bir anlayışa sahip değilseniz , önyükleme alanında (dışında ) hiçbir şeye dokunmanızı tavsiye etmem . cmdline.txtRPi başladığında işleri çalıştırmak için tasarlanmamıştır. Parametreleri önyükleme sırasında Linux çekirdeğine aktarmak için kullanılır.

Bunu SSH aracılığıyla yapmayı öneririm. Masaüstünüzdeki bir komut dosyası, basi / python / java / c / herhangi bir programı RPi'ye gönderebilir, yürütebilir ve bittiğinde silebilir. Masaüstünüzdeki komut dosyasına iş parçacığı ekleyin ve bunu aynı anda istediğiniz kadar cihaza gönderebilirsiniz.


1
Bunu şu şekilde yapıyoruz ama daha kolay bir çözüm arıyorum.
EDP

1
Oku: sunucu tarafından başlatılmak yerine istemci tarafından başlatılan kurulumu çalıştırın
EDP

@EDP: önyükleme konumunu düzenleyerek istediğinizi elde etmenin bir yolu yoktur. Dosyayı RPi'nin ilk önyüklemesindeki bir sunucudan çeken bir komut dosyası yazabilir ve bu programın başlangıç ​​komut dosyasını kaldırmasını sağlayabilirsiniz. Bu, özel bir resim kullanmanızı gerektirir.
Jacobm001

1
"Masaüstünüzdeki bir komut dosyası" - Masaüstümdeki hangi komut dosyası? İlk önyüklemede, Masaüstünde komut dosyası yok. "Bunu SSH üzerinden yapmak" - ilk önyüklemede Pi doğru Ethernet veya WLAN ayarlarına sahip olmayabilir.
Thomas Weller

İplik yapmanıza bile gerek yok, kumaş projesini kontrol edin. IIRC'nin tek geri dönüşü SSH
Steve Robillard

1

Muhtemelen, görüntüyü ilk önyüklemede bir komut dosyasını otomatik olarak çalıştıracak şekilde değiştirmeyi tercih ediyorsanız, görüntüyü komut dosyanızın yaptığı şekilde değiştirebilir ve daha sonra bu SD kartı bir görüntü dosyasına kaydedebilir ve flash için kullanabilirsiniz Yeni RPis ile kullanacağınız SD kartlar. Tüm RPis belli girişi yapmak istiyorsanız Örneğin, /etc/fstab, sadece değiştirebilir /etc/fstabmodifikasyon yapan bir senaryo yazmak yerine kendisini.

Kesinlikle (her görüntü farklı bir şekilde modifiye edilmelidir örn ise) metne eylemleri gerekiyorsa, size taşıma olabilir /etc/rc.localetmek /etc/rc.bakve bir komut dosyası koymak /etc/rc.localile yenilenmesini hangi /etc/rc.bakson komuta. Bu komut dosyası ilk önyükleme eylemlerini kendisi gerçekleştirebilir veya /bootisterseniz bölümden belirli bir komut dosyasını çağırabilir .

Burada/boot açıklandığı gibi çekirdeğe özel bir önyükleme ramdisk görüntüsü sağlayarak, yalnızca bölüme dokunarak otomatik çalıştırma yapmak mümkündür . Bu görüntü, kök bölümünü değiştirmek ve daha sonra kendinden silmek için komut dosyaları içerir . Yine de sorun değip değmeyeceğinden emin değilim.config.txt


-2

Sorununuz için bir çözümü olan Nard projeme bakmak isteyebilirsiniz:

1) Her SD karta, burada açıklandığı gibi normal bir Windows PC ile benzersiz bir kimlik atanabilir:
http://www.arbetsmyra.dyndns.org/nard/#devsettingsid

2) Tüm Pis'inizi açın

3) Mümkünse PC güvenlik duvarını devre dışı bırakın

4) Bir DOS komut istemi penceresi açın ve alt ağ yayın adresine ping atın

5) ARP tablosunu "arp -a" Windows komutuyla listeleyin. Listede yakındaki tüm Raspberry Pi'nin MAC ve IP adreslerini bulacaksınız.

6) Her cihaza telnet ile bağlayın (genellikle Windows'da da mevcuttur). Hoş geldiniz ifadesi, 1. adımda atanan kimliği görüntüler.


Belki de ilk açıklamam yeterince açık değildi. Özellikle Pi'leri tanımlamanın bir yolunu aramıyorum. Zaten bunu kapsamıştım. Aradığım şey /boot/cmdline.txt dosyasını değiştirerek bir veya daha fazla bash komutu çalıştırmak. Bunların hepsi ssh ile giriş yapmadan - bir kez bile.
EDP

Muhtemelen 'alt ağ yayın adresine ping atamazsınız', Şirin Saldırıları genellikle önlenir.
CrackerJack9
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.