Lexmark E352dn

Questa stampante laser, acquistata usata, è la nuova aggiunta alla mia rete locale che si stà facendo via via più affollata.

Si va a sostituire ad una Epson 6200L. Il motivo principale di questa sostituzione è la praticità: mentre la 6200L ha connettività solo attraverso porta parallela oppure USB la E352dn si può anche collegare alla rete, rendendo possibile stampare da qualsiasi macchina collegata alla rete locale. Inoltre la E352dn supporta tutti i sistemi operativi di mio interesse (riportando dai dati tecnici: “Virtualmente qualsiasi piattaforma che supporti TCP/IP”), mentre con la 6200L ho avuto qualche “piccolo” problema.

Naturalmente il problema della stampa da più postazioni si sarebbe potuto risolvere in modo diverso, ad esempio rendendo la Ultra 1 che uso come server multiuso anche un print server, ma sarebbe stato sicuramente più laborioso e mi avrebbe costretto ad avere la Ultra 1 accesa più spesso di quanto desideri. Inoltre, attendere il boot di una Ultra 1 soltanto per stampare un documento, magari di una singola pagina, dal portatile? No, grazie.

Ho già testato la stampante, anche se devo fare l’ultima fatidica prova, la stampa su carta trasparente da lucido, indispensabile per le fotoincisioni. Mi sembra sia più veloce e più silenziosa rispetto alla 6200L e, cosa che non guasta, stampa fronte-retro automaticamente.

Si può configurare la stampante attraverso il browser ed ha tante, davvero tante impostazioni. Configurare Solaris 10 per usarla è stato veloce ed indolore, il passaggio più difficile è stato trovare l’indirizzo IP che era stato assegnato alla stampante per poi assegnargliene uno nuovo adatto alla mia rete locale.

Insomma, è operativa da appena una giornata ma inizia molto bene.

A. C.

Posted in Hardware, Solaris | Leave a comment

Solaris 10 e gcc

Altro post-promemoria.

Supponiamo di avere appena installato Solaris 10 (nel mio caso, per macchine SPARC, ma suppongo lo stesso valga nel caso di macchine x86) e supponiamo anche che sia sia scelta l’installazione completa con supporto OEM.

Con il sistema fresco d’installazione provare a richiamare da un terminale gcc non dà il risultato sperato: gcc: non found

La soluzione è molto facile e veloce, basta aggiungere alla variabile d’ambiente PATH la directory /usr/sfw/bin

Per farlo è sufficiente modificare il file .profile presente nella home dell’utente che intende usare gcc.

Nella stessa directory è presente anche gmake cioè il GNU make nel caso servisse.

Naturalmente aggiungere /usr/sfw/bin non è sufficiente per compilare correttamente pacchetti software. La via più rapida è aggiungere alla variabile d’ambiente PATH un’altra directory, /usr/ccs/bin ottenendo così un’ambiente funzionante per compilare programmi da sorgente.

A.C.

Posted in Software, Solaris | Leave a comment

Divertirsi con i puntatori a funzioni in C

Questo post nasce da quattro chiacchiere scambiate con un buon amico. Per qualche motivo la discussione deve essere scivolata sui valori restituiti dalle funzioni e sulle stravaganze del codice scritto in C.

Qualcosa mi è rimasto in mente, una domanda che aveva una risposta istintiva ma che non avrei saputo completamente. Come risultato mi son trovato a scrivere un pò di codice.

La domanda: Una funzione di tipo void può restituire un valore?

La risposta è chiaramente sì.

Tutto il codice seguente non è “buon codice” dato che dà per scontata l’architettura x86 e quindi puntatori ed interi a 32 bit. I risultati possono essere simili con qualche modifica al codice per l’architetture x64 ma anche tremendamente diversi usando, ad esempio, l’architettura SPARC V9.

Iniziamo con il codice di una funzione estremamente banale:

void mock_function()
{
printf("Hi there!\n");
return 10;
}

Questa funzione viene accettata da un compilatore, ma genererà sicuramente un warning, ad esempio in gcc il warning sarà del tipo warning: ‘return’ with a value, in function returning void

Supponiamo di avere una variabile int i. La seguente riga di codice non incontrerà il favore del compilatore generando, anzichè un warning, un errore e impedendo la compilazione.

i = mock_function();

Il che è ragionevole, ma poco interessante. Per fortuna, grazie ai puntatori, il problema è risolto molto velocemente.

void *(*function_pointer)();
function_pointer = mock_function;

A questo punto il compilatore accetta il seguente codice, probabilmente con due warning: assegnazione ad un intero di un puntatore senza cast e assegnazione tra puntatori non compatibili.

i = function_pointer();

Vediamo un programma d’esempio:

#include "stdio.h"
void mock_function();
int main (int argc, char *argv[])
{
int i;
void *(*function_pointer)();
function_pointer = mock_function;
i = function_pointer();
printf("%d\n");
return 0;
}
void mock_function()
{
printf("Hi there!\n");
return 10;
}

A parte alcuni warning, il programma viene compilato senza errori in un eseguibile.

Supponendo di averlo compilato su una macchina basata su architettura x86 sono ragionevolmente convinto che il programma stamperà a schermo il risultato 10.

Naturalmente c’è il trucco. Il seguente frammento di codice nella funzione non serve assolutamente a restituire il valore 10.

return 10;

Scrivendo return 9; la funzione continuerebbe a restituire 10. Anche scrivendo return;

Perchè?

Tutto dipende dalla convenzione di chiamata. Quando viene richiamata una funzione deve esistere un modo ben definito per passare alla funzione stessa gli argomenti e per ricevere dalla funzione il valore che essa ritorna.

Esistono diverse convenzioni di chiamata ma nell’architettura x86 generalmente il valore restituito da una funzione si trova in un registro, per la precisione il registro EAX.

Si tratta certamente di una semplificazione esagerata ma per il codice di esempio è sufficiente.

La funzione mock_function() è di tipo void, quindi non restituisce nulla. i = mock_function(); non funziona perchè il compilatore ragionevolmente rifiuta di generare un binario in cui il contenuto del registro EAX venga spostato nella variabile i per poi essere utilizzato.

Ma dato che i puntatori sono tutti uguali, è possibile assegnare l’indirizzo di mock_function() ad un puntatore di tipo void *(*function_pointer)() ingannando il compilatore. Richiamando function_pointer() il compilatore si aspetta che la funzione ritorni un puntatore a void, quindi i = function_pointer() genera un binario in cui il contenuto del registro EAX viene spostato nella variabile i. Naturalmente, nell’architettura x86, sia gli int che i puntatori sono a 32 bit, quindi è possibile passare da intero a puntatore e viceversa ma non è necessariamente così in altre architetture.

Come è possibile far assumere un valore arbitario al registro EAX?

Si potrebbe usare dell’assembly inline, ad esempio il compilatore di Microsoft Visual C++ 2010 Express accetta il seguente codice

__asm mov eax, 10;

mentre gcc gradisce il seguente

asm ("movl $10, %eax");

Una piccola nota per chi fosse curioso: il primo spezzone di codice è scritto in sintassi Intel, mentre il secondo è scritto seguendo la sintassi AT&T.

La funzione modificata diventerebbe

void mock_function()
{
printf("Hi there!\n");
asm ("movl $10, %eax");
return;
}

Tuttavia, il codice originario restituise 10 senza utilizzare assembly inline. Qualcuno potrebbe chiedersi perchè ma la risposta è molto semplice: la funzione printf() manipola il registro EAX dato che restituisce il numero di caratteri scritti.

La stringa “Hi there!\n” è esattamente di 10 caratteri.

A.C.

Posted in Programming, Software | Leave a comment

Rompere il fiato

Decidere di fare una corsa in pieno inverno…

Evidente cortocircuito dei miei neuroni.

Coprire un pò più di 2 Km in meno di 20′…

Qualche parte di polmone.

Riuscire ancora a rompere il fiato…

Non.
Ha.
Prezzo.

Posted in Uncategorized | Leave a comment

It has arrived.

And now… let’s play.

R_b

Posted in Hardware | Leave a comment

“The IDPROM contents are invalid”

Seconda volta che mi capita di vedere questo messaggio.

Il significato è chiaro, anzi chiarissimo: la batteria della NVRAM è andata.

La prima volta che ho visto il messaggio si trattava della mia Ultra 1. Stavolta si tratta sempre di una macchina sun4u ma purtroppo è la mia macchina principale, la classica Ultra 10.

La riparazione non è difficile, ma è piuttosto laboriosa, visto che la batteria della NVRAM è integrata nel chip della NVRAM, ovvero il chip e la batteria sono annegati in un unico blocco di resina con il risultato che per raggiungere la batteria sono necessari taglierino e pazienza.

Naturalmente esiste anche la possibilità di trovare una nuova NVRAM, ma non penso proprio che seguirò questa strada.

Per ogni evenienza a suo tempo presi una Ultra 5 per avere una macchina spare, quindi anche nel caso le cose andassero male la potrò eventualmente cannibalizzare per rimettere in sesto la Ultra 10.

Comunque stavolta ho in programma di documentare qui più in dettaglio il processo di riparazione dal punto di vista hardware, partendo da questa guida.

r_b

Posted in Hardware | Leave a comment

Anniversario

Un anno in più.

Riferendomi spudoratamente ad una vignetta di xkcd.org: ancora due anni e poi si arriva ad una bella cifra tonda.

r_b

Posted in Uncategorized | Leave a comment

NAS Skintek

Due parole per spiegare che cos’è l’oggetto di cui parlerò: si tratta di una enclosure per hd PATA a cui oltre che via USB è possibile anche collegarsi attraverso una connessione di rete.

Visto che l’oggetto aveva un costo irrisorio, visto che di hd pata ne ho ancora parecchi in giro e visto che avevo voglia di provare ad integrare un NAS nella mia rete locale l’ho comprato senza aspettarmi nulla di che.

Naturalmente collegarsi via USB non dà problemi.

Qualche problema c’è invece con la connessione via rete.

Ora, attenzione: le seguenti operazioni hanno funzionato sulla mia unità e le scrivo qui più che altro come promemoria, non mi prendo alcuna responsabilità nel caso non fuzioni e/o danneggi l’hardware.

Detto questo, la sequenza di operazioni:

1) Configurare la scheda ethernet del proprio computer come client dhcp
2) Collegare con un cavo ethernet diretto il NAS al proprio computer
3) Verificare che la scheda di rete abbia ricevuto un indirizzo del tipo 169.254.170.xxx con xxx variabile tra 2 e 254
4) Individuare il MAC del server dhcp (ovvero il MAC del NAS).
5) Aprire un browser
6) Collegarsi a http://STORAGE-abcd dove abcd sono gli ultimi 4 caratteri alfanumerici del MAC del server dhcp
7) Verranno richieste username e password. Inserire rispettivamente admin e admin
8) Configurare a piacere

A questo punto si può iniziare ad utilizzare il NAS.

Un’ultima nota: se sapete bene ciò che state facendo, potreste essere in grado di aggiornare il firmware. Naturalmente questo espone al rischio di rendere inutilizzabile l’interfaccia di rete del NAS ma teoricamente l’interfaccia USB dovrebbe ancora funzionare.

Posted in Uncategorized | Leave a comment

Happy 2012!

Un anno è appena finito, un anno è appena iniziato.

Felice 2012 a tutti!

r_b

Posted in Ramblings, rolling_bean | Leave a comment

Buon Natale

Esattamente come c’è scritto nel titolo:

Buon Natale a tutti!

Posted in Hardware, rolling_bean | Leave a comment