diff --git a/stage23/entry.s2.c b/stage23/entry.s2.c index d8f91aae..a1724444 100644 --- a/stage23/entry.s2.c +++ b/stage23/entry.s2.c @@ -84,6 +84,9 @@ void entry(uint8_t boot_drive, int boot_from) { if (boot_from == BOOTED_FROM_HDD || boot_from == BOOTED_FROM_CD) { boot_volume = volume_get_by_coord(boot_drive, -1); + } else if (boot_from == BOOTED_FROM_PXE) { + pxe_init(); + boot_volume = pxe_bind_volume(); } volume_iterate_parts(boot_volume, diff --git a/stage23/fs/file.s2.c b/stage23/fs/file.s2.c index 95b328ea..a369bf2d 100644 --- a/stage23/fs/file.s2.c +++ b/stage23/fs/file.s2.c @@ -10,6 +10,7 @@ #include #include #include +#include bool fs_get_guid(struct guid *guid, struct volume *part) { if (echfs_check_signature(part)) { @@ -25,6 +26,20 @@ bool fs_get_guid(struct guid *guid, struct volume *part) { int fopen(struct file_handle *ret, struct volume *part, const char *filename) { ret->is_memfile = false; + if (part->pxe) { + struct tftp_file_handle *fd = ext_mem_alloc(sizeof(struct tftp_file_handle)); + + int r = tftp_open(fd, 0, 69, filename); + if (r) + return r; + + ret->fd = (void *)fd; + ret->read = (void *)tftp_read; + ret->size = fd->file_size; + + return 0; + } + if (iso9660_check_signature(part)) { struct iso9660_file_handle *fd = ext_mem_alloc(sizeof(struct iso9660_file_handle)); diff --git a/stage23/lib/part.h b/stage23/lib/part.h index 38c26be8..28f8fd46 100644 --- a/stage23/lib/part.h +++ b/stage23/lib/part.h @@ -18,6 +18,8 @@ struct volume { EFI_HANDLE efi_handle; #endif + bool pxe; + int drive; int partition; int sector_size; @@ -52,22 +54,29 @@ bool volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count #define volume_iterate_parts(_VOLUME_, _BODY_) ({ \ struct volume *_VOLUME = _VOLUME_; \ - while (_VOLUME->backing_dev != NULL) { \ - _VOLUME = _VOLUME->backing_dev; \ - } \ + if (_VOLUME->pxe) { \ + do { \ + struct volume *_PART = _VOLUME; \ + _BODY_ \ + } while (0); \ + } else { \ + while (_VOLUME->backing_dev != NULL) { \ + _VOLUME = _VOLUME->backing_dev; \ + } \ \ - int _PART_CNT = -1; \ - for (size_t _PARTNO = -1; ; _PARTNO++) { \ - if (_PART_CNT > _VOLUME->max_partition) \ - break; \ + int _PART_CNT = -1; \ + for (size_t _PARTNO = -1; ; _PARTNO++) { \ + if (_PART_CNT > _VOLUME->max_partition) \ + break; \ \ - struct volume *_PART = volume_get_by_coord(_VOLUME->drive, _PARTNO); \ - if (_PART == NULL) \ - continue; \ + struct volume *_PART = volume_get_by_coord(_VOLUME->drive, _PARTNO); \ + if (_PART == NULL) \ + continue; \ \ - _PART_CNT++; \ + _PART_CNT++; \ \ - _BODY_ \ + _BODY_ \ + } \ } \ }) diff --git a/stage23/lib/part.s2.c b/stage23/lib/part.s2.c index 7d918f0a..43f68fdf 100644 --- a/stage23/lib/part.s2.c +++ b/stage23/lib/part.s2.c @@ -41,6 +41,10 @@ static bool cache_block(struct volume *volume, uint64_t block) { } bool volume_read(struct volume *volume, void *buffer, uint64_t loc, uint64_t count) { + if (volume->pxe) { + panic("Attempted volume_read() on pxe"); + } + uint64_t block_size = BLOCK_SIZE_IN_SECTORS * volume->sector_size; uint64_t progress = 0; diff --git a/stage23/lib/uri.c b/stage23/lib/uri.c index 409d3d37..cd311a5c 100644 --- a/stage23/lib/uri.c +++ b/stage23/lib/uri.c @@ -177,7 +177,7 @@ static bool uri_tftp_dispatch(struct file_handle *fd, char *root, char *path) { static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path) { #if defined (bios) - if (false /*booted_from_pxe*/) + if (boot_volume->pxe) return uri_tftp_dispatch(fd, s_part, path); #endif diff --git a/stage23/mm/pmm.s2.c b/stage23/mm/pmm.s2.c index 2ed1fd7e..6c1f2a0d 100644 --- a/stage23/mm/pmm.s2.c +++ b/stage23/mm/pmm.s2.c @@ -406,6 +406,9 @@ void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type) } bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free_only, bool do_panic) { + if (length == 0) + return true; + uint64_t top = base + length; #if defined (bios) diff --git a/stage23/pxe/pxe.h b/stage23/pxe/pxe.h index a1a9ab65..84c86510 100644 --- a/stage23/pxe/pxe.h +++ b/stage23/pxe/pxe.h @@ -2,7 +2,9 @@ #define PXE_H #include +#include +struct volume *pxe_bind_volume(void); void pxe_init(void); int pxe_call(uint16_t opcode, uint16_t buf_seg, uint16_t buf_off) __attribute__((regparm(3))); @@ -56,18 +58,18 @@ struct pxenv { uint8_t checksum; uint32_t rm_entry; uint32_t pm_offset; - uint16_t pm_selector; - uint16_t stack_seg; - uint16_t stack_size; - uint16_t bc_code_seg; - uint16_t bc_code_size; - uint16_t bc_data_seg; - uint16_t bc_data_size; - uint16_t undi_data_seg; - uint16_t undi_data_size; - uint16_t undi_code_seg; - uint16_t undi_code_size; - uint32_t pxe_ptr; + uint16_t pm_selector; + uint16_t stack_seg; + uint16_t stack_size; + uint16_t bc_code_seg; + uint16_t bc_code_size; + uint16_t bc_data_seg; + uint16_t bc_data_size; + uint16_t undi_data_seg; + uint16_t undi_data_size; + uint16_t undi_code_seg; + uint16_t undi_code_size; + uint32_t pxe_ptr; } __attribute__((packed)); #define PXE_BANGPXE_SIGNATURE "!PXE" diff --git a/stage23/pxe/pxe.c b/stage23/pxe/pxe.s2.c similarity index 87% rename from stage23/pxe/pxe.c rename to stage23/pxe/pxe.s2.c index 60070f48..dac2c765 100644 --- a/stage23/pxe/pxe.c +++ b/stage23/pxe/pxe.s2.c @@ -5,9 +5,18 @@ #include #include #include +#include void set_pxe_fp(uint32_t fp); +struct volume *pxe_bind_volume(void) { + struct volume *volume = ext_mem_alloc(sizeof(struct volume)); + + volume->pxe = true; + + return volume; +} + void pxe_init(void) { //pxe installation check struct rm_regs r = { 0 }; diff --git a/stage23/pxe/tftp.h b/stage23/pxe/tftp.h index 0d0a64f3..08d9cc26 100644 --- a/stage23/pxe/tftp.h +++ b/stage23/pxe/tftp.h @@ -47,6 +47,6 @@ struct pxenv_get_file_size { //server_ip and server_port can be 0 for default int tftp_open(struct tftp_file_handle* handle, uint32_t server_ip, uint16_t server_port, const char* name); int tftp_read(void *fd, void *buf, uint64_t loc, uint64_t count); -uint32_t get_boot_server_info(); +uint32_t get_boot_server_info(void); #endif diff --git a/stage23/pxe/tftp.c b/stage23/pxe/tftp.s2.c similarity index 98% rename from stage23/pxe/tftp.c rename to stage23/pxe/tftp.s2.c index aab56e94..8ac88265 100644 --- a/stage23/pxe/tftp.c +++ b/stage23/pxe/tftp.s2.c @@ -8,7 +8,7 @@ #include #include -uint32_t get_boot_server_info() { +uint32_t get_boot_server_info(void) { struct pxenv_get_cached_info cachedinfo = { 0 }; cachedinfo.packet_type = 2; pxe_call(PXENV_GET_CACHED_INFO, ((uint16_t)rm_seg(&cachedinfo)), (uint16_t)rm_off(&cachedinfo));