From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eduardo Pereira Habkost Subject: Re: AW: [Fwd: Re: EDE - Personal Suggestions and Ideas] Date: Wed, 26 May 2004 14:19:54 -0300 Sender: linux-8086-owner@vger.kernel.org Message-ID: <20040526171954.GB21172@duckman.distro.conectiva> References: <20040526115733.GQ12951@vega.vega.lgb.hu> <200405261517.47059.dg@cowlark.com> <20040526151030.GC15905@vega.vega.lgb.hu> <200405261749.42017.dg@cowlark.com> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="wq9mPyueHGvFACwf" Return-path: Content-Disposition: inline In-Reply-To: <200405261749.42017.dg@cowlark.com> List-Id: To: linux-8086@vger.kernel.org --wq9mPyueHGvFACwf Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, May 26, 2004 at 05:49:42PM +0100, David Given wrote: > On Wednesday 26 May 2004 16:10, G=E1bor L=E9n=E1rt wrote: > > However, > > in my 286OS (which source was destroyed several years ago, when my sist= er > > tries to drink my computer with some cola ...) there was a signaling > > mechanism and the kernel can notify application that it SHOULD reload > > segment IDs and this signal is unblockable one. Sure, still ugly, but at > > least we haven't got reload segment IDs every time ;-) >=20 > The only issue with this is, what happens if it's the code or data segmen= ts=20 > that have changed... you can't execute any user code until the segments h= ave=20 > been updated and you can't update segments without running user code! Erm... shouldn't be this exactly the task of the scheduler? Simply the scheduler should be sure that the segment registers are updated and data is in the right place before switching to user code again. Before returning to the user process, the structure storing the 'context' will be updated before returning to user context. I think I didn't get what is the point. >=20 > [...] > > But you can assume that its > > assembly programmer say: OK, CS (code segment register) points to code > > segment, DS (data segment register) points to data segment *AND* ES (ex= tra > > segment register) points to the ACTUAL user data segment. >=20 > Ha! Great minds think alike, and fools seldom differ... I was going to pr= opose=20 > something like this. Except from C, and only allowing a single extra segm= ent=20 > (so that the user process never concerns itself with the contents of ES).= I=20 > was going to call it the buffer area and allow you to do things like: >=20 > { > resize_buffer(32*1024); /* request 32kB buffer area */ > copy_from_buffer(data, 2*1024, 32); /* copy 32 bytes to data from 2kB > into buffer area */ > } >=20 > However, I didn't mention it because I had vague memories that part of EL= KS'=20 > libc uses ES for some of its loops, and wanted to check on that. >=20 > But yeah, that would work. It might make a suitable compromise between=20 > single-segment code and multi-segment code. >=20 > If you want to use more than one extra segment, however, you end up with= =20 > exactly the same problem as before --- the kernel doesn't know where the= =20 > segment addresses are in the app's address space. Giving the kernel a poi= nter=20 > to where it's stored is really, really ugly. >=20 > Perhaps a better approach would be to have the kernel mediate all this; u= se=20 > syscalls to tell the kernel to allocate out-of-process memory. (Or, actua= lly,=20 > a device driver would be better because then it would all get cleared up= =20 > automatically when the process exits.) >=20 > { > int handle1 =3D allocate_buffer(48*1024); /* request 48kB buffer area */ > int handle2 =3D allocate_buffer(48*1024); /* and another one */ >=20 > use_buffer(handle1); /* tell the kernel to look up what selector > handle1 refers to and set it to ES */ > copy_from_buffer(data, 2*1024, 32); > use_buffer(handle2); > copy_to_buffer(3*1024, data, 32); > } >=20 > You'd get fast copying from a buffer to normal data and vice versa, but n= ot=20 > from one buffer to another buffer (unless you were to implement another= =20 > syscall so the kernel did it). >=20 > Ideally you don't want your user process playing with the segment registe= rs.=20 > Ever. That way lies madness, and horrible bugs when, e.g., the compiler= =20 > decides to cache a selector on the stack without telling you, and the ker= nel=20 > changes the selector without updating the version on the stack... I was thinking on this, too: things will be simpler if we explicitly state that user processes cannot touch the segment registers. The compiler be aware of that, too. But given that we have only one data segment, one code segment, and maybe one ES segment pointing to out of process data, the compiler shouldn't need to touch the segment registers, ever. We could have, instead of a "copy_{to,from}_buffer", a "map_buffer_to_es", that will make sure that the ES register for the process point to the selected buffer (reading your example again, I saw that this is exactly what your use_buffer() is supposed to do), but the way C sees the memory don't make this so simple. Unless the compiler give us some help to easily accessing data in the ES segment. If someday the compiler is supposed to support 'far' pointers, we could use them, but instead of storing the ES value on the pointer, and updating ES before accessing data, store the buffer handle on the pointer and call use_buffer() before using it. Yes, more expensive than simply setting the ES register, but would allow the OS to move the data, if needed. And that would be compatible with 286pmode, too. The difference is that on 286, we would need fewer copy operations, and fewer segment register changing. And if we want to have 286pmode-only, but slightly faster, applications, we can allow them to simply set ES to the returned handle, without a syscall. Obviously the returned handle, in this case, will be a segment identifier that can be directly put on a segment register. -- Eduardo --wq9mPyueHGvFACwf Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFAtNG6caRJ66w1lWgRAm28AKCjUJrvLgyCzfX1sA6hOUk3nsLxOwCginJP tvZuX6g7TOqyEx+JjhZBwPs= =GTkR -----END PGP SIGNATURE----- --wq9mPyueHGvFACwf--