Code:
drivers/misc/Kconfig | 11 +
drivers/misc/Makefile | 1 +
drivers/misc/bcm4751-gps.c | 490 +++++++++++++++++++++++++++++++++++++++
include/linux/i2c/bcm4751-gps.h | 59 +++++
4 files changed, 561 insertions(+), 0 deletions(-)
create mode 100644 drivers/misc/bcm4751-gps.c
create mode 100644 include/linux/i2c/bcm4751-gps.h
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0b591b6..1680673 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -390,6 +390,17 @@ config BMP085
To compile this driver as a module, choose M here: the
module will be called bmp085.
+config BCM4751_GPS
+ tristate "BCM4751 GPS driver"
+ depends on I2C
+ default n
+ ---help---
+ If you say yes here you get support for the Broadcom BCM4751 GPS
+ chip driver.
+
+ The driver supports only GPS in BCM4751 chip. When built as a driver
+ driver name is: bcm4751-gps. If unsure, say N here.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 255a80d..cfda6fb 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
+obj-$(CONFIG_BCM4751_GPS) += bcm4751-gps.o
obj-$(CONFIG_BMP085) += bmp085.o
obj-$(CONFIG_ICS932S401) += ics932s401.o
obj-$(CONFIG_LKDTM) += lkdtm.o
diff --git a/drivers/misc/bcm4751-gps.c b/drivers/misc/bcm4751-gps.c
new file mode 100644
index 0000000..03a3752
--- /dev/null
+++ b/drivers/misc/bcm4751-gps.c
@@ -0,0 +1,490 @@
+/*
+ * bcm4751-gps.c - Hardware interface for Broadcom BCM4751 GPS chip.
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Contact Matti Aaltonen, [email protected]
+ *
+ * Written by Andrei Emeltchenko <[email protected]>
+ * Modified by Yuri Zaporozhets <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#define DEBUG
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+#include <linux/i2c/bcm4751-gps.h>
+
+static struct bcm4751_gps_data *bcm4751_gps_device;
+
+static const char reg_vbat[] = "Vbat";
+static const char reg_vddio[] = "Vddio";
+
+/*
+ * Part of initialization is done in the board support file.
+ */
+
+static inline void bcm4751_gps_enable(struct bcm4751_gps_data *self)
+{
+ mutex_lock(&self->mutex);
+ if (!self->enable) {
+ regulator_bulk_enable(ARRAY_SIZE(self->regs), self->regs);
+ if (self->pdata->enable)
+ self->pdata->enable(self->client);
+ self->enable = 1;
+ }
+ mutex_unlock(&self->mutex);
+}
+
+static inline void bcm4751_gps_disable(struct bcm4751_gps_data *self)
+{
+ mutex_lock(&self->mutex);
+ if (self->enable) {
+ if (self->pdata->disable)
+ self->pdata->disable(self->client);
+ self->enable = 0;
+ regulator_bulk_disable(ARRAY_SIZE(self->regs), self->regs);
+ }
+ mutex_unlock(&self->mutex);
+}
+
+static inline void bcm4751_gps_wakeup_value(struct bcm4751_gps_data *self,
+ int value)
+{
+ mutex_lock(&self->mutex);
+ if (self->pdata->wakeup_ctrl)
+ self->pdata->wakeup_ctrl(self->client, value);
+ self->wakeup = value;
+ mutex_unlock(&self->mutex);
+}
+
+
+/*
+ * miscdevice interface
+ */
+
+static int bcm4751_gps_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int bcm4751_gps_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static ssize_t bcm4751_gps_read(struct file *file, char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct i2c_client *client = bcm4751_gps_device->client;
+ int num_read;
+ uint8_t tmp[BCM4751_MAX_BINPKT_RX_LEN];
+
+ /* Adjust for binary packet size */
+ if (count > BCM4751_MAX_BINPKT_RX_LEN)
+ count = BCM4751_MAX_BINPKT_RX_LEN;
+
+ dev_dbg(&client->dev, "reading %d bytes\n", count);
+
+ num_read = i2c_master_recv(client, tmp, count);
+
+ if (num_read < 0) {
+ dev_err(&client->dev, "got %d bytes instead of %d\n",
+ num_read, count);
+ return num_read;
+ } else {
+ dev_dbg(&client->dev, "reading %d bytes returns %d",
+ count, num_read);
+ }
+
+ return copy_to_user(buf, tmp, num_read) ? -EFAULT : num_read;
+}
+
+static ssize_t bcm4751_gps_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct i2c_client *client = bcm4751_gps_device->client;
+ uint8_t tmp[BCM4751_MAX_BINPKT_TX_LEN];
+ int num_sent;
+
+ if (count > BCM4751_MAX_BINPKT_TX_LEN)
+ count = BCM4751_MAX_BINPKT_TX_LEN;
+
+ dev_dbg(&client->dev, "writing %d bytes\n", count);
+
+ if (copy_from_user(tmp, buf, count))
+ return -EFAULT;
+
+ num_sent = i2c_master_send(client, tmp, count);
+
+ dev_dbg(&client->dev, "writing %d bytes returns %d",
+ count, num_sent);
+
+ return num_sent;
+}
+
+static int bcm4751_gps_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct i2c_client *client = bcm4751_gps_device->client;
+
+ dev_dbg(&client->dev, "ioctl: cmd = 0x%02x, arg=0x%02lx\n", cmd, arg);
+
+ switch (cmd) {
+ case I2C_SLAVE:
+ case I2C_SLAVE_FORCE:
+ if ((arg > 0x3ff) ||
+ (((client->flags & I2C_M_TEN) == 0) &&
+ arg > 0x7f))
+ return -EINVAL;
+ client->addr = arg;
+ dev_dbg(&client->dev, "ioctl: client->addr = %x", client->addr);
+ return 0;
+ case I2C_TENBIT:
+ if (arg)
+ client->flags |= I2C_M_TEN;
+ else
+ client->flags &= ~I2C_M_TEN;
+ return 0;
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static const struct file_operations bcm4751_gps_fileops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .read = bcm4751_gps_read,
+ .write = bcm4751_gps_write,
+ .unlocked_ioctl = bcm4751_gps_ioctl,
+ .open = bcm4751_gps_open,
+ .release = bcm4751_gps_release,
+};
+
+static struct miscdevice bcm4751_gps_miscdevice = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "bcm4751-gps",
+ .fops = &bcm4751_gps_fileops
+};
+
+
+/*
+ * sysfs interface
+ */
+
+static ssize_t bcm4751_gps_show_hostreq(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bcm4751_gps_data *self = dev_get_drvdata(dev);
+ int value = -1;
+
+ if (self->pdata->show_irq)
+ value = self->pdata->show_irq(self->client);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", value);
+}
+
+static ssize_t bcm4751_gps_show_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bcm4751_gps_data *self = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", self->enable);
+}
+
+static ssize_t bcm4751_gps_set_enable(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ struct bcm4751_gps_data *self = dev_get_drvdata(dev);
+ int value;
+
+ sscanf(buf, "%d", &value);
+ dev_dbg(dev, "enable: %d", value);
+
+ switch (value) {
+ case 0:
+ bcm4751_gps_disable(self);
+ break;
+
+ case 1:
+ bcm4751_gps_enable(self);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return len;
+}
+
+static ssize_t bcm4751_gps_show_wakeup(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bcm4751_gps_data *self = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", self->wakeup);
+}
+
+static ssize_t bcm4751_gps_set_wakeup(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ unsigned long val;
+ int ret;
+ struct bcm4751_gps_data *self = dev_get_drvdata(dev);
+
+ ret = strict_strtoul(buf, 0, &val);
+ if (ret && val > 1)
+ return -EINVAL;
+ else {
+ bcm4751_gps_wakeup_value(self, val);
+ dev_dbg(dev, "new wakeup value = %d", self->wakeup);
+ }
+
+ return len;
+}
+
+static struct device_attribute bcm4751_gps_attrs[] = {
+ __ATTR(enable, S_IRUGO|S_IWUSR,
+ bcm4751_gps_show_enable, bcm4751_gps_set_enable),
+ __ATTR(hostreq, S_IRUGO|S_IWUSR,
+ bcm4751_gps_show_hostreq, NULL),
+ __ATTR(wakeup, S_IRUGO|S_IWUSR,
+ bcm4751_gps_show_wakeup, bcm4751_gps_set_wakeup),
+};
+
+static int bcm4751_gps_register_sysfs(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(bcm4751_gps_attrs); i++) {
+ ret = device_create_file(dev, &bcm4751_gps_attrs[i]);
+ if (ret)
+ goto fail;
+ }
+ return 0;
+fail:
+ while (i--)
+ device_remove_file(dev, &bcm4751_gps_attrs[i]);
+
+ return ret;
+}
+
+static void bcm4751_gps_unregister_sysfs(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ int i;
+
+ for (i = ARRAY_SIZE(bcm4751_gps_attrs) - 1; i >= 0; i--)
+ device_remove_file(dev, &bcm4751_gps_attrs[i]);
+}
+
+/* IRQ thread */
+static irqreturn_t bcm4751_gps_irq_thread(int irq, void *dev_id)
+{
+ struct bcm4751_gps_data *data = dev_id;
+
+ dev_dbg(&data->client->dev, "irq, HOST_REQ=%d",
+ data->pdata->show_irq(data->client));
+
+ /* Update sysfs GPIO line here */
+ sysfs_notify(&data->client->dev.kobj, NULL, "hostreq");
+ return IRQ_HANDLED;
+}
+
+static int bcm4751_gps_probe(struct i2c_client *client,
+ const struct i2c_device_id *device_id)
+{
+ struct bcm4751_gps_data *data;
+ struct bcm4751_gps_platform_data *pdata;
+ int err;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ bcm4751_gps_device = data;
+
+ pdata = client->dev.platform_data;
+ if (!pdata) {
+ dev_err(&client->dev, "no platform data\n");
+ err = -ENODEV;
+ goto clean_data;
+ }
+
+ i2c_set_clientdata(client, data);
+ data->client = client;
+ data->pdata = pdata;
+
+ data->gpio_irq = pdata->gps_gpio_irq;
+ data->gpio_enable = pdata->gps_gpio_enable;
+ data->gpio_wakeup = pdata->gps_gpio_wakeup;
+
+ data->regs[0].supply = reg_vbat;
+ data->regs[1].supply = reg_vddio;
+ err = regulator_bulk_get(&client->dev,
+ ARRAY_SIZE(data->regs), data->regs);
+ if (err < 0) {
+ dev_err(&client->dev, "Can't get regulators\n");
+ goto clean_data;
+ }
+
+ if (pdata->setup) {
+ err = pdata->setup(client);
+ if (err)
+ goto clean_reg;
+ }
+
+ mutex_init(&data->mutex);
+ err = request_threaded_irq(client->irq, NULL,
+ bcm4751_gps_irq_thread,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ "bcm4751-gps", data);
+ if (err) {
+ dev_err(&client->dev, "could not get GPS_IRQ = %d\n",
+ client->irq);
+ goto clean_setup;
+ }
+
+ err = bcm4751_gps_register_sysfs(client);
+ if (err) {
+ dev_err(&client->dev,
+ "sysfs registration failed, error %d\n", err);
+ goto clean_irq;
+ }
+
+ bcm4751_gps_miscdevice.parent = &client->dev;
+ err = misc_register(&bcm4751_gps_miscdevice);
+ if (err) {
+ dev_err(&client->dev, "Miscdevice register failed\n");
+ goto clean_sysfs;
+ }
+
+ return 0;
+
+clean_sysfs:
+ bcm4751_gps_unregister_sysfs(client);
+
+clean_irq:
+ free_irq(client->irq, data);
+
+clean_setup:
+ if (pdata->cleanup)
+ pdata->cleanup(client);
+clean_reg:
+ regulator_bulk_free(ARRAY_SIZE(data->regs), data->regs);
+clean_data:
+ bcm4751_gps_device = NULL;
+ kfree(data);
+
+ return err;
+}
+
+static int bcm4751_gps_remove(struct i2c_client *client)
+{
+ struct bcm4751_gps_data *data = i2c_get_clientdata(client);
+
+ bcm4751_gps_disable(data);
+
+ free_irq(client->irq, data);
+ misc_deregister(&bcm4751_gps_miscdevice);
+ bcm4751_gps_unregister_sysfs(client);
+ if (data->pdata->cleanup)
+ data->pdata->cleanup(client);
+ regulator_bulk_free(ARRAY_SIZE(data->regs), data->regs);
+ kfree(data);
+ bcm4751_gps_device = NULL;
+
+ return 0;
+}
+
+static void bcm4751_gps_shutdown(struct i2c_client *client)
+{
+ dev_dbg(&client->dev, "BCM4751 shutdown\n");
+ bcm4751_gps_disable(i2c_get_clientdata(client));
+}
+
+#ifdef CONFIG_PM
+static int bcm4751_gps_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct bcm4751_gps_data *data = i2c_get_clientdata(client);
+ data->pdata->wakeup_ctrl(data->client, 0);
+ dev_dbg(&client->dev, "BCM4751 suspends\n");
+ return 0;
+}
+
+static int bcm4751_gps_resume(struct i2c_client *client)
+{
+ struct bcm4751_gps_data *data = i2c_get_clientdata(client);
+ data->pdata->wakeup_ctrl(data->client, 1);
+ dev_dbg(&client->dev, "BCM4751 resumes\n");
+ return 0;
+}
+#else
+#define bcm4751_gps_suspend NULL
+#define bcm4751_gps_resume NULL
+#endif
+
+static const struct i2c_device_id bcm4751_gps_id[] = {
+ { "bcm4751-gps", 0 },
+ { },
+};
+
+MODULE_DEVICE_TABLE(i2c, bcm4751_gps_id);
+
+static struct i2c_driver bcm4751_gps_i2c_driver = {
+ .driver = {
+ .name = "bcm4751-gps",
+ },
+
+ .id_table = bcm4751_gps_id,
+ .probe = bcm4751_gps_probe,
+ .remove = __devexit_p(bcm4751_gps_remove),
+ .shutdown = bcm4751_gps_shutdown,
+ .suspend = bcm4751_gps_suspend,
+ .resume = bcm4751_gps_resume,
+};
+
+static int __init bcm4751_gps_init(void)
+{
+ pr_info("Loading BCM4751 GPS driver\n");
+
+ return i2c_add_driver(&bcm4751_gps_i2c_driver);
+}
+module_init(bcm4751_gps_init);
+
+static void __exit bcm4751_gps_exit(void)
+{
+ i2c_del_driver(&bcm4751_gps_i2c_driver);
+}
+module_exit(bcm4751_gps_exit);
+
+MODULE_AUTHOR("Andrei Emeltchenko, Yuri Zaporozhets");
+MODULE_DESCRIPTION("BCM4751 GPS driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/i2c/bcm4751-gps.h b/include/linux/i2c/bcm4751-gps.h
new file mode 100644
index 0000000..69834b9
--- /dev/null
+++ b/include/linux/i2c/bcm4751-gps.h
@@ -0,0 +1,59 @@
+/*
+ * @file include/linux/i2c/bcm4751-gps.h
+ *
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Contact Matti Aaltonen, [email protected]
+ *
+ * Written by Andrei Emeltchenko <[email protected]>
+ * Modified by Yuri Zaporozhets <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _LINUX_I2C_BCM4751_GPS_H
+#define _LINUX_I2C_BCM4751_GPS_H
+
+/* Max packet sizes for RX and TX */
+#define BCM4751_MAX_BINPKT_RX_LEN 64
+#define BCM4751_MAX_BINPKT_TX_LEN 64
+
+/* Plaform data, used by the board support file */
+struct bcm4751_gps_platform_data {
+ int gps_gpio_irq;
+ int gps_gpio_enable;
+ int gps_gpio_wakeup;
+ int (*setup)(struct i2c_client *client);
+ void (*cleanup)(struct i2c_client *client);
+ void (*enable)(struct i2c_client *client);
+ void (*disable)(struct i2c_client *client);
+ void (*wakeup_ctrl)(struct i2c_client *client, int value);
+ int (*show_irq)(struct i2c_client *client);
+};
+
+/* Used internally by the driver */
+struct bcm4751_gps_data {
+ struct i2c_client *client;
+ struct bcm4751_gps_platform_data *pdata;
+ struct mutex mutex; /* Serialize things */
+ struct regulator_bulk_data regs[2];
+ unsigned int gpio_irq;
+ unsigned int gpio_enable;
+ unsigned int gpio_wakeup;
+ int enable;
+ int wakeup;
+};
+
+#endif
This is nokia's linux driver for the bcm4751 device. Can this be repackaged?
Online Nandroid Backup as seen on today's XDA front page.
This looks great! No more turning device off to make nandroid backups.
Has anyone tested it with the Atrix? And if so, on which ROM? Any issues?
"Why don't you try it yourself and tell for the rest of us?'
I guess it's better to ask before I screw up something on mine
Edit:
Since version 5.9 it works well with the Atrix, backing up /boot, /recovery, /system, /data, /cache and .android_secure. Tested and confirmed.
Personally, I don't think I'd trust such a backup. I very much believe no software, on phone or computer or anywhere else, should ever be backed up while it's live/running. Especially if it's the OS itself. I just wouldn't trust it.
For starters, it's making a backup of /data while many background services are running, live services that could at any point change any part of that same /data...
Installs fine. Can't get root permissions with it when it tries to perform a backup.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
That is not a problem. It is how fruit cakes are made.
The service does sound interesting.
ravilov said:
Personally, I don't think I'd trust such a backup. I very much believe no software, on phone or computer or anywhere else, should ever be backed up while it's live/running. Especially if it's the OS itself. I just wouldn't trust it.
For starters, it's making a backup of /data while many background services are running, live services that could at any point change any part of that same /data...
Click to expand...
Click to collapse
CaelanT said:
Installs fine. Can't get root permissions with it when it tries to perform a backup.
Click to expand...
Click to collapse
Re-install the latest version of busybox. It should work then.
Tested it, its working...
Sent from my MB860 using xda premium
upndwn4par said:
That is not a problem. It is how fruit cakes are made.
Click to expand...
Click to collapse
Hm, could you explain please?
Are you saying fruitcakes don't update /data randomly? Or don't have background processes?
I'm confused.
ravilov said:
Hm, could you explain please?
Are you saying fruitcakes don't update /data randomly? Or don't have background processes?
I'm confused.
Click to expand...
Click to collapse
Getting off topic, but fruit cakes are made from an app called rom factory. The app creates a copy of your boot and system images while the phone is running. I don't know how it works (you'd have to ask samcripp). But I would guess that it works like titanium backup in that it will pause any process it needs to copy.
So back to your point, yes, the system can be reliably copied while running.
upndwn4par said:
That is not a problem. It is how fruit cakes are made.
The service does sound interesting.
Click to expand...
Click to collapse
Fruitcakes don't back up /data. Only /system and /boot are backed up.
ameer1234567890 said:
Re-install the latest version of busybox. It should work then.
Click to expand...
Click to collapse
That fixed it. So I created a backup with this, then wiped and tried to restore. Had error on boot image. Had to restore from nandroid created in recovery earlier, so I guess it creates a backup, but the backup is balked in some way.
Sent from my MB860 using xda premium
CaelanT said:
That fixed it. So I created a backup with this, then wiped and tried to restore. Had error on boot image. Had to restore from nandroid created in recovery earlier, so I guess it creates a backup, but the backup is balked in some way.
Sent from my MB860 using xda premium
Click to expand...
Click to collapse
Provide me the log file at /data/local/tmp/onandroid.log
ameer1234567890 said:
Provide me the log file at /data/local/tmp/onandroid.log
Click to expand...
Click to collapse
I lost the original log from the failed restore after I restored from my nandroid I had created in recovery prior to that, so I repeated the process and did in fact have the same failure, so it is repeatable. Log from this attempt is attached.
Exactly what I said. The point was that you can copy files on a running os. Just like with the online nandroid.
Sent from my MB860 using xda app-developers app
Edit: @nerfman
I think you're missing the point here. Things like /system and /boot are perfectly fine to access and copy on a live system, they are mounted read-only anyway. /data on the other hand is mounted read-write and gets accessed and changed all the time. I just simply don't think it's at all safe to try making a backup of any file while it's (potentially) being changed. That sounds like a good way to get a corrupted copy of the file. Not a good way to get a reliable backup.
Your original statement (emphasis added by me):
"Personally, I don't think I'd trust such a backup. I very much believe no software, on phone or computer or anywhere else, should ever be backed up while it's live/running. Especially if it's the OS itself. I just wouldn't trust it.
For starters, it's making a backup of /data while many background services are running, live services that could at any point change any part of that same /data... "
Last time I checked, system and boot are integral parts of the os. Clearly this is possible as evidenced by fruit cakes. I never commented on data. But having said that, any process or service need only be paused to be copied. I don't see why you can't get your head wrapped around this concept.
ravilov said:
I think you're missing the point here. Things like /system and /boot are perfectly fine to access and copy on a live system, they are mounted read-only anyway. /data on the other hand is mounted read-write and gets accessed and changed all the time. I just simply don't think it's at all safe to try making a backup of any file while it's (potentially) being changed. That sounds like a good way to get a corrupted copy of the file. Not a good way to get a reliable backup.
Click to expand...
Click to collapse
CaelanT said:
I lost the original log from the failed restore after I restored from my nandroid I had created in recovery prior to that, so I repeated the process and did in fact have the same failure, so it is repeatable. Log from this attempt is attached.
Click to expand...
Click to collapse
Thank you for the details. I am guessing you are using an Atrix 4G.
There is an issue where I am unable to programmatically find the boot partition on some devices which does not have /proc/mtd and /proc/emmc
I have opened an issue for this. I am working on it. I shall post here when it is fixed.
For the time being, you can just restore backup done with Online Nandroid and then restore only the boot partition from a previous nandroid done with CWM.
ROM Factory Magic
Random FactsDeveloping ROM Factory took, 4 months, cost 743$, hard bricked one device and the finish product uses android, java zip, and the under laying linux. Its in continues research. With ever changing phones, ever changing ROM Factory. Because of the way the app is design only Phones with BML partition system can use it. Mostly high end devices.ROM Factory does not create a nandroid back up.Understanding how ROM Factory works.The Device LibraryIn the library I began to create a list of devices. This list contains a device name, and some specifics about the device. Such as /system partition location, and storage options.
The main function for it is to identify the device and provide the info. Looks something like this:
Code:
if(Phone.contentEquals("olympus")) //moto atrix
{
if(OS.contentEquals("2.3.4"))
{
zStorage = "/sdcard-ext";
} else if(OS.contentEquals("2.3.5")) {
zStorage = "/sdcard-ext";
} else if(OS.contentEquals("2.3.6")) {
zStorage = "/sdcard-ext";
} else {
zStorage = Environment.getExternalStorageDirectory().getAbsolutePath();
}
RName = "Atrix 4G";
appRun = true;
DataPart = "/dev/block/mmcblk0p07";
BootPart = "/dev/block/mmcblk0p11";
SysPart = "/dev/block/mmcblk0p12";
}
The SU ClassIn the class I build a custom set of methods to handle the super user commands require to create the back ups.
Looks something like this:
Code:
public void cmdSU(String suCmd){
DataOutputStream suShell = new DataOutputStream(user.getOutputStream());
try{
suShell.writeBytes(suCmd + "\n");
suShell.writeBytes("wait\n");
suShell.writeBytes("exit\n");
suShell.flush();
try { user.waitFor();
if (user.exitValue() != 255) { } else { }
} catch (InterruptedException e) { Log.e("SU", e.getMessage()); }
} catch (IOException e) { Log.e("SU", e.getMessage()); }
}
The Script EngineI still very much consider this a work in progress.In the class I build a custom set of methods to handle the creation of the edify script required by Recovery to install a ROM. To save time and resources instead of creating a new file, the app simply echos a new one through the SU class. The script engine also detects some of the phone settigns and prepares the script
Looks something like this:
Code:
// Script Engine v0.6 * By Samuel Rivera "SamCripp"
//
// This code is constantly evolving. So if you use this on your project please keep an eye on the repository the code came from.
//
// http://zombidev.com * http://fcm.zombidev.com * http://repo.zombidev.com
//
// This code is the intellectual property of Samuel Rivera, 2011-2012. I, Samuel Rivera, grant you the following rights.
// 1. You may modify and redistribute this code. 2. You may compile and redistribute this code. 3. You may use this code in personal or educational projects.
//
// With that said, here is a list of rights revoked.
// 1. You may not use this code on commercial projects. 2. You may not use this code on corporate environment.
// 3. You may not use the code in any malicious way. 4. You may not use it for profit.
//
// Conditions:
// 1. Any project utilizing this code, whether close or open source, must always provide the latest version of this code, including all modifications.
// 2. Any project utilizing this code, must provide a link back to http://fcm.zombidev.com and http://repo.zombidev.com.
// 3. Any project utilizing this code, must provide credit to Samuel Rivera as original author of code. ie:
// Script Engine v0.6 - Original Author: Samuel Rivera "SamCripp"
//
// Thanks for following this simple rules.
package com.samcripp.romff;
public class ScriptEng {
String SEVersion = new String("--Script Engine v0.6");
String boot = new String();
String system = new String();
String os = new String();
String romName = new String();
String devName = new String();
String device = new String();
String formatType = new String();
boolean SndInit = false;
boolean NormalM = false;
boolean AdvMode = false;
boolean AppMode = false;
boolean backupMode = false;
String TheScript = new String();
String sym = "\"";
String beginCmd = "(";
String endCmd = ") > ";
String echo = "echo "+ sym;
String and = " && ";
String pend = ");" + sym;
String prog = "show_progress(";
String sprog = "set_progress(";
String ui_print = "ui_print(\\" + sym;
String ui_end = "\\" + sym + ");"+ sym;
String warning = "--This script is generated automatically--";
String line = "- - - - - - - - - - - - - - - - - - - - - - -";
String pkgexb = "package_extract_file(\\" + sym + "/boot.img" + "\\" + sym + "," + "\\" + sym + boot + "\\" + sym + ");" + sym;
String pkgexs = "package_extract_file(\\" + sym + "/system.img" + "\\" + sym + "," + "\\" + sym + system + "\\" + sym + ");" + sym;
String fdlexs = "package_extract_dir(\\" + sym + "system" + "\\" + sym + "," + "\\" + sym + "/system" + "\\" + sym + ");" + sym;
String fdlexaa = "package_extract_dir(\\" + sym + "apps" + "\\" + sym + "," + "\\" + sym + "/tmp/apps" + "\\" + sym + ");" + sym;
String fdlexdd = "package_extract_dir(\\" + sym + "data" + "\\" + sym + "," + "\\" + sym + "/tmp/data" + "\\" + sym + ");" + sym;
String fdlexa = "run_program(\\" + sym + "/system/xbin/busybox" + "\\" + sym + ", " + "\\" + sym + "cp -R" + "\\" + sym + ", " + "\\" + sym + "/tmp/apps" +", " + "\\" + sym + "/data/app" + "\\" + sym + ");" + sym;
String busymount = "run_program(\\" + sym + "/system/xbin/busybox" + "\\" + sym + ", " + "\\" + sym + "mount" + "\\" + sym + ", " + "\\" + sym + "/data" + "\\" + sym + ");" + sym;
String busydata = "run_program(\\" + sym + "/system/xbin/busybox" + "\\" + sym + ", " + "\\" + sym + "cp -R" + "\\" + sym + ", " + "\\" + sym + "/tmp/data" +", " + "\\" + sym + "/data" + "\\" + sym + ");" + sym;
String umountS = "unmount(\\" + sym + "/system" + "\\" + sym + ");" + sym;
public ScriptEng(boolean Init, String dev, String dName, String deviceN, String bootL, String sysL, String rom, String romversion,String dOs){
boot = bootL;
system = sysL;
romName = rom + " " + romversion;
devName = dev;
os = dOs;
device = dName + " " + deviceN;
SndInit = Init;
// AdvMode = adv;
// AppMode = app;
// backupMode = backup;
}
public void Make(){
String formatS = new String();
String mountS = new String();
if(formatType == "ext4"){
formatS = "format(\\" + sym + "ext4" + "\\" + sym + "," + "\\" + sym + "EMMC" + "\\" + sym + "," + "\\" + sym + system + "\\" + sym + ");" + sym;
mountS = "mount(\\" + sym + "ext4" + "\\" + sym + "," + "\\" + sym + "EMMC" + "\\" + sym + "," + "\\" + sym + system + "\\" + sym + "," + "\\" + sym + "/system" + "\\" + sym + ");" + sym;
} else if(formatType == "yaffs"){
formatS = "format(\\" + sym;
}else{
formatS = "format(\\" + sym + "ext3" + "\\" + sym + "," + "\\" + sym + "EMMC" + "\\" + sym + "," + "\\" + sym + system + "\\" + sym + ");" + sym;
mountS = "mount(\\" + sym + "ext3" + "\\" + sym + "," + "\\" + sym + "EMMC" + "\\" + sym + "," + "\\" + sym + system + "\\" + sym + "," + "\\" + sym + "/system" + "\\" + sym + ");" + sym;
}
if(SndInit == true){
NormalM = false;
}else{
NormalM = true;
}
if(NormalM == true && SndInit == false && AdvMode == false && AppMode == false){
// good old normal phone
TheScript = beginCmd + echo + prog + "1.000000, 0" + pend + and + echo + ui_print + warning + ui_end
+ and + echo + ui_print + SEVersion + ui_end + and + echo + ui_print + "--Rom Name: "+ romName + ui_end
+ and + echo + ui_print + "--Rom Developer: " + devName + ui_end + and + echo + ui_print
+ "--Rom Base: " + os + ui_end + and + echo + ui_print + "--Device Name: " + device + ui_end
+ and + echo + ui_print + line + ui_end + and + echo + ui_print + "--Installing Boot" + ui_end
+ and + echo + sprog + "0.300000" + pend + and + echo + pkgexb
+ and + echo + ui_print + "--Installing System" + ui_end
+ and + echo + sprog + "0.650000" + pend + and + echo + pkgexs + and + echo + ui_print + line
+ ui_end + and + echo + ui_print + "--Don't forget to format data and cache" + ui_end
+ and + echo + sprog + "1.000000" + pend + endCmd;
} if(NormalM == false && SndInit == true && AdvMode == false && AppMode == false){
// normal second init
TheScript = beginCmd + echo + prog + "1.000000, 0" + pend + and + echo + ui_print + warning + ui_end
+ and + echo + ui_print + SEVersion + ui_end + and + echo + ui_print + "--Rom Name: "+ romName + ui_end
+ and + echo + ui_print + "--Rom Developer: " + devName + ui_end + and + echo + ui_print
+ "--Rom Base: " + os + ui_end + and + echo + ui_print + "--Device Name: " + device + ui_end
+ and + echo + ui_print + line + ui_end + and + echo + ui_print + "--Installing System" + ui_end
+ and + echo + sprog + "0.650000" + pend + and + echo + pkgexs + and + echo + ui_print + line
+ ui_end + and + echo + ui_print + "--Don't forget to format data and cache" + ui_end
+ and + echo + sprog + "1.000000" + pend + endCmd;
} if(NormalM == true && SndInit == false && AdvMode == true && AppMode == false && backupMode == false){
// normal device with advance mode
TheScript = beginCmd + echo + prog + "1.000000, 0" + pend + and + echo + ui_print + warning + ui_end
+ and + echo + ui_print + SEVersion + ui_end + and + echo + ui_print + "--Rom Name: "+ romName + ui_end
+ and + echo + ui_print + "--Rom Developer: " + devName + ui_end + and + echo + ui_print
+ "--Rom Base: " + os + ui_end + and + echo + ui_print + "--Device Name: " + device + ui_end
+ and + echo + ui_print + line + ui_end + and + echo + ui_print + "--Installing Boot" + ui_end
+ and + echo + sprog + "0.300000" + pend + and + echo + pkgexb
+ and + echo + ui_print + "--Formating System" + ui_end
+ and + echo + sprog + "0.550000" + pend + and + echo + formatS
+ and + echo + ui_print + "--Installing System" + ui_end
+ and + echo + sprog + "0.600000" + pend + and + echo + pkgexs
+ and + echo + ui_print + "--Mounting System" + ui_end
+ and + echo + sprog + "0.900000" + pend + and + echo + mountS
+ and + echo + ui_print + "--Extracting System Mods" + ui_end
+ and + echo + sprog + "0.950000" + pend + and + echo + fdlexs
+ and + echo + ui_print + "--UnMounting System" + ui_end
+ and + echo + sprog + "0.990000" + pend + and + echo + umountS
+ and + echo + ui_print + line
+ ui_end + and + echo + ui_print + "--Don't forget to format data and cache" + ui_end
+ and + echo + sprog + "1.000000" + pend + endCmd;
} if(NormalM == false && SndInit == true && AdvMode == true && AppMode == false && backupMode == false){
// second init device with advance mode
TheScript = beginCmd + echo + prog + "1.000000, 0" + pend + and + echo + ui_print + warning + ui_end
+ and + echo + ui_print + SEVersion + ui_end + and + echo + ui_print + "--Rom Name: "+ romName + ui_end
+ and + echo + ui_print + "--Rom Developer: " + devName + ui_end + and + echo + ui_print
+ "--Rom Base: " + os + ui_end + and + echo + ui_print + "--Device Name: " + device + ui_end
+ and + echo + ui_print + line + ui_end + and + echo + ui_print + "--Formating System" + ui_end
+ and + echo + sprog + "0.550000" + pend + and + echo + formatS
+ and + echo + ui_print + "--Installing System" + ui_end
+ and + echo + sprog + "0.600000" + pend + and + echo + pkgexs
+ and + echo + ui_print + "--Mounting System" + ui_end
+ and + echo + sprog + "0.900000" + pend + and + echo + mountS
+ and + echo + ui_print + "--Extracting System Mods" + ui_end
+ and + echo + sprog + "0.950000" + pend + and + echo + fdlexs
+ and + echo + ui_print + "--UnMounting System" + ui_end
+ and + echo + sprog + "0.990000" + pend + and + echo + umountS
+ and + echo + ui_print + line
+ ui_end + and + echo + ui_print + "--Don't forget to format data and cache" + ui_end
+ and + echo + sprog + "1.000000" + pend + endCmd;
} if(NormalM == true && SndInit == false && AdvMode == false && AppMode == true && backupMode == false){
// normal device with apps mode
TheScript = beginCmd + echo + prog + "1.000000, 0" + pend + and + echo + ui_print + warning + ui_end
+ and + echo + ui_print + SEVersion + ui_end + and + echo + ui_print + "--Rom Name: "+ romName + ui_end
+ and + echo + ui_print + "--Rom Developer: " + devName + ui_end + and + echo + ui_print
+ "--Rom Base: " + os + ui_end + and + echo + ui_print + "--Device Name: " + device + ui_end
+ and + echo + ui_print + line + ui_end + and + echo + ui_print + "--Installing Boot" + ui_end
+ and + echo + sprog + "0.300000" + pend + and + echo + pkgexb
+ and + echo + ui_print + "--Formating System" + ui_end
+ and + echo + sprog + "0.550000" + pend + and + echo + formatS
+ and + echo + ui_print + "--Installing System" + ui_end
+ and + echo + sprog + "0.600000" + pend + and + echo + pkgexs
+ and + echo + ui_print + "--Mounting System" + ui_end
+ and + echo + sprog + "0.900000" + pend + and + echo + mountS
+ and + echo + ui_print + "--Extracting Apps" + ui_end
+ and + echo + sprog + "0.930000" + pend + and + echo + fdlexaa
+ and + echo + sprog + "0.950000" + pend + and + echo + fdlexa
+ and + echo + ui_print + "--UnMounting System" + ui_end
+ and + echo + sprog + "0.990000" + pend + and + echo + umountS
+ and + echo + ui_print + line
+ ui_end + and + echo + ui_print + "--Don't forget to format data and cache" + ui_end
+ and + echo + sprog + "1.000000" + pend + endCmd;
} if(NormalM == false && SndInit == true && AdvMode == false && AppMode == true && backupMode == false){
// second init device with apps mode
TheScript = beginCmd + echo + prog + "1.000000, 0" + pend + and + echo + ui_print + warning + ui_end
+ and + echo + ui_print + SEVersion + ui_end + and + echo + ui_print + "--Rom Name: "+ romName + ui_end
+ and + echo + ui_print + "--Rom Developer: " + devName + ui_end + and + echo + ui_print
+ "--Rom Base: " + os + ui_end + and + echo + ui_print + "--Device Name: " + device + ui_end
+ and + echo + ui_print + line + ui_end + and + echo + ui_print + "--Formating System" + ui_end
+ and + echo + sprog + "0.550000" + pend + and + echo + formatS
+ and + echo + ui_print + "--Installing System" + ui_end
+ and + echo + sprog + "0.600000" + pend + and + echo + pkgexs
+ and + echo + ui_print + "--Mounting System" + ui_end
+ and + echo + sprog + "0.900000" + pend + and + echo + mountS
+ and + echo + ui_print + "--Extracting Apps" + ui_end
+ and + echo + sprog + "0.930000" + pend + and + echo + fdlexaa
+ and + echo + sprog + "0.950000" + pend + and + echo + fdlexa
+ and + echo + ui_print + "--UnMounting System" + ui_end
+ and + echo + sprog + "0.990000" + pend + and + echo + umountS
+ and + echo + ui_print + line
+ ui_end + and + echo + ui_print + "--Don't forget to format data and cache" + ui_end
+ and + echo + sprog + "1.000000" + pend + endCmd;
} if(NormalM == true && SndInit == false && AdvMode == false && AppMode == false && backupMode == true){
// normal device with back up mode
TheScript = beginCmd + echo + prog + "1.000000, 0" + pend + and + echo + ui_print + warning + ui_end
+ and + echo + ui_print + SEVersion + ui_end + and + echo + ui_print + "--Rom Name: "+ romName + ui_end
+ and + echo + ui_print + "--Rom Developer: " + devName + ui_end + and + echo + ui_print
+ "--Rom Base: " + os + ui_end + and + echo + ui_print + "--Device Name: " + device + ui_end
+ and + echo + ui_print + line + ui_end + and + echo + ui_print + "--Installing Boot" + ui_end
+ and + echo + sprog + "0.300000" + pend + and + echo + pkgexb
+ and + echo + ui_print + "--Formating System" + ui_end
+ and + echo + sprog + "0.550000" + pend + and + echo + formatS
+ and + echo + ui_print + "--Installing System" + ui_end
+ and + echo + sprog + "0.600000" + pend + and + echo + pkgexs
+ and + echo + ui_print + "--Mounting Data" + ui_end
+ and + echo + sprog + "0.900000" + pend + and + echo + busymount
+ and + echo + ui_print + "--Extracting Back Up" + ui_end
+ and + echo + sprog + "0.930000" + pend + and + echo + fdlexdd
+ and + echo + sprog + "0.950000" + pend + and + echo + busydata
+ and + echo + ui_print + line
+ ui_end + and + echo + ui_print + "--Don't forget to format data and cache" + ui_end
+ and + echo + sprog + "1.000000" + pend + endCmd;
} if(NormalM == false && SndInit == true && AdvMode == false && AppMode == false && backupMode == true){
// second init device with apps mode
TheScript = beginCmd + echo + prog + "1.000000, 0" + pend + and + echo + ui_print + warning + ui_end
+ and + echo + ui_print + SEVersion + ui_end + and + echo + ui_print + "--Rom Name: "+ romName + ui_end
+ and + echo + ui_print + "--Rom Developer: " + devName + ui_end + and + echo + ui_print
+ "--Rom Base: " + os + ui_end + and + echo + ui_print + "--Device Name: " + device + ui_end
+ and + echo + ui_print + line + ui_end + and + echo + ui_print + "--Formating System" + ui_end
+ and + echo + sprog + "0.550000" + pend + and + echo + formatS
+ and + echo + ui_print + "--Installing System" + ui_end
+ and + echo + sprog + "0.600000" + pend + and + echo + pkgexs
+ and + echo + ui_print + "--Mounting Data" + ui_end
+ and + echo + sprog + "0.900000" + pend + and + echo + busymount
+ and + echo + ui_print + "--Extracting Back Up" + ui_end
+ and + echo + sprog + "0.930000" + pend + and + echo + fdlexdd
+ and + echo + sprog + "0.950000" + pend + and + echo + busydata
+ and + echo + ui_print + line
+ ui_end + and + echo + ui_print + "--Don't forget to format data and cache" + ui_end
+ and + echo + sprog + "1.000000" + pend + endCmd;
}
}
public String Script(){
return TheScript;
}
}
And finally Linux!Pay attention, here is where the magic happens. The apps sends a simple "dd" command to linux to create a "live image" of your emmc contents.
Looks something like this:
Code:
// creates system
new Thread(new Runnable() {
public void run() {
upBar(35);
log.V("Creating the system image");
log.V("Command: " + "dd if=" + device.System() + " of=" + device.Storage() + "/romf/workdir/system.img");
UBER.requestSU();
UBER.cmdSU("dd if=" + device.System() + " of=" + device.Storage() + "/romf/workdir/system.img");
endCreateSystem.sendEmptyMessage(0);
}
})
.start();
Making it all work togetherStep 1: App loads and detects device. (First install downloads a payload zip with the update.bin)
Step 2: User begins the rom creation triggering...
Step 3: Generates the script and echo it through linux, with the device info. (su class use)
Step 4: Then the back ups are created using dd through linux. (su class use)
Step 5: Some good old java zip takes care of packaging, the update.bin, the system.img, and boot.img.
Ta da, creating a rom through android.Why don't they files corrupt using this methodThe data does not corrupt using my method because instead of copying directly changing files, im copying the latest "modified" version. also because of the image is ext3 or ext4 the files can be fixed during the dd if the change.ROM Factory 2 is going to use a new approach, instead of a list of devices, that class will be redesign to work with vold.fstab, and other methods of detecting the phones absolute partition location.
ameer1234567890 said:
Thank you for the details. I am guessing you are using an Atrix 4G.
There is an issue where I am unable to programmatically find the boot partition on some devices which does not have /proc/mtd and /proc/emmc
I have opened an issue for this. I am working on it. I shall post here when it is fixed.
For the time being, you can just restore backup done with Online Nandroid and then restore only the boot partition from a previous nandroid done with CWM.
Click to expand...
Click to collapse
I will continue to use CWM backup/restore until you have this resolved. The error occurs as soon as the restore starts as the boot partition is the first thing which is restored, so there is no opportunity for /system or /data to be restored. Hope you get this working for us because I like the idea of not rebooting to recovery to backup.
Cheers!
CaelanT said:
I will continue to use CWM backup/restore until you have this resolved. The error occurs as soon as the restore starts as the boot partition is the first thing which is restored, so there is no opportunity for /system or /data to be restored. Hope you get this working for us because I like the idea of not rebooting to recovery to backup.
Cheers!
Click to expand...
Click to collapse
I am working on a fix for this. If you could help me in testing it. Send me a PM and I shall send you the files.
ameer1234567890 said:
I am working on a fix for this. If you could help me in testing it. Send me a PM and I shall send you the files.
Click to expand...
Click to collapse
Back off, people, he can't accept so many volunteers.
I guess the worst thing that could happen is soft bricking. Right?
Right???
If so.. give short instructions on testing - what feedback you'd expect, log filest, etc. I might try it myself. Thanks!