The gumstix.org wiki has a page on how to configure your gumstix to auto-login on boot.  This can be very nice for “production” systems where the intention is to power on and run some specific firmware/code every time.

However, with the new Yocto/Poky images based on the 3.5 kernel, things have changed and the old instructions no longer work.  Here is a quick recipe to get autologin running again on the newer systems.  First of all credit to http://fedoraproject.org/wiki/Systemd for their section on setting up autologin on a virtual terminal with the new systemd architecture.

Step #1:

Compile this “autologin.c” program and install it to /sbin/autologin (make sure you have executable permissions, etc. etc.)

#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main()
{
       int nrv = 0;
       FILE* fptr = 0;
       char user[64];

       // clear buffer
       memset(user,'\0',64);

       // open autologin profile file
       fptr = fopen("/etc/autologin.profile\0","r\0");

       // make sure the file exists and was opened
       if (fptr != 0)
       {
               // the return value from fscanf will be 1 if the autologin profile name is read correctly
               nrv = fscanf(fptr,"%s\0",user);
       }

       // only autologin if the profile name was read successfully,
       // otherwise show the regular login prompt
       if (nrv > 0)
               nrv = execlp("login\0","login\0","-f\0",user,0);
       else
               nrv = execlp("login\0","login\0","\0",0,0);

       return 0;
}

Step #2

Create the /etc/autologin.profile file by running:

echo "root" > /etc/autologin.profile

The autologin program looks for this file to determine which user id should be autologged in.

Step #3

Setup the systemd configuration.

cp /lib/systemd/system/serial-getty@.service /etc/systemd/system/autologin@.service
ln -sf /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/serial-getty@ttyO2.service
cd /etc/systemd/system/getty.target.wants/
vi serial-getty@ttyO2.service

Next, change the line that reads”

ExecStart=-/sbin/agetty -s %I 115200

to read:

ExecStart=-/sbin/agetty -n -l /sbin/autologin -s %I 115200

Troubleshooting

  • If you still get a login prompt, make sure you created the /etc/autologin.profile file correctly, the autologin program needs that or it will just execute a standard login prompt.

Step #4

You may find yourself in a situation where you may not always want your code executed automatically.  You may want an option to “break in” and get a prompt.  There are many ways you could do this, but here’s one simple way:

Compile the “pressanykey.c” code and install the executable in /sbin/pressanykey

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>

int kbhit(void)
{
    fd_set rfds;
    struct timeval tv;
    int retval;
    struct termios term, oterm;
    int fd = 0;
    tcgetattr( fd, &oterm );
    memcpy( &term, &oterm, sizeof(term) );
    cfmakeraw(&term);
    tcsetattr( fd, TCSANOW, &term );
    /* Watch stdin (fd 0) to see when it has input. */
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    /* Wait up to one seconds. */
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    retval = select(1, &rfds, NULL, NULL, &tv);
    /* Don't rely on the value of tv now! */
    tcsetattr( fd, TCSANOW, &oterm );
    return(retval);
}

int mygetch( ) {
    struct termios oldt, newt;
    int ch;
    tcgetattr( STDIN_FILENO, &oldt );
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
    return ch;
}

int main(int argc, char **argv) {
    int count = 5;

    if ( argc > 1 ) {
	int tmp = atoi(argv[1]);
	if ( tmp > 0 ) {
	    count = tmp;
	}
    }

    printf("Press any key ... ");
    fflush(stdout);

    while ( count >= 0 ) {
	printf("%d ", count);
	fflush(stdout);

	//int result = mygetch();
	if ( kbhit() ) {
	    return 1;
	}
	//sleep(1);
	count--;
    }

    return 0;
}

Next create a ~/.profile file that includes the following:

/sbin/pressanykey 5
  if [ $? != 0 ]; then
    echo "Starting interactive shell"
  else
    echo "Continuing with default"
    /path/to/my/code
  fi

Now, along with autologging in as root (or which every user you specified) you will then be presented with a count down timer similar to the “u-boot” timer where you can press any key to get a shell prompt, or continue to your firmware code if no interaction is required.