aboutsummaryrefslogtreecommitdiffstats
path: root/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'emulator')
-rw-r--r--emulator/mksdcard/mksdcard.c71
-rw-r--r--emulator/qemud/qemud.c2
-rw-r--r--emulator/tests/Android.mk17
-rw-r--r--emulator/tests/test-qemud-pipes.c113
4 files changed, 179 insertions, 24 deletions
diff --git a/emulator/mksdcard/mksdcard.c b/emulator/mksdcard/mksdcard.c
index c85d0f8..c9a3eeb 100644
--- a/emulator/mksdcard/mksdcard.c
+++ b/emulator/mksdcard/mksdcard.c
@@ -27,7 +27,7 @@
/* a simple and portable program used to generate a blank FAT32 image file
*
- * usage: mksdcard [-l label] <size> <filename>
+ * usage: mksdcard [-l label] <size> <filename>
*/
#include <time.h>
@@ -43,6 +43,10 @@
#define BACKUP_BOOT_SECTOR 6
#define NUM_FATS 2
+/* sectors_per_disk is encoded as a signed int */
+#define MAX_SECTORS_PER_DISK 0x7FFFFFFF
+#define MAX_DISK_SIZE ((Wide)MAX_SECTORS_PER_DISK * BYTES_PER_SECTOR)
+
typedef long long Wide; /* might be something else if you don't use GCC */
typedef unsigned char Byte;
typedef Byte* Bytes;
@@ -53,10 +57,10 @@ typedef Byte* Bytes;
#define POKES(p,v) ( BYTE_(p,0) = (Byte)(v), BYTE_(p,1) = (Byte)((v) >> 8) )
#define POKEW(p,v) ( BYTE_(p,0) = (Byte)(v), BYTE_(p,1) = (Byte)((v) >> 8), BYTE_(p,2) = (Byte)((v) >> 16), BYTE_(p,3) = (Byte)((v) >> 24) )
-static Byte s_boot_sector [ BYTES_PER_SECTOR ]; /* boot sector */
+static Byte s_boot_sector [ BYTES_PER_SECTOR ]; /* boot sector */
static Byte s_fsinfo_sector [ BYTES_PER_SECTOR ]; /* FS Info sector */
-static Byte s_fat_head [ BYTES_PER_SECTOR ]; /* first FAT sector */
-static Byte s_zero_sector [ BYTES_PER_SECTOR ]; /* empty sector */
+static Byte s_fat_head [ BYTES_PER_SECTOR ]; /* first FAT sector */
+static Byte s_zero_sector [ BYTES_PER_SECTOR ]; /* empty sector */
/* this is the date and time when creating the disk */
static int
@@ -172,22 +176,28 @@ fat_init( Bytes fat )
static int
write_sector( FILE* file, Bytes sector )
{
- return fwrite( sector, 1, 512, file ) != 512;
+ int result = fwrite( sector, 1, BYTES_PER_SECTOR, file ) != BYTES_PER_SECTOR;
+ if (result) {
+ fprintf(stderr, "Failed to write sector of %d bytes: %s\n", BYTES_PER_SECTOR, strerror(errno));
+ }
+ return result;
}
static int
write_empty( FILE* file, Wide count )
{
- static Byte empty[64*1024];
+ static Byte empty[256*1024];
+ memset(empty, 0, sizeof(empty));
- count *= 512;
+ count *= BYTES_PER_SECTOR;
while (count > 0) {
int len = sizeof(empty);
if (len > count)
- len = count;
-
- if ( fwrite( empty, 1, len, file ) != (size_t)len )
+ len = count;
+ if ( fwrite( empty, 1, len, file ) != (size_t)len ) {
+ fprintf(stderr, "Failed to write %d bytes: %s\n", len, strerror(errno));
return 1;
+ }
count -= len;
}
@@ -201,6 +211,10 @@ static void usage (void)
fprintf(stderr, " if <size> is a simple integer, it specifies a size in bytes\n" );
fprintf(stderr, " if <size> is an integer followed by 'K', it specifies a size in KiB\n" );
fprintf(stderr, " if <size> is an integer followed by 'M', it specifies a size in MiB\n" );
+ fprintf(stderr, " if <size> is an integer followed by 'G', it specifies a size in GiB\n" );
+ fprintf(stderr, "\nMinimum size is 9M. The Android emulator cannot use smaller images.\n" );
+ fprintf(stderr, "Maximum size is %lld bytes, %lldK, %lldM or %lldG\n",
+ MAX_DISK_SIZE, MAX_DISK_SIZE >> 10, MAX_DISK_SIZE >> 20, MAX_DISK_SIZE >> 30);
exit(1);
}
@@ -211,7 +225,7 @@ int main( int argc, char** argv )
int sectors_per_disk;
char* end;
const char* label = NULL;
- FILE* f;
+ FILE* f = NULL;
for ( ; argc > 1 && argv[1][0] == '-'; argc--, argv++ )
{
@@ -238,19 +252,28 @@ int main( int argc, char** argv )
if (argc != 3)
usage();
- disk_size = strtol( argv[1], &end, 10 );
- if (disk_size == 0 && errno == EINVAL)
+ disk_size = strtoll( argv[1], &end, 10 );
+ if (disk_size <= 0 || errno == EINVAL || errno == ERANGE) {
+ fprintf(stderr, "Invalid argument size '%s'\n\n", argv[1]);
usage();
+ }
if (*end == 'K')
disk_size *= 1024;
else if (*end == 'M')
disk_size *= 1024*1024;
+ else if (*end == 'G')
+ disk_size *= 1024*1024*1024;
- if (disk_size < 8*1024*1024)
- fprintf(stderr, "### WARNING : SD Card images < 8 MB cannot be used with the Android emulator\n");
+ if (disk_size < 9*1024*1024) {
+ fprintf(stderr, "Invalid argument: size '%s' is too small.\n\n", argv[1]);
+ usage();
+ } else if (disk_size > MAX_DISK_SIZE) {
+ fprintf(stderr, "Invalid argument: size '%s' is too large.\n\n", argv[1]);
+ usage();
+ }
- sectors_per_disk = disk_size / 512;
+ sectors_per_disk = disk_size / BYTES_PER_SECTOR;
sectors_per_fat = get_sectors_per_fat( disk_size, get_sectors_per_cluster( disk_size ) );
boot_sector_init( s_boot_sector, s_fsinfo_sector, disk_size, NULL );
@@ -258,7 +281,8 @@ int main( int argc, char** argv )
f = fopen( argv[2], "wb" );
if ( !f ) {
- fprintf(stderr, "could not create file '%s', aborting...\n", argv[2] );
+ fprintf(stderr, "Could not create file '%s': %s\n", argv[2], strerror(errno));
+ goto FailWrite;
}
/* here's the layout:
@@ -274,7 +298,7 @@ int main( int argc, char** argv )
* zero sectors
*/
- if ( write_sector( f, s_boot_sector ) ) goto FailWrite;
+ if ( write_sector( f, s_boot_sector ) ) goto FailWrite;
if ( write_sector( f, s_fsinfo_sector ) ) goto FailWrite;
if ( BACKUP_BOOT_SECTOR > 0 ) {
if ( write_empty( f, BACKUP_BOOT_SECTOR - 2 ) ) goto FailWrite;
@@ -282,8 +306,7 @@ int main( int argc, char** argv )
if ( write_sector( f, s_fsinfo_sector ) ) goto FailWrite;
if ( write_empty( f, RESERVED_SECTORS - 2 - BACKUP_BOOT_SECTOR ) ) goto FailWrite;
}
- else
- if ( write_empty( f, RESERVED_SECTORS - 2 ) ) goto FailWrite;
+ else if ( write_empty( f, RESERVED_SECTORS - 2 ) ) goto FailWrite;
if ( write_sector( f, s_fat_head ) ) goto FailWrite;
if ( write_empty( f, sectors_per_fat-1 ) ) goto FailWrite;
@@ -297,8 +320,10 @@ int main( int argc, char** argv )
return 0;
FailWrite:
- fprintf(stderr, "could not write to '%s', aborting...\n", argv[2] );
- unlink( argv[2] );
- fclose(f);
+ if (f != NULL) {
+ fclose(f);
+ unlink( argv[2] );
+ fprintf(stderr, "File '%s' was not created.\n", argv[2]);
+ }
return 1;
}
diff --git a/emulator/qemud/qemud.c b/emulator/qemud/qemud.c
index e1c7b54..dc04de8 100644
--- a/emulator/qemud/qemud.c
+++ b/emulator/qemud/qemud.c
@@ -81,7 +81,7 @@
/* name of the single control socket used by the daemon */
#define CONTROL_SOCKET_NAME "qemud"
-#define DEBUG 1
+#define DEBUG 0
#define T_ACTIVE 0 /* set to 1 to dump traffic */
#if DEBUG
diff --git a/emulator/tests/Android.mk b/emulator/tests/Android.mk
new file mode 100644
index 0000000..04917f4
--- /dev/null
+++ b/emulator/tests/Android.mk
@@ -0,0 +1,17 @@
+# This directory contains various host tests to be used with the emulator
+# NOTE: Most of these are only built and run on Linux.
+
+LOCAL_PATH := $(call my-dir)
+
+# The test-qemud-pipes program is used to check the execution of QEMUD Pipes
+# See external/qemu/docs/ANDROID-QEMUD-PIPES.TXT for details.
+#
+ifeq ($(HOST_OS),XXXXlinux)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-qemud-pipes
+LOCAL_SRC_FILES := test-qemud-pipes.c
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_HOST_EXECUTABLE)
+
+endif # HOST_OS == linux \ No newline at end of file
diff --git a/emulator/tests/test-qemud-pipes.c b/emulator/tests/test-qemud-pipes.c
new file mode 100644
index 0000000..f5db531
--- /dev/null
+++ b/emulator/tests/test-qemud-pipes.c
@@ -0,0 +1,113 @@
+/* This program is used to test the QEMUD fast pipes.
+ * See external/qemu/docs/ANDROID-QEMUD-PIPES.TXT for details.
+ *
+ * The program acts as a simple TCP server that accepts data and sends
+ * them back to the client.
+ */
+
+#include <sys/socket.h>
+#include <net/inet.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#define DEFAULT_PORT 8012
+
+static void
+socket_close(int sock)
+{
+ int old_errno = errno;
+ close(sock);
+ errno = old_errno;
+}
+
+static int
+socket_loopback_server( int port, int type )
+{
+ struct sockaddr_in addr;
+
+ int sock = socket(AF_INET, type, 0);
+ if (sock < 0) {
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ int n = 1;
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+ if (TEMP_FAILURE_RETRY(bind(sock, &addr, sizeof(addr))) < 0) {
+ socket_close(sock);
+ return -1;
+ }
+
+ if (type == SOCK_STREAM) {
+ if (TEMP_FAILURE_RETRY(listen(sock, 4)) < 0) {
+ socket_close(sock);
+ return -1;
+ }
+ }
+
+ return sock;
+}
+
+int main(void)
+{
+ int sock, client;
+ int port = DEFAULT_PORT;
+
+ printf("Starting pipe test server on local port %d\n", port);
+ sock = socket_loopback_server( port, SOCK_STREAM );
+ if (sock < 0) {
+ fprintf(stderr, "Could not start server: %s\n", strerror(errno));
+ return 1;
+ }
+
+ client = accept(sock, NULL, NULL);
+ if (client < 0) {
+ fprintf(stderr, "Server error: %s\n", strerror(errno));
+ return 2;
+ }
+ printf("Client connected!\n");
+
+ /* Now, accept any incoming data, and send it back */
+ for (;;) {
+ char buff[1024], *p;
+ int ret, count;
+
+ do {
+ ret = read(client, buff, sizeof(buff));
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0) {
+ fprintf(stderr, "Client read error: %s\n", strerror(errno));
+ close(client);
+ return 3;
+ }
+ count = ret;
+ p = buff;
+ printf(" received: %d bytes\n", count);
+
+ while (count > 0) {
+ do {
+ ret = write(client, p, count);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0) {
+ fprintf(stderr, "Client write error: %s\n", strerror(errno));
+ close(client);
+ return 4;
+ }
+ printf(" sent: %d bytes\n", ret);
+
+ p += ret;
+ count -= ret;
+ }
+ }
+
+ return 0;
+}