-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreadaccess.c
executable file
·127 lines (113 loc) · 3.81 KB
/
readaccess.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//
// Created by Paul on 2/23/2018.
//
#define _LARGEFILE64_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/file.h>
#include <string.h>
#include <endian.h>
#include <sys/stat.h>
#include <errno.h>
#include "debug.h"
/*********************************************************************************************
drive access routines
In a bootloader, these three routines are likely to access eMMC or use a FTL directly.
For testing under Linux, we use standard i/o.
*****/
tDrive * openDrive( const char *drivePath )
{
tDrive * drive = calloc( sizeof(tDrive), 1 );
if (drive != NULL)
{
drive->sectorSize = 512;
drive->id = open(drivePath, O_RDONLY);
if (drive->id < 0)
{
LogError( "unable to open \'%s\' (%d: %s)",
drivePath, errno, strerror(errno) );
free(drive);
drive = NULL;
}
else
{
struct stat st;
if ( fstat( drive->id, &st) < 0 )
{
LogError( "unable to get the size of the drive (%d: %s)", errno, strerror(errno) );
}
else
{
drive->partition.start = 0;
drive->partition.length = 4096;
LogInfo( "drive size %ld (%.2f MB)",
drive->partition.length,
drive->partition.length / 1048576.0 );
drive->path = strdup(drivePath);
if (drive->path == NULL)
{
LogError( "### unable to store the path \'%s\' (%d: %s)\n",
drivePath, errno, strerror(errno) );
free(drive);
drive = NULL;
}
}
}
}
return (drive);
}
void setPartition( tDrive * drive, off64_t offset, size_t length )
{
drive->partition.start = offset;
drive->partition.length = length;
LogInfo( "partition start %ld (%#lx), size %ld (%.2f MB)",
drive->partition.start, drive->partition.start,
drive->partition.length, drive->partition.length / 1048576.0 );
}
ssize_t readDrive( tDrive * drive, off64_t offset, void * dest, size_t length )
{
ssize_t result = 0;
LogInfo( "readDrive( offset %#lx, %ld (%#lx) bytes)", offset, length, length );
if ( drive != NULL )
{
if ( (offset + length) > drive->partition.length )
{
LogError( "read requested past the end of partition (%ld + %ld > %ld)",
offset, length, drive->partition.start + drive->partition.length );
}
else
{
if ( lseek64( drive->id, drive->partition.start + offset, SEEK_SET ) < 0 )
{
LogError( "seek to offset %lu failed (%d: %s)",
drive->partition.start + offset, errno, strerror( errno ) );
}
else
{
result = read( drive->id, dest, length );
if ( result < 0 )
{
LogError( "read @ offset %lu for %lu bytes failed (%d: %s)\n",
offset, length, errno, strerror( errno ) );
}
}
}
}
return (result);
}
void closeDrive( tDrive * drive )
{
if (drive != NULL)
{
if (drive->id >= 0)
{
close(drive->id);
drive->id = -1;
}
}
}
/*******************************************************************************************\
| end of drive access routines |
\*******************************************************************************************/