diff --git a/handlers/diskpart_handler.c b/handlers/diskpart_handler.c
index 65010c1..cefe200 100644
--- a/handlers/diskpart_handler.c
+++ b/handlers/diskpart_handler.c
@@ -60,7 +60,8 @@ enum partfield {
 	PART_START,
 	PART_TYPE,
 	PART_NAME,
-	PART_FSTYPE
+	PART_FSTYPE,
+	PART_DOSTYPE
 };
 
 const char *fields[] = {
@@ -68,7 +69,8 @@ const char *fields[] = {
 	[PART_START] = "start",
 	[PART_TYPE] = "type",
 	[PART_NAME] = "name",
-	[PART_FSTYPE] = "fstype"
+	[PART_FSTYPE] = "fstype",
+	[PART_DOSTYPE] = "dostype"
 };
 
 struct partition_data {
@@ -78,6 +80,7 @@ struct partition_data {
 	char type[SWUPDATE_GENERAL_STRING_SIZE];
 	char name[SWUPDATE_GENERAL_STRING_SIZE];
 	char fstype[SWUPDATE_GENERAL_STRING_SIZE];
+	char dostype[SWUPDATE_GENERAL_STRING_SIZE];
 	LIST_ENTRY(partition_data) next;
 };
 LIST_HEAD(listparts, partition_data);
@@ -101,8 +104,17 @@ struct hnd_priv {
 static int diskpart_set_partition(struct fdisk_partition *pa,
 				  struct partition_data *part,
 				  unsigned long sector_size,
-				  struct fdisk_parttype *parttype)
+				  struct fdisk_parttype *parttype,
+				  unsigned long hybrid)
 {
+	TRACE("set partition-%zu:%s size %" PRIu64 " start %zu type %s%s%s",
+		  part->partno != LIBFDISK_INIT_UNDEF(part->partno) ? part->partno : 0,
+		  strlen(part->name) ? part->name : "UNDEF NAME",
+		  part->size != LIBFDISK_INIT_UNDEF(part->size) ? part->size / sector_size : 0,
+		  part->start!= LIBFDISK_INIT_UNDEF(part->start) ? part->start : 0,
+		  part->type,
+		  strlen(part->dostype) ? " dostype " : "",
+		  strlen(part->dostype) ? part->dostype : "");
 	int ret = 0;
 
 	if (!sector_size)
@@ -114,14 +126,14 @@ static int diskpart_set_partition(struct fdisk_partition *pa,
 		ret = fdisk_partition_set_start(pa, part->start);
 	else
 		ret = fdisk_partition_start_follow_default(pa, 1);
-	if (part->partno != LIBFDISK_INIT_UNDEF(part->partno))
+	if (!hybrid && part->partno != LIBFDISK_INIT_UNDEF(part->partno))
 		ret |= fdisk_partition_set_partno(pa, part->partno);
 	else
 		ret |= fdisk_partition_partno_follow_default(pa, 1);
-	if (strlen(part->name))
-	      ret |= fdisk_partition_set_name(pa, part->name);
+	if (!hybrid && strlen(part->name))
+		  ret |= fdisk_partition_set_name(pa, part->name);
 	if (part->size != LIBFDISK_INIT_UNDEF(part->size))
-	      ret |= fdisk_partition_set_size(pa, part->size / sector_size);
+		  ret |= fdisk_partition_set_size(pa, part->size / sector_size);
 	else
 		ret |= fdisk_partition_end_follow_default(pa, 1);
 
@@ -146,7 +158,7 @@ static bool diskpart_partition_cmp(const char *lbtype, struct fdisk_partition *f
 			(strcmp(fdisk_parttype_get_string(fdisk_partition_get_type(firstpa)),
 				fdisk_parttype_get_string(fdisk_partition_get_type(secondpa))) ||
 			strcmp(fdisk_partition_get_name(firstpa) ? fdisk_partition_get_name(firstpa) : "",
-		       		fdisk_partition_get_name(secondpa) ? fdisk_partition_get_name(secondpa) : ""))) ||
+					fdisk_partition_get_name(secondpa) ? fdisk_partition_get_name(secondpa) : ""))) ||
 		(!strcmp(lbtype, "dos") &&
 			fdisk_parttype_get_code(fdisk_partition_get_type(firstpa)) !=
 			fdisk_parttype_get_code(fdisk_partition_get_type(secondpa))) ||
@@ -168,15 +180,23 @@ static int diskpart(struct img_type *img,
 	struct dict_list *parts;
 	struct dict_list_elem *elem;
 	struct fdisk_context *cxt;
+	struct fdisk_context *doscxt = NULL;
 	struct partition_data *part;
 	struct partition_data *tmp;
 	struct fdisk_table *tb = NULL;
+	struct fdisk_table *dostb = NULL;
 	struct fdisk_table *oldtb = NULL;
+	struct fdisk_table *olddostb = NULL;
 	struct fdisk_parttype *parttype = NULL;
+	struct fdisk_parttype *dosparttype = NULL;
 	int ret = 0;
 	unsigned long i;
+	unsigned long hybrid = 0;
 	struct hnd_priv priv =  {FDISK_DISKLABEL_DOS};
 	bool createtable = false;
+	bool createdostable = false;
+
+	//fdisk_init_debug(0xffff);
 
 	if (!lbtype || (strcmp(lbtype, "gpt") && strcmp(lbtype, "dos"))) {
 		ERROR("Just GPT or DOS partition table are supported");
@@ -194,6 +214,8 @@ static int diskpart(struct img_type *img,
 		return -ENOMEM;
 	}
 
+	fdisk_disable_dialogs(cxt, 1);
+
 	ret = fdisk_assign_device(cxt, img->device, 0);
 	if (ret == -EACCES) {
 		ERROR("no access to %s", img->device);
@@ -247,18 +269,31 @@ static int diskpart(struct img_type *img,
 					case PART_FSTYPE:
 						strncpy(part->fstype, equal, sizeof(part->fstype));
 						break;
+					case PART_DOSTYPE:
+						strncpy(part->dostype, equal, sizeof(part->dostype));
+						hybrid++;
+						break;
 					}
 				}
 			}
 			elem = LIST_NEXT(elem, next);
 		}
 
-		TRACE("partition-%zu:%s size %" PRIu64 " start %zu type %s",
+		if (hybrid > 3) {
+			ERROR("I cannot add hybrid partition %zu(%s): hybrid dos partition limit of 3 exceeded",
+				  part->partno, strlen(part->name) ? part->name : "UNDEF NAME");
+			ret = -EINVAL;
+			goto handler_exit;
+		}
+
+		TRACE("partition-%zu:%s size %" PRIu64 " start %zu type %s%s%s",
 			part->partno != LIBFDISK_INIT_UNDEF(part->partno) ? part->partno : 0,
 			strlen(part->name) ? part->name : "UNDEF NAME",
 			part->size != LIBFDISK_INIT_UNDEF(part->size) ? part->size : 0,
 			part->start!= LIBFDISK_INIT_UNDEF(part->start) ? part->start : 0,
-			part->type);
+			part->type,
+			strlen(part->dostype) ? " dostype " : "",
+			strlen(part->dostype) ? part->dostype : "");
 
 		/*
 		 * Partitions in sw-description start from 1,
@@ -287,7 +322,11 @@ static int diskpart(struct img_type *img,
 	if (!fdisk_has_label(cxt)) {
 		WARN("%s does not contain a recognized partition table",
 		     img->device);
-		fdisk_create_disklabel(cxt, lbtype);
+		ret = fdisk_create_disklabel(cxt, lbtype);
+		if (ret) {
+			ERROR("Failed to create disk label");
+			goto handler_release;
+		}
 		createtable = true;
 	} else if (lbtype) {
 		if (!strcmp(lbtype, "gpt"))
@@ -298,12 +337,17 @@ static int diskpart(struct img_type *img,
 		if (!fdisk_is_labeltype(cxt, priv.labeltype)) {
 			WARN("Partition table of different type, setting to %s, all data lost !",
 				lbtype);
-			fdisk_create_disklabel(cxt, lbtype);
+			ret = fdisk_create_disklabel(cxt, lbtype);
+			if (ret) {
+				ERROR("Failed to create disk label");
+				goto handler_release;
+			}
 			createtable = true;
 		}
 	}
 
 	struct fdisk_label *lb = fdisk_get_label(cxt, NULL);
+	struct fdisk_label *doslb = NULL;
 	unsigned long sector_size = fdisk_get_sector_size(cxt);
 
 	/*
@@ -321,6 +365,32 @@ static int diskpart(struct img_type *img,
 		goto handler_exit;
 	}
 
+	if (hybrid) {
+		doscxt = fdisk_new_nested_context(cxt, "dos");
+		fdisk_disable_dialogs(doscxt, 1);
+
+		if (!fdisk_is_labeltype(doscxt, FDISK_DISKLABEL_DOS)) {
+			ret = fdisk_create_disklabel(doscxt, NULL);
+			if (ret) {
+				ERROR("Failed to create hybrid disk label");
+				goto handler_release;
+			}
+			createdostable = true;
+		}
+
+		doslb = fdisk_get_label(doscxt, "dos");
+		dostb = fdisk_new_table();
+
+		if (fdisk_get_partitions(doscxt, &olddostb))
+			createdostable = true;
+
+		if (!dostb) {
+			ERROR("OOM creating new table !");
+			ret = -ENOMEM;
+			goto handler_exit;
+		}
+	}
+
 	i = 0;
 
 	LIST_FOREACH(part, &priv.listparts, next) {
@@ -334,10 +404,30 @@ static int diskpart(struct img_type *img,
 			parttype = fdisk_label_get_parttype_from_string(lb, part->type);
 			if (!parttype)
 				parttype = fdisk_label_get_parttype_from_string(lb, GPT_DEFAULT_ENTRY_TYPE);
+			if (strlen(part->dostype)) {
+				struct fdisk_partition *newdospa;
+				newdospa = fdisk_new_partition();
+				dosparttype = fdisk_label_get_parttype_from_code(doslb, ustrtoull(part->dostype, 16));
+				if (!dosparttype) {
+					WARN("Failed to set partition type for hybrid partition: %zu(%s)", part->partno, part->name);
+				}
+				ret = diskpart_set_partition(newdospa, part, sector_size, dosparttype, hybrid);
+				if (ret) {
+					WARN("I cannot set all hybrid partition's parameters");
+				}
+				if ((ret = fdisk_table_add_partition(dostb, newdospa)) < 0) {
+					ERROR("I cannot add hybrid partition %zu(%s): %d", part->partno, part->name, ret);
+				}
+				fdisk_unref_partition(newdospa);
+				if (ret < 0) {
+					fdisk_unref_partition(newpa);
+					goto handler_exit;
+				}
+			}
 		} else {
 			parttype = fdisk_label_get_parttype_from_code(lb, ustrtoull(part->type, 16));
 		}
-		ret = diskpart_set_partition(newpa, part, sector_size, parttype);
+		ret = diskpart_set_partition(newpa, part, sector_size, parttype, 0);
 		if (ret) {
 			WARN("I cannot set all partition's parameters");
 		}
@@ -350,6 +440,31 @@ static int diskpart(struct img_type *img,
 		i++;
 	}
 
+	if (hybrid) {
+		struct fdisk_partition *newpa;
+		newpa = fdisk_new_partition();
+		part = (struct partition_data *)calloc(1, sizeof(struct partition_data));
+		if (!part) {
+			ERROR("FAULT: no memory");
+			ret = -ENOMEM;
+			goto handler_exit;
+		}
+		part->start = 1;
+		part->size = 33 * sector_size;
+		dosparttype = fdisk_label_get_parttype_from_code(doslb, 0xee);
+		ret = diskpart_set_partition(newpa, part, sector_size, dosparttype, hybrid);
+		if (ret) {
+			WARN("I cannot set all pmbr partition's parameters");
+		}
+		if ((ret = fdisk_table_add_partition(dostb, newpa)) < 0) {
+			ERROR("I cannot add the pmbr partition");
+		}
+		fdisk_unref_partition(newpa);
+		if (ret < 0)
+			goto handler_exit;
+		hybrid++;
+	}
+
 	/*
 	 * A partiton table was found on disk, now compares the two tables
 	 * to check if they differ.
@@ -387,6 +502,69 @@ static int diskpart(struct img_type *img,
 		}
 	}
 
+	/*
+	 * A dos partiton table was found on disk, now compares the two tables
+	 * to check if they differ.
+	 */
+	/*
+	if (hybrid && !createdostable) {
+		size_t numpartondisk = fdisk_table_get_nents(olddostb);
+
+		i = hybrid;
+		if (numpartondisk != i) {
+			TRACE("Number of hybrid partitions differs on disk: %lu <--> requested: %lu",
+				  (long unsigned int)numpartondisk, i);
+			createdostable = true;
+		} else {
+			struct fdisk_partition *pa, *newpa;
+			struct fdisk_iter *itr	 = fdisk_new_iter(FDISK_ITER_FORWARD);
+			struct fdisk_iter *olditr = fdisk_new_iter(FDISK_ITER_FORWARD);
+
+			i = 0;
+			while (i < numpartondisk && !createdostable) {
+				newpa=NULL;
+				pa = NULL;
+				if (fdisk_table_next_partition (dostb, itr, &newpa) ||
+					fdisk_table_next_partition (olddostb, olditr, &pa)) {
+					TRACE("Hybrid partition not found, something went wrong %lu !", i);
+					ret = -EFAULT;
+					goto handler_exit;
+				}
+				if (diskpart_partition_cmp("dos", pa, newpa)) {
+					createdostable = true;
+				}
+
+				fdisk_unref_partition(newpa);
+				fdisk_unref_partition(pa);
+				i++;
+			}
+		}
+	}
+	*/
+	if (hybrid) {
+		// TODO fix dos table comparison
+		createdostable = true;
+	}
+
+	if (createdostable) {
+		TRACE("Hybrid partitions on disk differ, write to disk;");
+		fdisk_delete_all_partitions(doscxt);
+		ret = fdisk_apply_table(doscxt, dostb);
+		if (ret) {
+			ERROR("Hybrid partition table cannot be applied! %d", ret);
+			goto handler_exit;
+		}
+
+		/*
+		 * Everything done, write into disk
+		 */
+		ret = fdisk_write_disklabel(doscxt);
+		if (ret) {
+			ERROR("Hybrid partition table cannot be written on disk %d", ret);
+			goto handler_exit;
+		}
+	}
+
 	if (createtable) {
 		TRACE("Partitions on disk differ, write to disk;");
 		fdisk_delete_all_partitions(cxt);
@@ -412,12 +590,16 @@ static int diskpart(struct img_type *img,
 handler_exit:
 	if (tb)
 		fdisk_unref_table(tb);
+	if (dostb)
+		fdisk_unref_table(dostb);
 	if (oldtb)
 		fdisk_unref_table(oldtb);
 	if (fdisk_deassign_device(cxt, 0))
 		WARN("Error deassign device %s", img->device);
 
 handler_release:
+	if (fdisk_get_parent(doscxt))
+		fdisk_unref_context(doscxt);
 	fdisk_unref_context(cxt);
 
 	/*
