[syslinux] [Syslinux-GSoC] Exporting real-mode functions
H. Peter Anvin
hpa at zytor.com
Tue Jun 2 07:38:16 PDT 2009
liu Aleaxander wrote:
>
> well, I have to say it alos does not work.
>
I looked at your code, and the problem is that you're not using the
bounce buffer.
void getoneblk(char *buf, __u32 block, int block_size)
{
int sec_per_block = block_size / 512; /* 512==sector size */
com32sys_t regs;
regs.eax.l = block * sec_per_block;
regs.ebp.l = sec_per_block;
regs.es = SEG(buf);
regs.ebx.w[0] = OFFS(buf);
call16(getlinsec, ®s, NULL);
}
Here, "buf" will generally be > 1 MB, so applying SEG() and OFFS() to it
results in garbage.
Instead, you need to do something like:
void getoneblk(char *buf, __u32 block, int block_size)
{
int sec_per_block = block_size / 512; /* 512==sector size */
com32sys_t regs;
/* We need to clear at least the segment registers... */
memset(®s, 0, sizeof regs);
regs.eax.l = block * sec_per_block;
regs.ebp.l = sec_per_block;
regs.es = SEG(core_xfer_buf);
regs.ebx.w[0] = OFFS(core_xfer_buf); /* Or just zero */
call16(getlinsec, ®s, NULL);
memcpy(buf, core_xfer_buf, block_size);
}
Similarly, returning the pointer in gs:si doesn't work, since it's above
the 1 MB boundary. We probably can't use core_xfer_buf to return the
block, though, so doing what you want to do here is nontrival -- the
easiest way to do this is to export the existing 16-bit cache_seg in the
same way we have xfer_buf_seg -> core_xfer_buf; that can then replace
cache_data[] until we have moved all the cache-using code to 32-bit
mode. I just checked in such an export.
A few technical notes:
I believe the existing code will call getcachesec with a zero block
number; it expects to get back a cache pointer for a zeroed block.
A few stylistic notes:
- Please use shifts instead of multiplications and divisions. This
often means keeping sizes as power of two rather than direct numbers
(i.e. block_size probably should be "12" instead of "4096").
- I'd prefer if we used <inttypes.h> types, i.e. uint32_t rather than __u32.
- Don't put prototypes inside functions. However, if you are allocating
a static buffer which will only be used inside one function, *do* put it
inside the function.
-hpa
--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.
More information about the Syslinux
mailing list