Avrdude Aracı ile Arduino Klonlamak

Arduino IDE, Arduino’ya kod yüklerken (upload) arka planda avrdude (AVR Downloader Uploader) isimli araçtan faydalanır. avrdude, STK500 protokolü ile Arduino Bootloader’ı ile konuşarak mikrodenetleyicinin flash belleğine yazar veya içeriğini okur (okuma/yazma yaparken kullanılan bootloader hakkındaki detayları ilerleyen paragraflarda bulacaksınız). avrdude.exe aracını “C:\Program Files (x86)\Arduino\hardware\tools\avr\bin” dizininde bulabilirsiniz. Arduino IDE’nin yükleme yapmak için kullandığı aşağıdaki komutu Arduino IDE üzerinde görmek için; Dosya->Tercihler menüsü ile ulaşılan yapılandırma ekranındaki derleme ve yükleme için “Ayrıntılı çıktı” seçeneğini etkinleştirebilirsiniz. Böylece Arduino IDE’nin avrdude aracını arka planda nasıl kullandığını görebilirsiniz.

avrdude -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM4 -b115200 -D -Uflash:w:"hex_dosyasi.hex":i

Yukarıdaki komutu açıklamak gerekirse; “avrdude.conf” dosyasındaki yapılandırmaya göre (avrdude bu yapılandırma dosyasına mutlaka ihtiyaç duyar) atmega328 (-p: AVR aygıt/parça adı) aygıtına arduino (-c: programmer) programlayıcısını kullanılarak COM4 (-P: port) üzerinden 115200 baud hızında (-b:baud rate) “hex_dosyasi.hex” adlı dosyanın içeriği yazılmaktadır (:w). -v (verbose) seçeneği ise araç tarafından gerçekleştirilen işlemlerin ne detayda konsol ekranında görüntüleneceğini ayarlar. Daha fazla detay için birden fazla -v kullanabilirsiniz. :i seçeneği kodların Intel Hex biçiminde yorumlanacağını bildirir.

Mevcut bir Arduino üzerindeki kodu hex dosyası olarak elde etmek/okumak (download) için aşağıdaki komutu kullanabilirsiniz. Komuttaki tek değişiklik yazma (:w) işlemi yerine okuma işleminin (:r) gerçekleştirilmesidir. Okunan dosya “okunan_hex_dosyasi.hex” adıyla kaydedilmiştir. Yukarıdaki ve aşağıdaki komutta .hex dosyasının tam yolunu (dizini) belirtebilirsiniz. Belirtilmezse .hex dosyası çalışılan dizinde varsayılır.

avrdude -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM4 -b115200 -D -Uflash:r:"okunan_hex_dosyasi.hex":i

AVR serisi ATMEL mikrodenetleyicilerin bellek organizasyonu

Arduino bootloader’ı (ön yükleyicisi) ne işe yarar?

Eğer geliştirmelerinizi Arduino IDE ile gerçekleştiriyorsanız, mikrodenetleyici üzerinde Arduino Bootloader adlı ön yükleme programını kullanıyorsunuz demektir. Bootloader açılış yükleyicisi programın adıdır. Arduino ya da mikrodenetleyici enerjilendiğinde önce bu program çalışır ve icrayı asıl uygulama programına devreder. Peki açılışta çalışan bootloader programının görevi tam olarak nedir?

Önceki başlıkta yer verilen görselde görebileceğiniz gibi yazdığınız programların saklandığı alan Flash Memory’dir. Flash memory’nin büyük kısmına (Program Memory) uygulama programımız yerleşirken, belleğin sonuna denk gelen ufak bir kısmına da Arduino Bootloader programı yerleşir. Bootloader’ın varlığı Arduino Kodunun çalışabilmesi için zorunlu olmamasına rağmen, Arduino IDE ile program yüklerken fayda sağlar. Bu faydalar ilerleyen paragraflarda açıklanmıştır. Aşağıdaki görselde uygulama programının ve açılış önyükleyicisinin (bootloader) bellekteki yerleşimi ve çalışma sırası gösterilmiştir.

Arduino Bootloader’ın görevi

Bootloader (burada bahsettiğim Arduino IDE’ye ait olandır, bunun dışında Atmel mikrodenetleyiciler üzerinde çalışabilecek farklı özelliklere sahip birçok bootloader vardır) karta enerji verildiğinde ilk çalışan programdır. Örneğin Arduino Uno üzerinde çalışmaya başlayan bootloader programı Arduino IDE üzerinden gelen bir program yükleme (upload) isteği olup olmadığına bakar. Varsa, programın .hex kodu USB portu üzerinden seri olarak okunur ve Flash Memory’nin uygulama programı alanına yazılır ve ardından sağlama kontrolü için geri okunur. Görüldüğü gibi Arduino Bootloader’ın esas görevi program kodunu bilgisayardan okumak ve Flash Memory alanına yazmaktır. Bootloader programı yazdığı veriyi aynen geri okuyabilmişse tamamen devreden çıkar ve icrayı/çalışmayı uygulama programına devreder. Genellikle 512 Byte (2KB’a kadar artırılabilir) uzunluğunda olan Bootloader programının yer aldığı Flash Memory bölümü, genellikle 3 byte’dan oluşan (düşük, yüksek ve genişletilmiş) sigorta kaydedicileri aracılığı ile koruma altına alınmıştır (kilitlenmiştir), böylece hem bootloader’ın bozulmaması için bir önlem alınmış olunur hem de Arduino’ya her daim Arduino IDE üzerinden program atılabilmesi (upload) garanti altına alınmış olur. Detayları ilgili uc’ın (micro controller) veri sayfalarında anlatıldığı üzere BOOTSZ0 ve BOOTSZ1 kaydedici bitleri kullanılarak bootlader alanının büyüklüğü ile program alanın adres uzayı ayarlanabilir.

Arduino Bootloader – Boot Flash Section

Fabrikadan yeni çıkmış bir Atmel çipine bootloader programı yazılmadan önce çipin içindeki ilgili sigortalar açılır, bootloader programı yazılır ve yine sigortalar aracılığı ile bootloader bölümünün üzerine seri programlama yoluyla yazılması devre dışı bırakılır (bootloader kilitlenir). Bootloader’ın seri programlama yoluyla yazılması devre dışı kaldığında bootloader’ı yeniden yazmak için ISP/ICSP programlama arayüzü kullanılır. Bu işlemi harici bir programlama donanımı ile veya ikinci bir Arduino’yu ISP programlayıcı haline getirerek ICSP portu üzerinden bağlamak suretiyle gerçekleştirebilirsiniz. Sigortalar aracılığıyla yanlışlıkla da olsa ISP programlama arayüzü de devre dışı bırakılabilir. Bu durumda karta bootloader yazmanın tek yolu yüksek voltaj programlaması yapabilen bir programlayıcı ile mümkün olabilir, aksi takdirde kart kullanılmaz duruma gelir ve yani çöp olur.

Kodun kopyalanmasını/klonlanmasını önlemek

Atmega328p (Uno) mikrodenetleyicisi kilit bitleri aracılığı ile kodun kopyalanmaya karşı korunmasını sağlayacak özelliklere sahiptir. Önceki başlıkta sigortalar aracılığı ile bootloader ve uygulama programı (sketch) bellek bölümlerinin dışarıdan yazma veya okumaya karşı korumasının yapılabildiğini belirtmiştim. Bu başlıkta kodun klonlanmasının önüne nasıl geçilebileceğini açıklayacağımızdan öncelikle bootloader bölümüne odaklanmalıyız. Çünkü uygulama bölümünün seri/ISP portları aracılığıyla okunamamasını sigortalar vasıtasıyla sağlayabiliyoruz fakat bootloader bölümüne yazılacak bir programın dahili olarak uygulama bellek bölümünü okumasını engelleyemiyoruz. Yani bootloader programı değiştirilerek koruma seri/ISP yoluyla okuma koruması koyulmuş bir Flash dahili olarak okunabilir. Dediğimiz gibi bootloader ilk çalışan program ve çalıştığı depolama ortamını okuma yetkisi var. Bu programı değiştirerek uygulama bölümünü okumasını ve istediğimiz bir protokolle seri/ISP arayüzü üzerinden dışarı vermesi mümkün. Bu durumda 2 seçenek var gibi duruyor. Ya hiç bootloader programı kullanmayacağız ki aslında uygulama programının çalışabilmesi için bootloader programına gerek yoktur. Çünkü bootloader sadece program yükleme sırasında görev yapar. Ya da bootloader programına yazma koruması uygulayacağız ki bu da yüksek voltaj programlama ile aşılabilir. Yüksek voltaj programlayıcı ile mikrodenetleyici kartın dışına alınıp RESET pinine 12v uygulanarak sigorta yapılandırması değiştirilir. Dolayısıyla en iyi yöntem bir bootloader kullanmadan ISP programlayıcı ile uygulama programımızı mikrodenetleyiciye yüklemek ve okuma koruması için gerekli sigortaları etkinleştirmek.

Kodun kopyalanmasını zorlaştırmak için bazı yöntemler

Kodunuzun kopyalanmasını zorlaştırmak için uygulayabileceğiniz başka yöntemler de var:

  • Arduino’ların program ve data’nın saklandığı FLASH belleğin (Uno:32KB) haricinde EEPROM adında bir belleğe (Uno:1KB) daha sahiptir. Kapasitelerini buradan görebilirsiniz. Programcı EEPROM kütüphanesini kullanarak burada veri saklayabilir veya okuyabilir. Bu yöntemde EEPROM alanına bir seri numarası kaydedilir ve programın başlangıcında hardcoded olarak kontrol edilir. Seri numarası aynı değilse program durur. Yukarıdakine benzer yöntemlerle EEPROM alanı kopyalanmaz ise seri numarası doğrulanamayacaktır. Ancak şu komut ile EEPROM alanını okumak mümkündür: avrdude -C”C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf” -v -v -v -patmega328p -carduino -PCOM4 -b115200 -D -Ueeprom:r:”eeprom.hex”:i
  • Arduino devresinin tam olarak kopyalanmadığını varsayarak, pinlerden birini INPUT_PULLUP yapın ve bir diğerini OUTPUT yaparak bu pin’e kısa devre edin. Daha sonra da kod içinden pin’i okutun. Eğer devre tam olarak taklit edilmemişse kod çalışmaya devam etmez. Bu da klonlamayı önlemek için devre üzerinde uygulanabilecek basit bir yöntemdir. Tabi bu örnek ADC ile gerilim bölücü üzerinden okunan bir değer veya bir osilatörün çıkışı kontrol edilmek şeklinde geliştirilebilir.
  • Kodunuza uzun süreli bir timer ekleyin. Örneğin 90gün. Timer tetiklendiğinde devre çalışmasını durdurur ve servis çağrılmasını isteyebilir. Bu uygulama daha çok düzenli bakıma ihtiyaç duyan cihazlarda kullanılabilecek bir yöntemdir. Bakım zamanı geçmişse cihaz çalışmasını tamamen dudurur veya devre üzerindeki bir sigortayı attırarak kendine zarar verir ve fiziksel olarak çalışmaz hale getirir. Buna benzer bir yazıyı daha önce “PCB yanar kaynağına geri döner” başlığında yazmıştım.

https://forum.arduino.cc/t/arduino-uno-how-to-set-reading-protection-lock-bits/876927/5

Kaynaklar

  • https://www.electronicwings.com/arduino/basics-to-developing-bootloader-for-arduino
  • https://www.avrfreaks.net/forum/atmega328p-software-protection-and-verification

Yazar: Özgür Koca

Yazar - Tankado.com

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.