mirror of
https://github.com/ipxe/ipxe
synced 2025-12-19 11:00:27 +03:00
[comboot] Remove userptr_t from COMBOOT image parsing
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -162,15 +162,13 @@ static int com32_exec_loop ( struct image *image ) {
|
|||||||
static int com32_identify ( struct image *image ) {
|
static int com32_identify ( struct image *image ) {
|
||||||
const char *ext;
|
const char *ext;
|
||||||
static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 };
|
static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 };
|
||||||
uint8_t buf[5];
|
|
||||||
|
|
||||||
if ( image->len >= 5 ) {
|
if ( image->len >= sizeof ( magic ) ) {
|
||||||
/* Check for magic number
|
/* Check for magic number
|
||||||
* mov eax,21cd4cffh
|
* mov eax,21cd4cffh
|
||||||
* B8 FF 4C CD 21
|
* B8 FF 4C CD 21
|
||||||
*/
|
*/
|
||||||
copy_from_user ( buf, image->data, 0, sizeof(buf) );
|
if ( memcmp ( image->data, magic, sizeof ( magic) ) == 0 ) {
|
||||||
if ( ! memcmp ( buf, magic, sizeof(buf) ) ) {
|
|
||||||
DBGC ( image, "COM32 %p: found magic number\n",
|
DBGC ( image, "COM32 %p: found magic number\n",
|
||||||
image );
|
image );
|
||||||
return 0;
|
return 0;
|
||||||
@@ -206,7 +204,7 @@ static int com32_identify ( struct image *image ) {
|
|||||||
*/
|
*/
|
||||||
static int com32_load_image ( struct image *image ) {
|
static int com32_load_image ( struct image *image ) {
|
||||||
size_t filesz, memsz;
|
size_t filesz, memsz;
|
||||||
userptr_t buffer;
|
void *buffer;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
filesz = image->len;
|
filesz = image->len;
|
||||||
@@ -230,20 +228,18 @@ static int com32_load_image ( struct image *image ) {
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int com32_prepare_bounce_buffer ( struct image * image ) {
|
static int com32_prepare_bounce_buffer ( struct image * image ) {
|
||||||
unsigned int seg;
|
void *seg;
|
||||||
userptr_t seg_userptr;
|
|
||||||
size_t filesz, memsz;
|
size_t filesz, memsz;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
seg = COM32_BOUNCE_SEG;
|
seg = real_to_virt ( COM32_BOUNCE_SEG, 0 );
|
||||||
seg_userptr = real_to_virt ( seg, 0 );
|
|
||||||
|
|
||||||
/* Ensure the entire 64k segment is free */
|
/* Ensure the entire 64k segment is free */
|
||||||
memsz = 0xFFFF;
|
memsz = 0xFFFF;
|
||||||
filesz = 0;
|
filesz = 0;
|
||||||
|
|
||||||
/* Prepare, verify, and load the real-mode segment */
|
/* Prepare, verify, and load the real-mode segment */
|
||||||
if ( ( rc = prep_segment ( seg_userptr, filesz, memsz ) ) != 0 ) {
|
if ( ( rc = prep_segment ( seg, filesz, memsz ) ) != 0 ) {
|
||||||
DBGC ( image, "COM32 %p: could not prepare bounce buffer segment: %s\n",
|
DBGC ( image, "COM32 %p: could not prepare bounce buffer segment: %s\n",
|
||||||
image, strerror ( rc ) );
|
image, strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
|||||||
#include <realmode.h>
|
#include <realmode.h>
|
||||||
#include <basemem.h>
|
#include <basemem.h>
|
||||||
#include <comboot.h>
|
#include <comboot.h>
|
||||||
#include <ipxe/uaccess.h>
|
|
||||||
#include <ipxe/image.h>
|
#include <ipxe/image.h>
|
||||||
#include <ipxe/segment.h>
|
#include <ipxe/segment.h>
|
||||||
#include <ipxe/init.h>
|
#include <ipxe/init.h>
|
||||||
@@ -67,62 +66,53 @@ struct comboot_psp {
|
|||||||
*
|
*
|
||||||
* @v image COMBOOT image
|
* @v image COMBOOT image
|
||||||
*/
|
*/
|
||||||
static void comboot_copy_cmdline ( struct image * image, userptr_t seg_userptr ) {
|
static void comboot_copy_cmdline ( struct image * image, void *seg ) {
|
||||||
const char *cmdline = ( image->cmdline ? image->cmdline : "" );
|
const char *cmdline = ( image->cmdline ? image->cmdline : "" );
|
||||||
int cmdline_len = strlen ( cmdline );
|
int cmdline_len = strlen ( cmdline );
|
||||||
|
uint8_t *psp_cmdline;
|
||||||
|
|
||||||
|
/* Limit length of command line */
|
||||||
if( cmdline_len > COMBOOT_MAX_CMDLINE_LEN )
|
if( cmdline_len > COMBOOT_MAX_CMDLINE_LEN )
|
||||||
cmdline_len = COMBOOT_MAX_CMDLINE_LEN;
|
cmdline_len = COMBOOT_MAX_CMDLINE_LEN;
|
||||||
uint8_t len_byte = cmdline_len;
|
|
||||||
char spc = ' ', cr = '\r';
|
|
||||||
|
|
||||||
/* Copy length to byte before command line */
|
/* Copy length to byte before command line */
|
||||||
copy_to_user ( seg_userptr, COMBOOT_PSP_CMDLINE_OFFSET - 1,
|
psp_cmdline = ( seg + COMBOOT_PSP_CMDLINE_OFFSET );
|
||||||
&len_byte, 1 );
|
psp_cmdline[-1] = cmdline_len;
|
||||||
|
|
||||||
/* Command line starts with space */
|
/* Command line starts with space */
|
||||||
copy_to_user ( seg_userptr,
|
psp_cmdline[0] = ' ';
|
||||||
COMBOOT_PSP_CMDLINE_OFFSET,
|
|
||||||
&spc, 1 );
|
|
||||||
|
|
||||||
/* Copy command line */
|
/* Copy command line */
|
||||||
copy_to_user ( seg_userptr,
|
memcpy ( &psp_cmdline[1], cmdline, cmdline_len );
|
||||||
COMBOOT_PSP_CMDLINE_OFFSET + 1,
|
|
||||||
cmdline, cmdline_len );
|
|
||||||
|
|
||||||
/* Command line ends with CR */
|
/* Command line ends with CR */
|
||||||
copy_to_user ( seg_userptr,
|
psp_cmdline[ 1 + cmdline_len ] = '\r';
|
||||||
COMBOOT_PSP_CMDLINE_OFFSET + cmdline_len + 1,
|
|
||||||
&cr, 1 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize PSP
|
* Initialize PSP
|
||||||
*
|
*
|
||||||
* @v image COMBOOT image
|
* @v image COMBOOT image
|
||||||
* @v seg_userptr segment to initialize
|
* @v seg segment to initialize
|
||||||
*/
|
*/
|
||||||
static void comboot_init_psp ( struct image * image, userptr_t seg_userptr ) {
|
static void comboot_init_psp ( struct image * image, void *seg ) {
|
||||||
struct comboot_psp psp;
|
struct comboot_psp *psp;
|
||||||
|
|
||||||
/* Fill PSP */
|
/* Fill PSP */
|
||||||
|
psp = seg;
|
||||||
|
|
||||||
/* INT 20h instruction, byte order reversed */
|
/* INT 20h instruction, byte order reversed */
|
||||||
psp.int20 = 0x20CD;
|
psp->int20 = 0x20CD;
|
||||||
|
|
||||||
/* get_fbms() returns BIOS free base memory counter, which is in
|
/* get_fbms() returns BIOS free base memory counter, which is in
|
||||||
* kilobytes; x * 1024 / 16 == x * 64 == x << 6 */
|
* kilobytes; x * 1024 / 16 == x * 64 == x << 6 */
|
||||||
psp.first_non_free_para = get_fbms() << 6;
|
psp->first_non_free_para = get_fbms() << 6;
|
||||||
|
|
||||||
DBGC ( image, "COMBOOT %p: first non-free paragraph = 0x%x\n",
|
DBGC ( image, "COMBOOT %p: first non-free paragraph = 0x%x\n",
|
||||||
image, psp.first_non_free_para );
|
image, psp->first_non_free_para );
|
||||||
|
|
||||||
/* Copy the PSP to offset 0 of segment.
|
|
||||||
* The rest of the PSP was already zeroed by
|
|
||||||
* comboot_prepare_segment. */
|
|
||||||
copy_to_user ( seg_userptr, 0, &psp, sizeof( psp ) );
|
|
||||||
|
|
||||||
/* Copy the command line to the PSP */
|
/* Copy the command line to the PSP */
|
||||||
comboot_copy_cmdline ( image, seg_userptr );
|
comboot_copy_cmdline ( image, seg );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,7 +122,7 @@ static void comboot_init_psp ( struct image * image, userptr_t seg_userptr ) {
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int comboot_exec_loop ( struct image *image ) {
|
static int comboot_exec_loop ( struct image *image ) {
|
||||||
userptr_t seg_userptr = real_to_virt ( COMBOOT_PSP_SEG, 0 );
|
void *seg = real_to_virt ( COMBOOT_PSP_SEG, 0 );
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
state = rmsetjmp ( comboot_return );
|
state = rmsetjmp ( comboot_return );
|
||||||
@@ -141,7 +131,7 @@ static int comboot_exec_loop ( struct image *image ) {
|
|||||||
case 0: /* First time through; invoke COMBOOT program */
|
case 0: /* First time through; invoke COMBOOT program */
|
||||||
|
|
||||||
/* Initialize PSP */
|
/* Initialize PSP */
|
||||||
comboot_init_psp ( image, seg_userptr );
|
comboot_init_psp ( image, seg );
|
||||||
|
|
||||||
/* Hook COMBOOT API interrupts */
|
/* Hook COMBOOT API interrupts */
|
||||||
hook_comboot_interrupts();
|
hook_comboot_interrupts();
|
||||||
@@ -246,12 +236,12 @@ static int comboot_identify ( struct image *image ) {
|
|||||||
*/
|
*/
|
||||||
static int comboot_prepare_segment ( struct image *image )
|
static int comboot_prepare_segment ( struct image *image )
|
||||||
{
|
{
|
||||||
userptr_t seg_userptr;
|
void *seg;
|
||||||
size_t filesz, memsz;
|
size_t filesz, memsz;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Load image in segment */
|
/* Load image in segment */
|
||||||
seg_userptr = real_to_virt ( COMBOOT_PSP_SEG, 0 );
|
seg = real_to_virt ( COMBOOT_PSP_SEG, 0 );
|
||||||
|
|
||||||
/* Allow etra 0x100 bytes before image for PSP */
|
/* Allow etra 0x100 bytes before image for PSP */
|
||||||
filesz = image->len + 0x100;
|
filesz = image->len + 0x100;
|
||||||
@@ -260,17 +250,17 @@ static int comboot_prepare_segment ( struct image *image )
|
|||||||
memsz = 0xFFFF;
|
memsz = 0xFFFF;
|
||||||
|
|
||||||
/* Prepare, verify, and load the real-mode segment */
|
/* Prepare, verify, and load the real-mode segment */
|
||||||
if ( ( rc = prep_segment ( seg_userptr, filesz, memsz ) ) != 0 ) {
|
if ( ( rc = prep_segment ( seg, filesz, memsz ) ) != 0 ) {
|
||||||
DBGC ( image, "COMBOOT %p: could not prepare segment: %s\n",
|
DBGC ( image, "COMBOOT %p: could not prepare segment: %s\n",
|
||||||
image, strerror ( rc ) );
|
image, strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zero PSP */
|
/* Zero PSP */
|
||||||
memset ( seg_userptr, 0, 0x100 );
|
memset ( seg, 0, 0x100 );
|
||||||
|
|
||||||
/* Copy image to segment:0100 */
|
/* Copy image to segment:0100 */
|
||||||
memcpy ( ( seg_userptr + 0x100 ), image->data, image->len );
|
memcpy ( ( seg + 0x100 ), image->data, image->len );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user