Setting up “autologin” on a gumstix running the 3.5 kernel (yocto, poky, et. al.)
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.