[syslinux] [PATCH 08/12] core: introduce multidisk syntax for accessing a disk using it's MBR signature
Andre Ericson
de.ericson at gmail.com
Mon Aug 20 01:16:50 PDT 2012
Introduce "(mbr:0x12345678,2)/foo/bar" like syntax to access the disk with
MBR signature of 0x1234568 and the partition number 2.
Signed-off-by: Andre Ericson <de.ericson at gmail.com>
---
core/fs/fs.c | 2 +-
core/fs/readdir.c | 2 +-
core/include/multidisk.h | 2 +-
core/multidisk.c | 94 +++++++++++++++++++++++++++++++++++++-----------
4 files changed, 76 insertions(+), 24 deletions(-)
diff --git a/core/fs/fs.c b/core/fs/fs.c
index 9f9e4fc..df82578 100644
--- a/core/fs/fs.c
+++ b/core/fs/fs.c
@@ -494,7 +494,7 @@ int open_file(const char *name, struct com32_filedata *filedata)
struct muldisk_path *mul_path;
if (name[0] == '(') {
- mul_path = muldisk_path_parse(name);
+ mul_path = hdd_part_from_mdpath(name);
if (!mul_path)
return -1;
diff --git a/core/fs/readdir.c b/core/fs/readdir.c
index fe68b01..20f60d7 100644
--- a/core/fs/readdir.c
+++ b/core/fs/readdir.c
@@ -16,7 +16,7 @@ DIR *opendir(const char *path)
if (path[0] == '(') {
- mul_path = muldisk_path_parse(path);
+ mul_path = hdd_part_from_mdpath(path);
if (!mul_path)
return NULL;
diff --git a/core/include/multidisk.h b/core/include/multidisk.h
index 2515887..1e43d4a 100644
--- a/core/include/multidisk.h
+++ b/core/include/multidisk.h
@@ -11,6 +11,6 @@ struct muldisk_path {
int find_partition(struct part_iter **_iter, int drive, int partition);
int add_fs(struct fs_info *fs, uint8_t disk, uint8_t partition);
struct fs_info *get_fs(uint8_t disk, uint8_t partition);
-struct muldisk_path* muldisk_path_parse(const char *path);
+struct muldisk_path* hdd_part_from_mdpath(const char *path);
#endif /* MULTIDISK_H */
diff --git a/core/multidisk.c b/core/multidisk.c
index 78d3dbf..3cc8f7b 100644
--- a/core/multidisk.c
+++ b/core/multidisk.c
@@ -104,13 +104,28 @@ bail:
return -1;
}
-struct muldisk_path* muldisk_path_parse(const char *path)
+static uint8_t charhex_to_hex(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 0xa;
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 0xa;
+ return 0xff;
+}
+
+struct muldisk_path* hdd_part_from_mdpath(const char *path)
{
struct muldisk_path *mpath;
+ struct disk_dos_mbr *mbr = NULL;
+ struct disk_info diskinfo;
const char *c = path;
char buff[4];
uint8_t hdd = 0;
uint8_t partition = 0;
+ uint32_t mbr_sig = 0;
+ int disk;
int i = 0;
int mult = 1;
@@ -120,6 +135,7 @@ struct muldisk_path* muldisk_path_parse(const char *path)
if (path[1] == 'h' && path[2] == 'd') {
c += 2;
+
/* get hdd number */
for (++c; *c && *c != ','; ++c)
buff[i++] = *c;
@@ -129,32 +145,68 @@ struct muldisk_path* muldisk_path_parse(const char *path)
/* str to uint8_t */
while (i--) {
+ if (buff[i] < '0' || buff[i] > '9')
+ goto bail;
hdd += (buff[i] - 48) * mult;
mult *= 10;
}
- mpath->hdd = hdd;
- /* get partition number */
- i = 0;
- for (++c; *c && *c != ')'; ++c)
- buff[i++] = *c;
- if (!*c)
- goto bail;
- buff[i] = '\0';
+ } else if (!strncmp(path + 1, "mbr:0x", 6)) {
+ c += 6;
+
+ /* get mbr sig */
+ for (++c; *c && *c != ','; ++c) {
+ mbr_sig = mbr_sig << 4;
+ i = charhex_to_hex(*c);
+ if (i == 0xff)
+ goto bail;
+ mbr_sig += i;
+ }
- /* str to uint8_t */
- mult = 1;
- while (i--) {
- partition += (buff[i] - 48) * mult;
- mult *= 10;
+ /* find hdd from mbr */
+ for (disk = 0x80; disk < 0xff; disk++) {
+ if (disk_get_params(disk, &diskinfo))
+ continue;
+ if (!(mbr = disk_read_sectors(&diskinfo, 0, 1)))
+ continue;
+ if (mbr->sig != disk_mbr_sig_magic)
+ continue;
+ if (mbr_sig == mbr->disk_sig) {
+ hdd = disk - 0x80;
+ free(mbr);
+ break;
+ }
+ free(mbr);
}
- mpath->partition = partition;
- i = 0;
- /* c was on ')' jump it and stop at beginning of path */
- for (c++; *c; c++)
- mpath->relative_name[i++] = *c;
- mpath->relative_name[i] = '\0';
- return mpath;
+ if (disk == 0xff)
+ goto bail;
+
+ } else {
+ goto bail;
+ }
+ /* get partition number */
+ i = 0;
+ for (++c; *c && *c != ')'; ++c)
+ buff[i++] = *c;
+ if (!*c)
+ goto bail;
+ buff[i] = '\0';
+
+ /* str to uint8_t */
+ mult = 1;
+ while (i--) {
+ if (buff[i] < '0' || buff[i] > '9')
+ goto bail;
+ partition += (buff[i] - 48) * mult;
+ mult *= 10;
}
+ mpath->partition = partition;
+ mpath->hdd = hdd;
+ i = 0;
+ /* c was on ')' jump it and stop at beginning of path */
+ for (c++; *c; c++)
+ mpath->relative_name[i++] = *c;
+ mpath->relative_name[i] = '\0';
+ return mpath;
bail:
free(mpath);
--
1.7.11.3
More information about the Syslinux
mailing list