Vai al contenuto
PLC Forum


Linux su SoC


del_user_97632

Messaggi consigliati

Pensavo di illustrare, per chi interessato, come si installa Linux su un dispositivo embedded.

 

Piuttosto che i soliti arm, supponiamo la scheda monti un SoC ColdFire mcf54415, 250Mhz, big endian.

SoC = system on chip, composto da un core + vari moduli hardware incorporati.

 

Per ora spiego a grandi linee, se poi a qualcuno interessa lo espando.

 

 

U-Boot 2019.07-rc4-00284-ge485d1cce0-dirty (Jun 23 2019 - 22:47:15 +0200)

CPU:   Freescale MCF54415 (Mask:a0 Version:2)
       CPU CLK 240 MHz BUS CLK 120 MHz FLB CLK 60 MHz
       INP CLK 30 MHz VCO CLK 480 MHz
DRAM:  128 MiB
MMC:   FSL_SDHC: 0
Loading Environment from SPI Flash... SF: Detected is25lp128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB
OK
In:    uart@fc060000
Out:   uart@fc060000
Err:   uart@fc060000
Hit any key to stop autoboot:  0 
2512928 bytes read in 565 ms (4.2 MiB/s)
339588 bytes read in 143 ms (2.3 MiB/s)
## Booting kernel from Legacy Image at 40001000 ...
   Image Name:   mainline kernel
   Created:      2019-09-02  23:38:34 UTC
   Image Type:   M68K Linux Kernel Image (uncompressed)
   Data Size:    2512864 Bytes = 2.4 MiB
   Load Address: 40001000
   Entry Point:  40001000
   Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 41001000 ...
   Image Name:   stmark2 initramfs image
   Created:      2019-03-29  20:03:58 UTC
   Image Type:   M68K Linux RAMDisk Image (gzip compressed)
   Data Size:    339524 Bytes = 331.6 KiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
   Loading Ramdisk to 47d33000, end 47d85e44 ... OK
[    0.000000] Linux version 5.3.0-rc4stmark2-001-00062-g0e56ad36affd-dirty (angelo@dfj) (gcc version 5.2.0 (crosstools-sysam-2016.04.16)) #329 Tue Sep 3 01:38:33 CEST 2019
[    0.000000] initrd at 0x47d33000:0x47d85e44
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 16312
[    0.000000] Kernel command line:  console=ttyS0,115200 root=/dev/ram0 rw rootfstype=ramfs rdinit=/sbin/init devtmpfs.mount=1
[    0.000000] Dentry cache hash table entries: 16384 (order: 3, 65536 bytes, linear)
[    0.000000] Inode-cache hash table entries: 8192 (order: 2, 32768 bytes, linear)
[    0.000000] Sorting __ex_table...
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 127544K/131072K available (1844K kernel code, 115K rwdata, 408K rodata, 72K init, 273K bss, 3528K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=16, Order=0-3, MinObjects=0, CPUs=1, Nodes=8
[    0.000000] NR_IRQS: 256
[    0.000000] clocksource: pit: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1019338904850 ns
[    0.000000] Console: colour dummy device 80x25
[    0.070000] Calibrating delay loop... 237.15 BogoMIPS (lpj=1185792)
[    0.080000] pid_max: default: 32768 minimum: 301
[    0.080000] Mount-cache hash table entries: 2048 (order: 0, 8192 bytes, linear)
[    0.080000] Mountpoint-cache hash table entries: 2048 (order: 0, 8192 bytes, linear)
[    0.110000] devtmpfs: initialized
[    0.140000] random: get_random_u32 called from bucket_table_alloc+0x13c/0x15e with crng_init=0
[    0.140000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.140000] futex hash table entries: 256 (order: -2, 3072 bytes, linear)
[    0.330000] clocksource: Switched to clocksource pit
[    0.340000] FS-Cache: Loaded
[    0.540000] Unpacking initramfs...
[    1.200000] Freeing initrd memory: 320K
[    1.210000] workingset: timestamp_bits=27 max_order=14 bucket_order=0
[    1.470000] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    1.480000] romfs: ROMFS MTD (C) 2007 Red Hat, Inc.
[    1.480000] io scheduler mq-deadline registered
[    1.480000] io scheduler kyber registered
[    2.560000] random: fast init done
[    2.680000] ColdFire internal UART serial driver
[    2.690000] mcfuart.0: ttyS0 at MMIO 0xfc060000 (irq = 90, base_baud = 7500000) is a ColdFire UART
[    2.900000] printk: console [ttyS0] enabled
[    2.910000] mcfuart.0: ttyS1 at MMIO 0xfc064000 (irq = 91, base_baud = 7500000) is a ColdFire UART
[    2.920000] mcfuart.0: ttyS2 at MMIO 0xfc068000 (irq = 92, base_baud = 7500000) is a ColdFire UART
[    2.930000] mcfuart.0: ttyS3 at MMIO 0xfc06c000 (irq = 93, base_baud = 7500000) is a ColdFire UART
[    2.960000] sdhci: Secure Digital Host Controller Interface driver
[    2.960000] sdhci: Copyright(c) Pierre Ossman
[    2.970000] sdhci-pltfm: SDHCI platform and OF driver helper
[    2.970000] mmc0 bounce up to 128 segments into one, max segment size 65536 bytes
[    3.030000] mmc0: SDHCI controller on sdhci-esdhc-mcf.0 [sdhci-esdhc-mcf.0] using DMA

Greetings !

For further information check: http://www.sysam.it

/ # [  104.750000] random: crng init done

/ # 
/ # ls
bin      etc      linuxrc  proc     srv      usr
boot     home     mnt      root     sys      var
dev      lib      opt      sbin     tmp
/ # 

 

1) Prima cosa, servre un boot loader, per i SoC, chiamato in genere "secondary boot loader" (il primary e' il ROM bootloader). Il bootloader viene caricato nella ram statica interna del SoC dal ROM bootloader (ram statiche interne che vanno in genere da 4K a 512K e oltre). Il suo compito principale e' di inizializzare le ddr/sdram esterne e caricare linux nella ram dinamica. Il piu comune per sistemi embedded e' "U-boot". Dunque va verificato che l'architettura su cui il bootloader deve girare sia supportata. Nei sorgenti U-boot si vede:

 

arch/m68k/coldfire/m5441x.c      <-- e' supportata

 

Si procede dunque a creare il supporto per la scheda e i file di configurazione. Per ora tralascio, si trovano esempi nelle mille schede gia supportate. Con un po di esperienza di C, si parte da una scheda simile, stessa cpu, si copiano i file di scheda che si trovano in "include/configs" "configs" e "board"  e si modifica / toglie / aggiunge qualche parte.

 

Il bootloader va configurato appositamente, a seconda del supporto da cui vierne letto e a quello da cui leggera' il kernel. Di solito il bootloader si trova su una flash spi nor, qspi.

 

2) Linux, si verifica che l'architettura / cpu sia supportata da Linux. Folder arch/ si verifica aiutandosi anche con grep o da elixir

https://elixir.bootlin.com/linux/latest/source/arch/m68k/coldfire/m5441x.c

e' supportata

 

3) Si scaricano i sorgenti ufficiali linux, da kernel.org e si configura il kernel

 

3.a) personalizzare i "device"

 

La parte piu complessa qui e' indicare i dispositivi situati nella scheda. Nei sistemi embedded, a differenza del PC dove i dispositivi vengono rilevati dinamicamente, vanno dichiarati. E nel kernel si aggiungono solo i driver che servono per gestirli. Per questo bisogna preparare in genere ad esmpio un "devicetree (dts)" (architetture arm piu recenti) o, come per quest'architettura che non supporta i devicetree, si deve creare un board.c file.

 

3.b) personalizzare i driver da includere

 

make menuconfig   (come inizio configurare tutti i driver come buit-in [*])

make savedefconfig

mv defconfig arch/m68k/config/miascheda_defconfig

 

4) si cerca l'apposita toolchain per il SoC in oggetto e si cross-compila

 

export CROSS_COMPILE=/opt/toolchains/m68k/gcc-5.2.0-nolibc/bin/m68k-linux-

export ARCH=m68k

# quest'archittettura richiede un load address, che deve coincidere con quello in cui il kernel verra' caricato in memoria da u-boot

load_addr=0x40001000

 

make miascheda_defconfig

make -j8 KALLSYMS_EXTRA_PASS=1 LOADADDR=${load_addr} zImage

 

5) ora Linux (binario monolitico e' pronto per essere caricato in memoria e eseguito.

 

6) il root file system

Per iniziare, si puo' creare in maniera semplice iun root fil system composto dai soli programmi busybox cross-compilati.

Per iniziare, e' semplice creare un initramfs e inglobarlo nel kernel, o farlo caricare dal bootloader passando al kernel l'indirizzo di memoria dove e' situato (bootm image initramfs).

 

Questo a grandi linee. Per ora ho tralasciato diversi dettagli. Se qualcuno fosse interessato, sono disponibile a trasformarlo in un tutorial piu dettagliato.

 

 

Modificato: da _angelo_
Link al commento
Condividi su altri siti

  • 5 months later...

Sarei interessato a ulteriori info in merito.

Ancora non ho deciso che CPU target utilizzare, e mi mancano molte info base come i requisiti minimi (es. quanta RAM, se MMU è obbligatorio, ecc...).

Ho anche alcune Allwinner A13 che aspettano di essere utilizzate...

Link al commento
Condividi su altri siti

Visto che _angelo_ non aggiorna la discussione dal 3 settembre dello scorso anno ritengo che difficilmente ci saranno novità a breve.

Link al commento
Condividi su altri siti

del_user_97632

Ciao Just4Fun,

 

eccomi qua, avevo postato questa guida cosi per vedere se a qualcuno interessava l'argomento.

 

Per un Linux minimale, da 10 a 16MB per girare possono bastare, ma dipende da quello che devi fare, considerando che un po' di memoria la dovrai probabilmente montare, andrei su DDR2 64MB o 128MB, comunque, a seconda di quello che devi fare.

 

MMU non e' obbligatoria, vedi i vari ColdFire senza MMU su cui gira bene linux, perche ora il codice "no-mmu" che parecchi anni fa era in uClinux e' stato tirato dentro al kernel mainline. Per altro MMU si puo disabilitare da menuconfig.

 

Si, se vuoi farti una scheda in casa Allwinner A13 andrebbe bene, puoi saldarli a mano, pero' il probblema e' che supporta minimo DDR2 che sono tutte BGA. Avresti il problema di saldarli se non hai un attrezzatura adeguata. Se anche le linee tra SoC e DDR2 non sono perfette (adattamento impedenza non corretto o lunghezza) in genere abbassando la frequenza di bus a 150Mhz dovrebbe funzionare. Io sono riuscito con kicad.

 

Ora ci sono SoC + DDR interna che ti evitano il collegamento a una DDR esterna, che puo non essere banale, specie per le DDR3 o 4. Si chiamano SiP (system in package) di sicuro li ho visti con 64MB di DDR interna ma credo ne esistano con ancora piu memoria.

 

 

Saluti

Angelo

 

 

Modificato: da _angelo_
Link al commento
Condividi su altri siti

8 ore fa, _angelo_ ha scritto:

cosi per vedere se a qualcuno interessava l'argomento.

 

aspettavi un trigger per riprenderla;)

Link al commento
Condividi su altri siti

del_user_97632

Ciao Livio,

 

si argomento forse troppo di nicchia, non mi era chiaro quanto interesse ci fosse, comunque, "per quel che ne so", lieto di proseguirlo.

 

Mi hanno chiamato come speaker a parlare a fosdem 2020 dunque questo mese passato non ho seguito il forum, toccato studiare ogni notte. Esperienza scioccante, sala piena di gente, ma in qualche modo e' andata.

 

Qui sotto il boot della prima schedina che ho progettato e saldato qui in casa.

E' un caso ormai obsoleto, "legacy", ma mostra linux in esecuzione su cpu 90Mhz senza mmu, SDRAM da 16MB,

un esempio abbastanza minimale.

 

Nel sistema ci sono:

 

- un semplicissimo ROMFS read-only,

- un symbolic link a una partizione jffs2 dove nel caso salvare dati,

- kernel e rootfs sono in una semplice flash parallela,

- poi semplicemente busybox, e un paio di programmi scritti da me.

 

 

U-Boot 2018.11-rc1-00075-g6a2b3cc131-dirty (Oct 09 2018 - 23:20:03)

CPU:   Freescale Coldfire MCF5307 at 90 MHz
DRAM:  16 MiB
Flash: 4 MiB
Loading Environment from Flash... OK
Hit any key to stop autoboot:  0
## Booting kernel from Legacy Image at ffc30000 ...
   Image Name:   uClinux 3.x Kernel
   Image Type:   M68K Linux Kernel Image (uncompressed)
   Data Size:    2437124 Bytes = 2.3 MiB
   Load Address: 00020000
   Entry Point:  00020000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
init started: BusyBox v1.21.0-uc0 (2018-10-09 23:30:54 CEST)

mount: mounting sysfs on /sys failed: No such device



Welcome to
   
     __ _ _ __ ___   ___ ___  _ __ ___
    / _` | '_ ` _ \ / __/ _ \| '__/ _ \
   | (_| | | | | | | (_| (_) | | |  __/
    \__,_|_| |_| |_|\___\___/|_|  \___|
                                    
                      

For further information check:
http://www.sysam.it



BusyBox v1.21.0-uc0 (2018-10-09 23:30:54 CEST) hush - the humble shell

~ #
~ # cat /proc/meminfo
MemTotal:          13744 kB
MemFree:            5256 kB
MemAvailable:       5064 kB
Buffers:               0 kB
Cached:              688 kB
SwapCached:            0 kB
Active:              128 kB
Inactive:            528 kB
Active(anon):          0 kB
Inactive(anon):        0 kB
Active(file):        128 kB
Inactive(file):      528 kB
Unevictable:           0 kB
Mlocked:               0 kB
MmapCopy:           1368 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:             0 kB
Mapped:                0 kB
Shmem:                 0 kB
Slab:               1288 kB
SReclaimable:        112 kB
SUnreclaim:         1176 kB
KernelStack:         352 kB
PageTables:            0 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:        6872 kB
Committed_AS:          0 kB
VmallocTotal:          0 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
~ #

~ # cat /proc/cpuinfo 
CPU:		COLDFIRE(m5307)
MMU:		none
FPU:		none
Clocking:	88.4MHz
BogoMips:	58.98
Calibration:	29491200 loops
~ # cat /proc/version
uClinux version 4.4.0-uc0amcore-001 (angelo@jerusalem) (gcc version 5.4.0 (GCC) ) #21 Tue Oct 9 23:30:06 CEST 2018

Ci gira il kernel uClinux che e' una vecchia distribuzione orientata alle cpu no-mmu, ma ora dovrebbe girare il kernel mainline senza problemi.

 

Dei 16MB di SDRAM ne restano ancora 5 liberi, ma a parte un bot IRC che ci sta girado, un telnet e un web server, non c'e' altro.

 

Saluti

angelo

 

 

Modificato: da _angelo_
Link al commento
Condividi su altri siti

Ok grazie per le info.

 

Stavo anche valutando un Allwinner V3s che come suggerivi tu ha anche 64MB di RAM interna, oppure un approccio del tipo "retrocomputer" con un 68000.

Nel caso posterò qui eventuali aggiornamenti.

 

Ciao.

 

 

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...