[lwip-users] Port to 8086 Architecture.

12 views
Skip to first unread message

Robert Morse

unread,
Feb 15, 2007, 2:46:13 PM2/15/07
to Mailing list for lwIP users
Hi,
I am new to the LWIP, and trying to get things going on a Turbo186
processor.
(i.e. a 8086 processor with a larger memory space.) I have a new
driver going for
the AM79C760 ethernet chip, and that looks ok. On a network with just
a computer and
the UUT, I can ping all day and no problems. Now, connect to a network
with a lot
of traffic and the unit crashes. It looks like it is random, and looks
like memory
corruption problems.

I am getting a lot of :

pbuf_header: failed as 024e000e < 024d0100 (not enough space for new
header size)
(the actual address would be 0024e0e and 0024e00, which would be false
for the above
test.)

Then I see where the IP header:... starts to give bad src/dst and other
errors, then
the system crashes and reboots.

I guess my question after all this, has anyone ported lwip to a 8086
processor.

Robert

_______________________________________________
lwip-users mailing list
lwip-...@nongnu.org
http://lists.nongnu.org/mailman/listinfo/lwip-users

Taranowski, Thomas (SWCOE)

unread,
Feb 15, 2007, 4:48:35 PM2/15/07
to Mailing list for lwIP users
What version of the stack are you using?

Robert Morse

unread,
Feb 16, 2007, 7:29:54 AM2/16/07
to Mailing list for lwIP users
I am using version 1.2 of the stack from the tar ball that was released.

Robert Morse

unread,
Feb 16, 2007, 9:49:35 AM2/16/07
to Mailing list for lwIP users
Thanks for all the help, but I now have it running.

What I had to do was in the one section where the address compare in
the pbuf_header() routine. I had to change the if to call a function
that created a linear address from the segment/offset then compare those
address.

Thanks
Robert

Kieran Mansley

unread,
Feb 16, 2007, 9:55:49 AM2/16/07
to Mailing list for lwIP users
On Fri, 2007-02-16 at 09:49 -0500, Robert Morse wrote:
> Thanks for all the help, but I now have it running.
>
> What I had to do was in the one section where the address compare in
> the pbuf_header() routine. I had to change the if to call a function
> that created a linear address from the segment/offset then compare those
> address.

It's not entirely clear from this what change you made, and whether it
is more widely applicable. Could you supply a diff?

Kieran

Robert Morse

unread,
Feb 16, 2007, 10:57:56 AM2/16/07
to Mailing list for lwIP users

On Feb 16, 2007, at 9:55 AM, Kieran Mansley wrote:

> On Fri, 2007-02-16 at 09:49 -0500, Robert Morse wrote:
>> Thanks for all the help, but I now have it running.
>>
>> What I had to do was in the one section where the address compare in
>> the pbuf_header() routine. I had to change the if to call a function
>> that created a linear address from the segment/offset then compare
>> those
>> address.
>
> It's not entirely clear from this what change you made, and whether it
> is more widely applicable. Could you supply a diff?
>
> Kieran
>

Ok,

In the pbuf.c module, here is the diff that I used:

482c482
< if ((u8_t *)p->payload < (u8_t *)p + sizeof(struct pbuf)) {
---
> if (MAKELINADDRESS((u8_t *)p->payload) < MAKELINADDRESS( (u8_t
*)p + sizeof(struct pbuf)) ) {

Then in my sys_arch.c, i created the following function.

u32_t makelinAddress( void *a)
{
u32_t a_linAddr;
u32_t a_o = (u32_t)FP_OFF(a);
u32_t a_s = (u32_t)FP_SEG(a);

a_linAddr = (a_s << 8) + a_o;
return( a_linAddr);
}

Then in my cc.h, I did a define of
#define MAKELINADDRESS(x) makelinAddress(x)

For system that already have a linear address, they could define the
following in cc.h
#define MAKELINADDRESS(x) x

Now, I am not sure this is the only place where something like this
might need to be done,
as all the pointer manipulations that is done, there might be some more
offset wraps that
might happen depending on where the data areas are placed. I have not
yet looked at
replacing all pointers with 'far pointers'.

Setup.

Runing a Turbo86 processor, which looks like a 8086 but has 256 byte
pages instead of
16 byte pages of a 8086. This allows 16Meg memory space instead of the
8086 1Meg memory
space. I have to run in Large model as I do not have source to our
kernel, and that is
only compiled in Large model.

Robert

David Empson

unread,
Feb 18, 2007, 5:37:35 PM2/18/07
to Mailing list for lwIP users
On Saturday, February 17, 2007 3:55 AM, "Kieran Mansley" <kie...@recoil.org>
wrote:

> On Fri, 2007-02-16 at 09:49 -0500, Robert Morse wrote:
>> What I had to do was in the one section where the address compare in
>> the pbuf_header() routine. I had to change the if to call a function
>> that created a linear address from the segment/offset then compare those
>> address.
>
> It's not entirely clear from this what change you made, and whether it
> is more widely applicable. Could you supply a diff?

The 8086 and 80186 address memory using a 16-bit segment and 16-bit offset.
(This also applies to "real mode" in later 80x86 processors.) The segment is
multiplied by 16 to determine the physical memory address of a particular
"paragraph", then the offset is added. A segment by itself can be used as
the base address of a 64 KB memory area, but any address which is a multiple
of 16 within that area can be the start of a new segment, so segments can
overlap, and multiple combinations of segment and offset can refer to the
same memory location.

This means it is difficult to compare 32-bit pointers unless they are first
"normalised", by shifting and adding the segment and offset to form a 20-bit
linear address. If the normalised pointer needs to be used as a memory
address again, it is split back into a 4-bit segment and 16-bit offset
(X000:XXXX), or 16-bit segment and 4-bit offset (XXXX:000X).

Some x86 compilers have a memory model where this is done automatically (it
was called the "huge" model in Borland C++ back when I last used it). As
long as specific comparisons can be isolated and coded correctly, it is
more efficient to use the "large" model, which doesn't automatically
normalise pointers but still allows more than 64 KB to be addressed as long
as any single data structure doesn't exceed 64 KB.

Any code to deal with normalising pointers in LWIP would have to be
conditional on an 80x86 processor so I doubt it would be useful for other
processor families.

Kieran Mansley

unread,
Feb 19, 2007, 3:41:30 AM2/19/07
to Mailing list for lwIP users
On Mon, 2007-02-19 at 11:37 +1300, David Empson wrote:
> On Saturday, February 17, 2007 3:55 AM, "Kieran Mansley" <kie...@recoil.org>
> wrote:
> > On Fri, 2007-02-16 at 09:49 -0500, Robert Morse wrote:
> >> What I had to do was in the one section where the address compare in
> >> the pbuf_header() routine. I had to change the if to call a function
> >> that created a linear address from the segment/offset then compare those
> >> address.
> >
> > It's not entirely clear from this what change you made, and whether it
> > is more widely applicable. Could you supply a diff?
>
> The 8086 and 80186 address memory using a 16-bit segment and 16-bit offset.
> (This also applies to "real mode" in later 80x86 processors.) The segment is
> multiplied by 16 to determine the physical memory address of a particular
> "paragraph", then the offset is added. A segment by itself can be used as
> the base address of a 64 KB memory area, but any address which is a multiple
> of 16 within that area can be the start of a new segment, so segments can
> overlap, and multiple combinations of segment and offset can refer to the
> same memory location.

Thanks for the background and explanation - very helpful in
understanding the change.

Kieran

Reply all
Reply to author
Forward
0 new messages