Procházet zdrojové kódy

Add PXE FILE API.

tags/v0.9.3
Michael Brown před 17 roky
rodič
revize
950057eeed

+ 25
- 0
src/arch/i386/interface/pxe/pxe_call.c Zobrazit soubor

@@ -91,6 +91,11 @@ union pxenv_call {
91 91
 			( struct s_PXENV_UNDI_GET_IFACE_INFO * );
92 92
 	PXENV_EXIT_t ( * undi_get_state ) ( struct s_PXENV_UNDI_GET_STATE * );
93 93
 	PXENV_EXIT_t ( * undi_isr ) ( struct s_PXENV_UNDI_ISR * );
94
+	PXENV_EXIT_t ( * file_open ) ( struct s_PXENV_FILE_OPEN * );
95
+	PXENV_EXIT_t ( * file_close ) ( struct s_PXENV_FILE_CLOSE * );
96
+	PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
97
+	PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
98
+	PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * );
94 99
 };
95 100
 
96 101
 /**
@@ -269,6 +274,26 @@ __cdecl void pxe_api_call ( struct i386_all_regs *ix86 ) {
269 274
 		pxenv_call.undi_isr = pxenv_undi_isr;
270 275
 		param_len = sizeof ( pxenv_any.undi_isr );
271 276
 		break;
277
+	case PXENV_FILE_OPEN:
278
+		pxenv_call.file_open = pxenv_file_open;
279
+		param_len = sizeof ( pxenv_any.file_open );
280
+		break;
281
+	case PXENV_FILE_CLOSE:
282
+		pxenv_call.file_close = pxenv_file_close;
283
+		param_len = sizeof ( pxenv_any.file_close );
284
+		break;
285
+	case PXENV_FILE_SELECT:
286
+		pxenv_call.file_select = pxenv_file_select;
287
+		param_len = sizeof ( pxenv_any.file_select );
288
+		break;
289
+	case PXENV_FILE_READ:
290
+		pxenv_call.file_read = pxenv_file_read;
291
+		param_len = sizeof ( pxenv_any.file_read );
292
+		break;
293
+	case PXENV_GET_FILE_SIZE:
294
+		pxenv_call.get_file_size = pxenv_get_file_size;
295
+		param_len = sizeof ( pxenv_any.get_file_size );
296
+		break;
272 297
 	default:
273 298
 		DBG ( "PXENV_UNKNOWN_%hx", opcode );
274 299
 		pxenv_call.unknown = pxenv_unknown;

+ 5
- 0
src/include/pxe.h Zobrazit soubor

@@ -58,6 +58,11 @@ union u_PXENV_ANY {
58 58
 	struct s_PXENV_UNDI_GET_IFACE_INFO	undi_get_iface_info;
59 59
 	struct s_PXENV_UNDI_GET_STATE		undi_get_state;
60 60
 	struct s_PXENV_UNDI_ISR			undi_isr;
61
+	struct s_PXENV_FILE_OPEN		file_open;
62
+	struct s_PXENV_FILE_CLOSE		file_close;
63
+	struct s_PXENV_FILE_SELECT		file_select;
64
+	struct s_PXENV_FILE_READ		file_read;
65
+	struct s_PXENV_GET_FILE_SIZE		get_file_size;
61 66
 };
62 67
 
63 68
 typedef union u_PXENV_ANY PXENV_ANY_t;

+ 131
- 0
src/include/pxe_api.h Zobrazit soubor

@@ -1555,6 +1555,137 @@ extern PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr );
1555 1555
 
1556 1556
 /** @} */ /* pxe_undi_api */
1557 1557
 
1558
+/** @defgroup pxe_file_api PXE FILE API
1559
+ *
1560
+ * POSIX-like file operations
1561
+ *
1562
+ * @{
1563
+ */
1564
+
1565
+/** @defgroup pxenv_file_open PXENV_FILE_OPEN
1566
+ *
1567
+ * FILE OPEN
1568
+ *
1569
+ * @{
1570
+ */
1571
+
1572
+/** PXE API function code for pxenv_file_open() */
1573
+#define PXENV_FILE_OPEN			0x00e0
1574
+
1575
+/** Parameter block for pxenv_file_open() */
1576
+struct s_PXENV_FILE_OPEN {
1577
+	PXENV_STATUS_t Status;		/**< PXE status code */
1578
+	UINT16_t FileHandle;		/**< File handle */
1579
+	SEGOFF16_t FileName;		/**< File URL */
1580
+	UINT32_t Reserved;		/**< Reserved */
1581
+} PACKED;
1582
+
1583
+typedef struct s_PXENV_FILE_OPEN PXENV_FILE_OPEN_t;
1584
+
1585
+extern PXENV_EXIT_t pxenv_file_open ( struct s_PXENV_FILE_OPEN *file_open );
1586
+
1587
+/** @} */ /* pxenv_file_open */
1588
+
1589
+/** @defgroup pxenv_file_close PXENV_FILE_CLOSE
1590
+ *
1591
+ * FILE CLOSE
1592
+ *
1593
+ * @{
1594
+ */
1595
+
1596
+/** PXE API function code for pxenv_file_close() */
1597
+#define PXENV_FILE_CLOSE		0x00e1
1598
+
1599
+/** Parameter block for pxenv_file_close() */
1600
+struct s_PXENV_FILE_CLOSE {
1601
+	PXENV_STATUS_t Status;		/**< PXE status code */
1602
+	UINT16_t FileHandle;		/**< File handle */
1603
+} PACKED;
1604
+
1605
+typedef struct s_PXENV_FILE_CLOSE PXENV_FILE_CLOSE_t;
1606
+
1607
+extern PXENV_EXIT_t pxenv_file_close ( struct s_PXENV_FILE_CLOSE
1608
+				       *file_close );
1609
+
1610
+/** @} */ /* pxenv_file_close */
1611
+
1612
+/** @defgroup pxenv_file_select PXENV_FILE_SELECT
1613
+ *
1614
+ * FILE SELECT
1615
+ *
1616
+ * @{
1617
+ */
1618
+
1619
+/** PXE API function code for pxenv_file_select() */
1620
+#define PXENV_FILE_SELECT		0x00e2
1621
+
1622
+/** File is ready for reading */
1623
+#define RDY_READ			0x0001
1624
+
1625
+/** Parameter block for pxenv_file_select() */
1626
+struct s_PXENV_FILE_SELECT {
1627
+	PXENV_STATUS_t Status;		/**< PXE status code */
1628
+	UINT16_t FileHandle;		/**< File handle */
1629
+	UINT16_t Ready;			/**< Indication of readiness */
1630
+} PACKED;
1631
+
1632
+typedef struct s_PXENV_FILE_SELECT PXENV_FILE_SELECT_t;
1633
+
1634
+extern PXENV_EXIT_t pxenv_file_select ( struct s_PXENV_FILE_SELECT
1635
+					*file_select );
1636
+
1637
+/** @} */ /* pxenv_file_select */
1638
+
1639
+/** @defgroup pxenv_file_read PXENV_FILE_READ
1640
+ *
1641
+ * FILE READ
1642
+ *
1643
+ * @{
1644
+ */
1645
+
1646
+/** PXE API function code for pxenv_file_read() */
1647
+#define PXENV_FILE_READ		0x00e3
1648
+
1649
+/** Parameter block for pxenv_file_read() */
1650
+struct s_PXENV_FILE_READ {
1651
+	PXENV_STATUS_t Status;		/**< PXE status code */
1652
+	UINT16_t FileHandle;		/**< File handle */
1653
+	UINT16_t BufferSize;		/**< Data buffer size */
1654
+	SEGOFF16_t Buffer;		/**< Data buffer */
1655
+} PACKED;
1656
+
1657
+typedef struct s_PXENV_FILE_READ PXENV_FILE_READ_t;
1658
+
1659
+extern PXENV_EXIT_t pxenv_file_read ( struct s_PXENV_FILE_READ *file_read );
1660
+
1661
+/** @} */ /* pxenv_file_read */
1662
+
1663
+/** @defgroup pxenv_get_file_size PXENV_GET_FILE_SIZE
1664
+ *
1665
+ * GET FILE SIZE
1666
+ *
1667
+ * @{
1668
+ */
1669
+
1670
+/** PXE API function code for pxenv_get_file_size() */
1671
+#define PXENV_GET_FILE_SIZE		0x00e4
1672
+
1673
+/** Parameter block for pxenv_get_file_size() */
1674
+struct s_PXENV_GET_FILE_SIZE {
1675
+	PXENV_STATUS_t Status;		/**< PXE status code */
1676
+	UINT16_t FileHandle;		/**< File handle */
1677
+	UINT32_t FileSize;		/**< File size */
1678
+} PACKED;
1679
+
1680
+typedef struct s_PXENV_GET_FILE_SIZE PXENV_GET_FILE_SIZE_t;
1681
+
1682
+extern PXENV_EXIT_t pxenv_get_file_size ( struct s_PXENV_GET_FILE_SIZE
1683
+					  *get_file_size );
1684
+
1685
+/** @} */ /* pxenv_get_file_size */
1686
+
1687
+/** @} */ /* pxe_file_api */
1688
+
1558 1689
 /** @defgroup pxe_loader_api PXE Loader API
1559 1690
  *
1560 1691
  * The UNDI ROM loader API

+ 191
- 0
src/interface/pxe/pxe_file.c Zobrazit soubor

@@ -0,0 +1,191 @@
1
+/** @file
2
+ *
3
+ * PXE FILE API
4
+ *
5
+ */
6
+
7
+#include <stdlib.h>
8
+#include <stdio.h>
9
+#include <errno.h>
10
+#include <byteswap.h>
11
+#include <gpxe/uaccess.h>
12
+#include <gpxe/posix_io.h>
13
+#include <gpxe/features.h>
14
+#include <pxe.h>
15
+
16
+/*
17
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
18
+ *
19
+ * This program is free software; you can redistribute it and/or
20
+ * modify it under the terms of the GNU General Public License as
21
+ * published by the Free Software Foundation; either version 2 of the
22
+ * License, or any later version.
23
+ *
24
+ * This program is distributed in the hope that it will be useful, but
25
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27
+ * General Public License for more details.
28
+ *
29
+ * You should have received a copy of the GNU General Public License
30
+ * along with this program; if not, write to the Free Software
31
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32
+ */
33
+
34
+FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 1 );
35
+
36
+/**
37
+ * FILE OPEN
38
+ *
39
+ * @v file_open				Pointer to a struct s_PXENV_FILE_OPEN
40
+ * @v s_PXENV_FILE_OPEN::FileName	URL of file to open
41
+ * @ret #PXENV_EXIT_SUCCESS		File was opened
42
+ * @ret #PXENV_EXIT_FAILURE		File was not opened
43
+ * @ret s_PXENV_FILE_OPEN::Status	PXE status code
44
+ * @ret s_PXENV_FILE_OPEN::FileHandle	Handle of opened file
45
+ *
46
+ */
47
+PXENV_EXIT_t pxenv_file_open ( struct s_PXENV_FILE_OPEN *file_open ) {
48
+	userptr_t filename;
49
+	size_t filename_len;
50
+	int fd;
51
+
52
+	DBG ( "PXENV_FILE_OPEN" );
53
+
54
+	/* Copy name from external program, and open it */
55
+	filename = real_to_user ( file_open->FileName.segment,
56
+			      file_open->FileName.offset );
57
+	filename_len = strlen_user ( filename, 0 );
58
+	{
59
+		char uri_string[ filename_len + 1 ];
60
+
61
+		copy_from_user ( uri_string, filename, 0,
62
+				 sizeof ( uri_string ) );
63
+		DBG ( " %s", uri_string );
64
+		fd = open ( uri_string );
65
+	}
66
+
67
+	if ( fd < 0 ) {
68
+		file_open->Status = PXENV_STATUS ( fd );
69
+		return PXENV_EXIT_FAILURE;
70
+	}
71
+
72
+	DBG ( " as file %d", fd );
73
+
74
+	file_open->FileHandle = fd;
75
+	file_open->Status = PXENV_STATUS_SUCCESS;
76
+	return PXENV_EXIT_SUCCESS;
77
+}
78
+
79
+/**
80
+ * FILE CLOSE
81
+ *
82
+ * @v file_close			Pointer to a struct s_PXENV_FILE_CLOSE
83
+ * @v s_PXENV_FILE_CLOSE::FileHandle	File handle
84
+ * @ret #PXENV_EXIT_SUCCESS		File was closed
85
+ * @ret #PXENV_EXIT_FAILURE		File was not closed
86
+ * @ret s_PXENV_FILE_CLOSE::Status	PXE status code
87
+ *
88
+ */
89
+PXENV_EXIT_t pxenv_file_close ( struct s_PXENV_FILE_CLOSE *file_close ) {
90
+
91
+	DBG ( "PXENV_FILE_CLOSE %d", file_close->FileHandle );
92
+
93
+	close ( file_close->FileHandle );
94
+	file_close->Status = PXENV_STATUS_SUCCESS;
95
+	return PXENV_EXIT_SUCCESS;
96
+}
97
+
98
+/**
99
+ * FILE SELECT
100
+ *
101
+ * @v file_select			Pointer to a struct s_PXENV_FILE_SELECT
102
+ * @v s_PXENV_FILE_SELECT::FileHandle	File handle
103
+ * @ret #PXENV_EXIT_SUCCESS		File has been checked for readiness
104
+ * @ret #PXENV_EXIT_FAILURE		File has not been checked for readiness
105
+ * @ret s_PXENV_FILE_SELECT::Status	PXE status code
106
+ * @ret s_PXENV_FILE_SELECT::Ready	Indication of readiness
107
+ *
108
+ */
109
+PXENV_EXIT_t pxenv_file_select ( struct s_PXENV_FILE_SELECT *file_select ) {
110
+	fd_set fdset;
111
+	int ready;
112
+
113
+	DBG ( "PXENV_FILE_SELECT %d", file_select->FileHandle );
114
+
115
+	FD_ZERO ( &fdset );
116
+	FD_SET ( file_select->FileHandle, &fdset );
117
+	if ( ( ready = select ( &fdset, 0 ) ) < 0 ) {
118
+		file_select->Status = PXENV_STATUS ( ready );
119
+		return PXENV_EXIT_FAILURE;
120
+	}
121
+
122
+	file_select->Ready = ( ready ? RDY_READ : 0 );
123
+	file_select->Status = PXENV_STATUS_SUCCESS;
124
+	return PXENV_EXIT_SUCCESS;
125
+}
126
+
127
+/**
128
+ * FILE READ
129
+ *
130
+ * @v file_read				Pointer to a struct s_PXENV_FILE_READ
131
+ * @v s_PXENV_FILE_READ::FileHandle	File handle
132
+ * @v s_PXENV_FILE_READ::BufferSize	Size of data buffer
133
+ * @v s_PXENV_FILE_READ::Buffer		Data buffer
134
+ * @ret #PXENV_EXIT_SUCCESS		Data has been read from file
135
+ * @ret #PXENV_EXIT_FAILURE		Data has not been read from file
136
+ * @ret s_PXENV_FILE_READ::Status	PXE status code
137
+ * @ret s_PXENV_FILE_READ::Ready	Indication of readiness
138
+ * @ret s_PXENV_FILE_READ::BufferSize	Length of data read
139
+ *
140
+ */
141
+PXENV_EXIT_t pxenv_file_read ( struct s_PXENV_FILE_READ *file_read ) {
142
+	userptr_t buffer;
143
+	ssize_t len;
144
+
145
+	DBG ( "PXENV_FILE_READ %d to %04x:%04x+%04x", file_read->FileHandle,
146
+	      file_read->Buffer.segment, file_read->Buffer.offset,
147
+	      file_read->BufferSize );
148
+
149
+	buffer = real_to_user ( file_read->Buffer.segment,
150
+				file_read->Buffer.offset );
151
+	if ( ( len = read_user ( file_read->FileHandle, buffer, 0,
152
+				file_read->BufferSize ) ) < 0 ) {
153
+		file_read->Status = PXENV_STATUS ( len );
154
+		return PXENV_EXIT_FAILURE;
155
+	}
156
+
157
+	DBG ( " read %04zx", ( ( size_t ) len ) );
158
+
159
+	file_read->BufferSize = len;
160
+	file_read->Status = PXENV_STATUS_SUCCESS;
161
+	return PXENV_EXIT_SUCCESS;
162
+}
163
+
164
+/**
165
+ * GET FILE SIZE
166
+ *
167
+ * @v get_file_size			Pointer to a struct s_PXENV_GET_FILE_SIZE
168
+ * @v s_PXENV_GET_FILE_SIZE::FileHandle	File handle
169
+ * @ret #PXENV_EXIT_SUCCESS		File size has been determined
170
+ * @ret #PXENV_EXIT_FAILURE		File size has not been determined
171
+ * @ret s_PXENV_GET_FILE_SIZE::Status	PXE status code
172
+ * @ret s_PXENV_GET_FILE_SIZE::FileSize	Size of file
173
+ */
174
+PXENV_EXIT_t pxenv_get_file_size ( struct s_PXENV_GET_FILE_SIZE
175
+				   *get_file_size ) {
176
+	ssize_t filesize;
177
+
178
+	DBG ( "PXENV_GET_FILE_SIZE %d", get_file_size->FileHandle );
179
+
180
+	filesize = fsize ( get_file_size->FileHandle );
181
+	if ( filesize < 0 ) {
182
+		get_file_size->Status = PXENV_STATUS ( filesize );
183
+		return PXENV_EXIT_FAILURE;
184
+	}
185
+
186
+	DBG ( " is %zd", ( ( size_t ) filesize ) );
187
+
188
+	get_file_size->FileSize = filesize;
189
+	get_file_size->Status = PXENV_STATUS_SUCCESS;
190
+	return PXENV_EXIT_SUCCESS;
191
+}

Načítá se…
Zrušit
Uložit