Kami sering melihat pemula bertanya di forum mikropengawal sama ada mikropengawal kecil 8-bit mereka boleh menjalankan Linux. Soalan-soalan ini sering menimbulkan ketawa. Kami sering melihat orang di forum Linux bertanya apakah keperluan minimum untuk menjalankan Linux. Jawapan biasa ialah Linux memerlukan seni bina 32-bit dan MMU (Unit Pengurusan Memori), dan sekurang-kurangnya 1MB RAM untuk memenuhi kernel.
Namun, projek ini bertujuan untuk (dan telah berjaya) menghancurkan persepsi ini. Papan pembangunan yang ditunjukkan dalam gambar di bawah adalah berdasarkan ATmega1284P. Saya (orang asing) juga membuat papan pembangunan berdasarkan ATmega644a, yang juga berjaya. Papan pembangunan ini tidak menggunakan pemproses lain dan boleh boot kernel Linux 2.6.34. Malah, ia juga boleh menjalankan timbunan Ubuntu penuh, termasuk X (jika anda sanggup menunggu untuk boot) dan persekitaran desktop gnome.
▍RAM (memori akses rawak)
Ya, betul, pemasangan Linux penuh memerlukan beberapa megabait RAM dan CPU 32-bit dengan MMU. Projek ini mempunyai semuanya. Mula-mula, mari kita akses RAM. Seperti yang anda lihat, terdapat modul memori SIMM 30-pin antik dalam litar. Inilah yang pernah digunakan oleh PC berasaskan 80286. Ia antara muka dengan ATmega dan saya menulis kod untuk mengaksesnya dan menyegarkannya mengikut spesifikasi (SDRAM memerlukan penyegaran kadar yang berterusan untuk mengelakkan kehilangan data).
Berapa cepatkah ia? Gangguan muat semula berlaku setiap 62ms dan mengambil masa 1.5ms, jadi ia menggunakan kurang daripada 3% daripada CPU. Akses RAM, untuk memudahkan pengaturcaraan, satu bait pada satu masa. Jalur lebar maksimum yang dihasilkan ini ialah kira-kira 300KBps.
***▍*Storan
Untuk RAM berfungsi dalam keadaan tidur, kami mempunyai dua perkara untuk ditangani. Penyimpanan bukanlah masalah yang terlalu sukar untuk diselesaikan. Sangat mudah untuk berinteraksi dengan kad SD menggunakan SPI, yang saya lakukan dalam projek saya. Kad SD 1GB akan berfungsi dengan baik, walaupun 512MB mencukupi untuk sistem fail tertentu ini (Ubuntu Jaunty).
ATmega mempunyai modul SPI perkakasan, tetapi atas sebab apa pun, ia tidak berfungsi dengan lancar, jadi saya memotong sedikit antara muka. Ia masih cukup tebal - kira-kira 200KBps. Ia juga masuk akal untuk projek itu - ia boleh dilaksanakan pada mana-mana mikropengawal dengan pin yang mencukupi, tanpa menggunakan modul perkakasan tambahan.
***▍*CPU (Unit Pemprosesan Pusat)
Yang tinggal ialah keperluan CPU dan MMU 32-bit. Walau bagaimanapun, AVR tidak mempunyai MMU, dan ia adalah 8-bit. Untuk mengatasi kesukaran ini, saya menulis emulator ARM. ARM ialah seni bina yang paling saya kenali, dan ia cukup mudah untuk saya berasa selesa menulis emulator untuknya. Mengapa menulis satu daripada mengalihkan satu?
Nah, mengalihkan kod orang lain tidak menyeronokkan, ditambah pula saya tidak melihat dokumentasi yang didokumenkan untuk memindahkan emulator ke peranti 8-bit dengan mudah. Satu sebab: desakan pengkompil AVR pada 16 bit untuk mengendalikan integer akan menyebabkan anda masalah dengan mudah "(1
***▍*Fungsi lain
Papan berkomunikasi dengan dunia sebenar melalui port bersiri. Pada masa ini ia disambungkan melalui port bersiri ke minikom yang berjalan pada PC saya, tetapi sambungan alternatif yang boleh diuji ialah papan kekunci dan LCD aksara yang disambungkan ke litar yang akan menjadikannya kendiri sepenuhnya. Terdapat dua lagi LED pada papan. Mereka menunjukkan akses kepada kad SD. Satu mewakili operasi baca dan satu lagi mewakili operasi tulis. Terdapat juga butang pada papan litar. Apabila ditekan dan ditahan selama 1 saat ia akan mengeluarkan port bersiri daripada kelajuan berkesan semasa CPU yang dicontohi. Kekerapan utama AVR ialah 24MHz (overclock sedikit melebihi 20MHz asal).
***▍*Berapa cepatkah ia?
uARM pastinya tidak mempunyai daemon kadar. Ia mengambil masa kira-kira 2 jam untuk boot ke gesaan BASH (baris arahan kernel "init=/bin/bash"). Kemudian mengambil masa lebih daripada 4 jam untuk memulakan keseluruhan Ubuntu ("exec init" dan kemudian log masuk). Memulakan X akan mengambil masa yang lebih lama. Kelajuan CPU yang dicontohi yang berkesan ialah kira-kira 6.5KHz, iaitu kira-kira perkara yang anda jangkakan mencontohi CPU 32-bit dan MMU pada mikropengawal 8-bit yang sedikit. Anehnya, setelah diboot, sistem ini agak boleh digunakan. Anda boleh memasukkan arahan dan mendapatkan jawapan dalam masa seminit. Maksudnya anda sebenarnya boleh menggunakannya. Sebagai contoh, saya menggunakannya untuk memformat kad SD saya hari ini. Ia pastinya bukan yang terpantas, tetapi saya rasa ia mungkin yang paling murah, paling lambat, paling mudah untuk dipasang dengan tangan, mempunyai kiraan bahagian paling rendah, dan merupakan PC Linux paling rendah. Papan litar dipateri dengan tangan menggunakan wayar, tanpa memerlukan papan litar bercetak (PCB).
***▍*Butiran emulator?
Emulator agak modular, membolehkan ia dikembangkan untuk meniru konfigurasi SoC (System on Chip) dan perkakasan lain sesuka hati. CPU simulasi ialah ARMv5TE. Beberapa ketika dahulu, saya mula bekerja untuk menyokong ARMv6, tetapi ia belum selesai (seperti yang dapat dilihat dari kod) kerana ia tidak begitu diperlukan. SoC simulasi ialah PXA255.
Disebabkan reka bentuk modular, anda boleh menggantikan fail SoC.c dan menyusun SoC baharu yang lengkap menggunakan teras ARMv5TE yang sama, atau menggantikan teras, atau menggantikan persisian seperti yang anda mahu. Ini sengaja, maksud saya kod ini juga merupakan contoh yang cukup kemas tentang bagaimana ARM SoC berfungsi. Kod emulator CPU itu sendiri tidak terlalu kemas, jadi, ia adalah emulator CPU. Ini telah ditulis beberapa tahun yang lalu dalam lebih 6 bulan masa lapang dan kemudian diketepikan. Ia baru-baru ini dibangkitkan khusus untuk projek ini. Emulator melaksanakan i-cache untuk meningkatkan kelajuan. Ini memberi AVR banyak bantuan, membolehkan memori dalaman diakses pada lebih 5MB sesaat tidak seperti RAM luaran saya. Saya belum sempat melaksanakan d-cache (data caching), tetapi ia berada dalam senarai tugasan saya. Mengakses peranti blok tidak dicontohi sebagai peranti SD. Ini ternyata terlalu perlahan. Sebaliknya terdapat peranti cakera paravirtual (pvdisk, lihat pvDisk.tar.bz2, berlesen GPL), yang saya tulis menggunakan opcode yang tidak sah untuk dimuatkan ke dalam emulator dan mengakses cakera. Ramdisk (cakera maya) dalam imej saya memuatkan pvdisk ini dan kemudian menukar direktori akar kepada /dev/pvd1.
ramdisk disertakan dalam "rd.img". "Jenis mesin" yang saya gunakan ialah PalmTE2. kenapa? Oleh kerana saya sangat biasa dengan perkakasan ini, ia adalah jenis mesin PXA255 yang pertama yang saya lihat.
***▍*Panggilan hiper?
Terdapat beberapa perkhidmatan yang anda boleh membuat permintaan kepada emulator dengan menggunakan opcode khas. Dalam ARM ialah 0xF7BBBBBB, dalam Thumb ialah 0xBBBB. Ini dipilih kerana ia berada dalam julat di mana jaminan ARM tidak ditentukan. Nombor hypercall diluluskan dalam daftar R12, parameter diluluskan dalam daftar R0-R3, dan nilai pulangan diletakkan dalam R0.
Panggilan:
· 0 = Hentikan simulasi
· 1 = cetak nombor perpuluhan
· 2 = cetak aksara
· 3 = Dapatkan saiz RAM
· 4 = operasi peranti blok (R0 = operasi, R1 = nombor sektor). Ambil perhatian bahawa ini tidak menulis kepada RAM yang dicontohi, mereka menggunakan hypercall lain untuk mengisi penimbal dalaman emulator yang diakses oleh pengguna yang ditiru, satu perkataan pada satu masa. Saya berniat untuk melaksanakan DMA, tetapi masih belum mencapainya.
Operasi:
· 0 = Dapatkan maklumat (jika nombor sektor ialah 0, kembalikan bilangan sektor; jika nombor sektor ialah 1, kembalikan saiz sektor dalam bait)
· 1 = dibaca sektor
· 2 = tulis sektor
· 5 = menyekat akses penimbal peranti (R0 = nilai masuk/nilai keluar, R1 = bilangan perkataan, R2 = 1 jika ditulis, 0 sebaliknya)
***▍*Sokongan ibu jari?
Sokongan penuh untuk Thumb. Saya menipu sedikit dan menyahkod setiap rentetan arahan Thumb (instr) ke dalam rentetan arahan ARM yang setara dan melaksanakannya dan bukannya menggunakan fungsi emulator ARM. Ia tidak sepantas yang asal, tetapi ia mudah dan kodnya kecil. Anda boleh menggunakan jadual carian 256KB, tetapi saya merasakan 256KB terlalu besar untuk memori denyar mikropengawal. Sesetengah arahan Thumb tidak boleh ditukar kepada arahan ARM, sebaliknya ia diproses dengan betul.
Saya mahu membina satu!
Untuk tujuan bukan komersial, anda pasti boleh melakukan ini. Kaedah pendawaian adalah seperti berikut:
· DQ0-DQ7 RAM disambungkan ke C0-C7 AVR
· Sambungkan A0-A7 RAM ke A0-A7 AVR;
· Sambungkan A8-A11 RAM kepada B0-B3 AVR;· RAM nRAM nRAS nCAS nWE sambungkan AVR D7 B4 B5
· DI SCK DO SD menghubungkan B6 B7 D6 AVR;
· Tulisan baca LED disambungkan ke D2 D3 AVR (pin LED lain disambungkan ke tanah).
· Butang disambungkan ke D4 AVR (pin lain disambungkan ke tanah).
RAM boleh menjadi mana-mana SIMM 30-pin 16MB yang boleh berjalan pada kadar penyegaran CAS-sebelum-RAS sebanyak 4000 kitaran setiap 64 milisaat. Yang saya gunakan (OWC) boleh dibeli dalam talian dengan harga beberapa dolar. Skema ditunjukkan di sini, klik untuk membesarkan.
***▍*
Kod sumber?Kod ini agak kemas, tetapi ia berfungsi (kod tidak boleh dimuat turun di China). Untuk menyediakan emulator pada PC anda dan mencubanya taip "make". Untuk menjalankan gunakan "./uARM DISK_IMAGE". Untuk membina versi PC yang dioptimumkan gunakan "make BUILD=opt". Untuk membina versi AVR yang sedang berjalan gunakan "make BUILD=avr". Kini, ia disusun untuk menyasarkan ATmega1284P. Untuk menyusun dengan ATmega644 sebagai sasaran, selain mengubah suai makefile, kurangkan nombor dalam icache.h supaya i-cache cukup kecil untuk dipadankan dengan RAM di dalam 644. Turut disertakan dalam arkib ialah fail hex akhir untuk 1284p.
▍Proses permulaan
Untuk mengekalkan ruang kod dalam AVR, hampir tiada kod permulaan wujud dalam emulator. Sebenarnya, "ROM" berjumlah 50 bait: 8 bait digunakan untuk memilih mod Thumb, dan beberapa kod Thumb membaca sektor pertama kad SD dan melompat ke mod Thumb (lihat embeddedBoot.c). MBR kad SD mempunyai pemuat but lain (ditulis dalam mod Thumb). Pemuat but ini melihat MBR, mencari partition aktif dan memuatkan kandungannya ke penghujung RAM. Kemudian, ia melompat ke alamat RAM destinasi +512 (lihat mbrBoot.c). Pemuat but ketiga dan terbesar, ELLE (lihat ELLE.c), dijalankan di sini. Pemuat but ini menempatkan semula ramdisk, menyediakan ATAGS, dan memanggil kernel. Saya menyediakan semua binari dan kod sumber supaya anda boleh membuat imej anda sendiri jika anda mahu. Proses but mengingatkan but PC. :) Alat mkbooting.sh yang disertakan boleh digunakan untuk mencipta imej yang berfungsi untuk partition but.
Atas ialah kandungan terperinci Bolehkah Linux berjalan pada MCU 8-bit?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!