Skip to content

Instantly share code, notes, and snippets.

Created October 1, 2013 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/6787023 to your computer and use it in GitHub Desktop.
Save anonymous/6787023 to your computer and use it in GitHub Desktop.
ioctl wrapper, kcard_handler, and custom rcS
/*
https://www.gnu.org/software/libc/manual/html_node/
Compilation:
CTARGET=arm-buildroot-linux-uclibcgnueabi
CFLAGS="-Wall -Os -pipe -static -marm -mcpu=arm9e -march=armv5te -mtune=arm926ej-s -mfpu=vfp -mabi=aapcs-linux -mfloat-abi=soft -msoft-float -fno-stack-protector -fno-common -ffixed-r8 -ffreestanding"
BRPATH=/path/to/buildroot-2013.08.1/output/host
"$BRPATH/usr/bin/$CTARGET-gcc" -o ioctl ioctl.c $CFLAGS -I"$BRPATH/usr/$CTARGET/sysroot/usr/include"
"$BRPATH/usr/bin/$CTARGET-strip" -s ioctl
trap 'echo USR1: $(ioctl /dev/ka-main 0x17 .s)' USR1
ioctl /dev/ka-main 0x20
ioctl /dev/ka-main 0x12 .s 10
ioctl /dev/ka-main 0x16 .p $$
*/
#include <errno.h> // errno, ERANGE
#include <fcntl.h> // open, O_RDWR
#include <limits.h> // LONG_MAX, LONG_MIN
#include <stdio.h> // fprintf, perror, printf
#include <stdlib.h> // exit, EXIT_FAILURE, strtol
#include <string.h> // strcmp
#include <sys/ioctl.h> // ioctl
#include <sys/stat.h> // stat, S_ISCHR
#include <unistd.h> // close
#define OPT_SELF 0
#define OPT_DEVICE 1
#define OPT_COMMAND 2
#define OPT_TYPE 3
#define OPT_ARGUMENT 4
#define BASE_AUTO 0
#define CHAR_NULL '\0'
#define ARG_I "i"
#define ARG_IP ".i"
#define ARG_PP ".p"
#define ARG_SP ".s"
#define FCN_DEFAULT 0
#define FCN_I 1
#define FCN_IP 2
#define FCN_PP 3
#define FCN_SP 4
const char help[] =
"Usage: %s device command [type [argument]]\n"
" device character device to interact with\n"
" command operation to perform (integer)\n"
" type one of the following:\n"
" i int\n"
" .i &int\n"
" .p &pid_t\n"
" .s &short\n"
" argument value stored in type\n"
"Output: value from passing type/pointer during ioctl\n"
"Exit status: return value of ioctl syscall\n";
void panic (char *str);
#define panic(str) { perror(str); exit(EXIT_FAILURE); }
void
stat_wrapper (const char *file)
{
struct stat fs;
if (stat(file, &fs) == -1)
panic("stat");
if (S_ISCHR(fs.st_mode) == 0) {
fprintf(stderr, "stat: Is not a character device\n");
exit(EXIT_FAILURE);
}
}
int
strtol_wrapper (const char *str, int fd)
{
char *end;
int val = strtol(str, &end, BASE_AUTO);
if (errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
panic("strtol");
if (*end == CHAR_NULL)
return val;
if (fd != -1)
close(fd);
fprintf(stderr, "strtol: Failed to parse string\n");
exit(EXIT_FAILURE);
}
int
open_wrapper (const char *file)
{
int fd = open(file, O_RDWR);
if (fd == -1)
panic("open");
return fd;
}
int
main (int argc, char *argv[])
{
int cmd, fcn = FCN_DEFAULT, fd = -1, ret;
argc--;
if (argc < OPT_COMMAND || argc > OPT_ARGUMENT) {
fprintf(stderr, help, argv[OPT_SELF]);
exit(EXIT_FAILURE);
}
stat_wrapper(argv[OPT_DEVICE]);
cmd = strtol_wrapper(argv[OPT_COMMAND], fd);
if (argc >= OPT_TYPE) {
if (strcmp(argv[OPT_TYPE], ARG_I) == 0)
fcn = FCN_I;
else if (strcmp(argv[OPT_TYPE], ARG_IP) == 0)
fcn = FCN_IP;
else if (strcmp(argv[OPT_TYPE], ARG_PP) == 0)
fcn = FCN_PP;
else if (strcmp(argv[OPT_TYPE], ARG_SP) == 0)
fcn = FCN_SP;
else {
fprintf(stderr, "strcmp: Unsupported type\n");
exit(EXIT_FAILURE);
}
}
fd = open_wrapper(argv[OPT_DEVICE]);
switch (fcn) {
case FCN_I: {
if (argc != OPT_ARGUMENT) {
close(fd);
fprintf(stderr, "type: Argument required\n");
exit(EXIT_FAILURE);
}
int val = strtol_wrapper(argv[OPT_ARGUMENT], fd);
ret = ioctl(fd, cmd, val);
break;
}
case FCN_IP: {
int val;
if (argc == OPT_ARGUMENT)
val = strtol_wrapper(argv[OPT_ARGUMENT], fd);
ret = ioctl(fd, cmd, &val);
if (argc == OPT_TYPE)
printf("%i", val);
break;
}
case FCN_PP: {
pid_t val;
if (argc == OPT_ARGUMENT)
val = strtol_wrapper(argv[OPT_ARGUMENT], fd);
ret = ioctl(fd, cmd, &val);
if (argc == OPT_TYPE)
printf("%i", val);
break;
}
case FCN_SP: {
short val;
if (argc == OPT_ARGUMENT)
val = strtol_wrapper(argv[OPT_ARGUMENT], fd);
ret = ioctl(fd, cmd, &val);
if (argc == OPT_TYPE)
printf("%d", val);
break;
}
default:
ret = ioctl(fd, cmd, NULL);
}
close(fd);
exit(ret);
}
#!/bin/sh
DEV=/dev/ka-main # Character device created by /lib/ka2000-sdhc.ko ?
# /dev/ka-pwm, /dev/ka-pwm1 # Undocumented
# Obtained from busybox-1.20.2_KA/kcard/kcard_app.c:
KCARD_DISABLE_USERCALL=0x10 # Disable sending SIGUSR1 to registered PID
KCARD_ENABLE_USERCALL=0x11 # Enable sending SIGUSR1 to registered PID
KCARD_SET_USERCALL_INTERVAL=0x12 # Set SIGUSR1 period in seconds
KCARD_RESCAN_IMAGES=0x13 # Rescan for control images ?
KCARD_DEL_PROGRAM_BIN=0x14 # Undocumented
KCARD_SET_PID=0x16 # Register PID to periodically receive SIGUSR1
KCARD_GET_CMD=0x17 # Get signal from driver during SIGUSR1 handler
KCARD_DISABLE_SLEEP=0x20 # Disable ARM sleep
KCARD_ENABLE_SLEEP=0x21 # Enable ARM sleep
KCARD_STOP_CTRL_IMG_CHECK=0x22 # Disable control image check ? (SWITCH_STOP_CTRL_IMG_CHECK)
KCARD_TRIGGER_FULL_RANGE=0x23 # ? (bomb reg 21f8 - 30fc)
KCARD_GO_SLEEP=0x99 # Undocumented
KCARD_WAKEUP=0x100 # Undocumented
KCARD_SIG_DEL_IMG_0=1 # Delete control image /mnt/sd/DCIM/199_WIFI/WSD00001.JPG
KCARD_SIG_DEL_IMG_1=2 # Delete control image /mnt/sd/DCIM/199_WIFI/WSD00002.JPG
KCARD_SIG_DEL_IMG_2=3 # Delete control image /mnt/sd/DCIM/199_WIFI/WSD00003.JPG
KCARD_SIG_DEL_IMG_3=4 # Delete control image /mnt/sd/DCIM/199_WIFI/WSD00004.JPG
KCARD_SIG_DPOF=6 # Undocumented
KCARD_SIG_UPDATED=7 # Files have changed on the card, should perform full umount/mount
KCARD_SIG_NO_IMGS=8 # No control images were detected ?
KCARD_SIG_SCAN=9 # Rescan for control images ?
KCARD_SIG_SLEEP=99 # Re-setup SIGUSR1 handler ?
KCARD_SIG_WAKEUP=100 # Re-setup SIGUSR1 handler ?
refresh_sd() {
# mount -o remount /mnt/sd WILL NOT WORK! mount triggers specific behavior somehow
sync && umount /mnt/sd && mount /mnt/sd
}
sigusr1() {
ioctl $DEV $KCARD_DISABLE_USERCALL
trap - USR1
local cmd=$(ioctl $DEV $KCARD_GET_CMD .s)
echo "kcard_handler: get_cmd=$?, cmd=$cmd"
refresh_sd
trap sigusr1 USR1
ioctl $DEV $KCARD_ENABLE_USERCALL
}
trap sigusr1 USR1
# These tend to exit with -1 (255) on failure
ioctl $DEV $KCARD_DISABLE_SLEEP # kcard_cmd -s 0
#[todo] type should be int, but ioctl fails
ioctl $DEV $KCARD_SET_USERCALL_INTERVAL .s 10 # kcard_startup -s 0
#ioctl $DEV $KCARD_STOP_CTRL_IMG_CHECK
ioctl $DEV $KCARD_SET_PID .p $$ # kcard_app --nohidden &
while true; do sleep 1; done
#!/bin/sh
date -s 201301010000
echo 2 > /proc/sys/vm/overcommit_memory
echo 100 > /proc/sys/vm/overcommit_ratio
ifconfig lo 127.0.0.1 up
mkdir -p /mnt/mtd /mnt/sd
insmod /lib/ka2000-sdhc.ko max_sd_blk=8
sleep 1
cat <<"EOF" > /etc/fstab
none /dev/pts devpts mode=0622 0 0
/dev/mtdblock0 /mnt/mtd jffs2 noatime,nodiratime 0 0
/dev/mmcblk0p1 /mnt/sd vfat shortname=winnt 1 1
EOF
mount -a
if [ -f /mnt/sd/program.bin ]; then
for file in program.bin image3 initramfs3.gz mtd_jffs2.bin; do
rm -f "/mnt/sd/$file"
done
fi
[ -x /usr/bin/kcard_handler ] && kcard_handler &
:<<"REMOVE_THIS_LINE_TO_ENABLE_WIFI"
insmod /lib/ar6000.ko
insmod /lib/ka2000-sdio.ko
sleep 1
ifconfig mlan0 10.0.0.1 netmask 255.255.255.0 up
iwconfig mlan0 power off
cat <<"EOF" > /etc/hostapd.conf
interface=mlan0
ssid=WIFISD
EOF
hostapd -B /etc/hostapd.conf
REMOVE_THIS_LINE_TO_ENABLE_WIFI
if [ -f /mnt/sd/autorun.sh ]; then
chmod 777 /mnt/sd/autorun.sh
/mnt/sd/autorun.sh
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment