From owner-freebsd-hackers@FreeBSD.ORG Wed Feb 20 21:44:50 2008 Return-Path: Delivered-To: freebsd-hackers@FreeBSD.ORG Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BF66516A404 for ; Wed, 20 Feb 2008 21:44:50 +0000 (UTC) (envelope-from xcllnt@mac.com) Received: from smtpoutm.mac.com (smtpoutm.mac.com [17.148.16.70]) by mx1.freebsd.org (Postfix) with ESMTP id A745213C448 for ; Wed, 20 Feb 2008 21:44:50 +0000 (UTC) (envelope-from xcllnt@mac.com) Received: from mac.com (asmtp001-s [10.150.69.64]) by smtpoutm.mac.com (Xserve/smtpout007/MantshX 4.0) with ESMTP id m1KLiorN023820; Wed, 20 Feb 2008 13:44:50 -0800 (PST) Received: from mini-g4.jnpr.net (natint3.juniper.net [66.129.224.36]) (authenticated bits=0) by mac.com (Xserve/asmtp001/MantshX 4.0) with ESMTP id m1KLihkC010820 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Wed, 20 Feb 2008 13:44:44 -0800 (PST) Message-Id: <1E2E2F4B-5169-42B4-AFFC-259B401F7F60@mac.com> From: Marcel Moolenaar To: Oliver Fromme In-Reply-To: <200802202008.m1KK8ZoJ008043@lurza.secnetix.de> Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v919.2) Date: Wed, 20 Feb 2008 13:44:42 -0800 References: <200802202008.m1KK8ZoJ008043@lurza.secnetix.de> X-Mailer: Apple Mail (2.919.2) Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: /boot/loader graphics support & extensibility X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Feb 2008 21:44:50 -0000 On Feb 20, 2008, at 12:08 PM, Oliver Fromme wrote: > By the way: Will the standard i386 /boot/loader work > on an EFI machine, or does it require a different loader > binary? It needs a different loader. If you want to support EFI the right way, it also needs a different kernel -- one that respects the memory map. But that's a different story :-) > If the former, then there must be some code that probes > whether BIOS or EFI is present, and takes care of using > one or the other. At a quick glance I wasn't able to > find such code. Correct. > One final question: What happens if you try to call a > BIOS interrupt (such as the 0x10 video interrupt) on > an EFI machine? Will it crash? Or is there a > compatibility layer that returns "not supported"? Assume it will crash. The EFI machine may be ia64, which makes "int 10h" especially wrong. On i386/amd64 It's best to assume that there's no BIOS emulation. I don't think BIOS emulation is standard on Macs. I think that's what BootCamp is for and it's optional. >> I haven't looked at the code yet, so I don't know >> which graphics functions we're talking about. > > Here's an excerpt from the .h file (it's not complete): > > void gfx_setcolor(int index, int color); > void gfx_setrgb(int color, int red, int green, int blue); > void gfx_usecolor(int color); > void gfx_pixel(int x, int y); > void gfx_rect(int x, int y, int width, int height); > void gfx_line(int x1, int y1, int x2, int y2); > void gfx_triangle(int x1, int y1, int x2, int y2, int x3, int y3); > void gfx_circle(int x, int y, int diameter); > struct fontinfo *gfx_loadfont(char *filename); > void gfx_text(int *x, int *y, unsigned char *text, int length); > unsigned char *gfx_loadpcx(char *filename); > void gfx_showpcx(unsigned char *pcx, int xstart, int ystart); > >> You may want to keep in mind that EFI basically >> defines a single graphics function: bitblt. If the >> graphics functions are variations of bitblt, then >> yes, it's very reasonable. > > Actually I don't plan to use a bitblit function at all, > because it's not really feasible in standard VGA modes. What do you mean by that? I implemented bitblt for VGA for vtc(4). Take a look at: http://people.freebsd.org/~marcel/vga.diff [patch extracted from the tty branch in Perforce] >>> However, I'm not sure how to go about the initialization >>> of the graphics mode. Currently I have a FICL word >>> called "vmode" that takes an integer parameter from the >>> stack which is the VGA mode number. That is, this line: >>> >>> 18 vmode >>> >>> will switch to VGA mode 0x12 (that's 640 x 480 @ 4bit) >>> by calling the appropriate VGA BIOS function. This is >>> all in the ficl/i386/* subdirectory, so it's compiled >>> only for the i386 boot loader. >>> >>> If someone else writes support for some sparc64 graphics >>> hardware, that code would be located in ficl/sparc64/* >>> so it would be compiled in when building the loader for >>> sparc64. >>> >>> However, on sparc64 there is no such thing as VGA mode >>> 0x12, so the vmode instruction has to have a different >>> interface. I'm not really sure what to do here. >>> >>> One possible approach would be to let "vmode" take >>> three parameters: x resolution, y resoluton, depth. >>> So you could type: >>> >>> 640 480 4 vmode >>> >>> In that case every graphics driver needs to have a table >>> that maps resolution and depth to mode numbers. OK. >>> But what if the desired mode isn't supported at all? >>> For example, the sparc CG6 does not support the above >>> mode at all. Should the vmode instructon fail in such >>> a case? >> >> Why not have the platform set a suitable graphics mode? >> In other words: rather than have the end-user code >> determine a mode, which they can't do reliably, why >> not have the mode be set for the end-user code. > > So you mean that "vmode" wouldn't take any arguments > at all? Correct. > That would be possible. But then there will be other > problems. For example, lets say that the i386 loader > decides to use 640x480 @4bit, and the sparc64 loader > decides that 1152x900 @8bit is "best". > > The Forth code clearly needs a way to query the resolution > and bit depth that was set, so it can chose an appropriate > background image. It might also have to chose a different > font. Yes, that's generally the difficulty with graphics. > So the bottom line is that the Forth code cannot easily > be abstracted from the hardware anyway. Well, it cannot be abstracted from the graphics settings, but it is abstracted from the hardware. > There's also a problem when VESA support is added: It's > not possible to reliable detect what resolutions the > attached monitor supports, so by default we must use > 640x480 anyway, even if VESA support is present and the > hardware can do 1600x1200 or whatever. Using a higher- > resolution mode is a decision that needs to be made by > the admin, not by the loader, so there must be a way > for the Forth code to request a specific resolution. This does not have to be done in Forth. If in Forth you simply say "Switch to graphics" and the platform code looks up an environment variable for the actual mode, then the user is still control of the resolution. In fact, this is much more user friendly than having the user edit Forth code, which he/she may not... >> It seems to me that there are 2 ways of thinking about >> consoles. One is the traditional way of not assuming >> too much and just use the console in a serial fashion >> so that it works with dump terminals as well. The other >> is the graphical way of thinking which removes any and >> all levels of abstraction (other than using BIOS mode >> numbers????) and demands that the user can set every >> little bit that can be set. > > There will be users who want exactly that, i.e. be able > to set every little bit that can be set. I already got > such requests in private mail. While I understand the request, it should not be forgotten that it's easy to end up with nothing if you allow the user control over everything. On top of that, we can't use any code in the loader from the kernel, so whatever support we add, we need to add to the kernel too. At least, I think it's lame to support fancy graphics in the loader and then not support at least the same in the kernel. If you raise the bar for the loader, you also have to raise it for the kernel. How else would the kernel be able to use the console? So, the question is: how important is it for the user to be able to tweak it all. Is it merely people going nuts over it (like a toddler going nuts over candy) than we should simply forget about it (and tell the user to grow up :-). If there's an actual reason for it (say: to support HD TVs) then it's something that we could keep in mind if we think it's the future (I have my Mac Mini hooked up to my TV, so it's real for me). > Of course, it would be pretty easy to implement both. > So you have one function that simply set the mode that > the driver thinks is best (that would be a 640x480 mode > in the i386 case). And a second function that takes > resolution and depth as parameters, in order to switch > to a specific mode. There could be a special depth > value (0 or -1) indicating "I don't care, just give > me whatever you can at this resolution". Yes. If common code doesn't care about the setting, then it's easy enough to allow the user to pick the setting of choice... >> There's an in-between. The loader exists only to load >> a kernel. We want it to look nice, but there's no >> reason to tweak resolutions so that you can see the >> kernel being loader in HD. The platform, which >> includes the firmware, knows best which resolutions >> look good. > > I bet there will be people who disagree with the firmware > about which resolution looks good. True. But in that case you want to change the setting in the firmware, not in the loader. If you want to depend on the firmware/BIOS for mode setting then you also have to depend on the Firmware/BIOS to allow the user to select a setting of choice. Here too the loader then pretty much as to work with whatever it gets thrown at it. >> This could very well be a non-VGA mode. >> The best thing we can do is work with what is given >> to us by the firmware or the platform. Then it will >> look nice and it will work in cases we don't know >> how to set the mode, but we know it's graphical. > > I agree that the Forth code should not need to know how to > set a mode. I will change the current interface in my code > so it doesn't use VGA mode numbers. > > My goal is that the Forth code should not have to care > about the graphics hardware at all, as long as the > underlying driver supports a resolution that the Forth > code is prepared to deal with. Agreed. Even if that's standard VGA for now... > It's not feasible to define a hardware-specific setpixel > function and let all other functions use it. That would > make all functions slower. A _lot_ slower. Orders of > magnitude slower. In VGA planar modes, you have to > select each of the four bitplanes, one after another > (using inb + mask + outb to the ISA registers), in order > to set a single pixel. Doing that for every single pixel > in a character string or PCX image would be prohibitively > inefficient. These functions need to deal with the bits > directly, and only switch planes if necessary. That's why there's bitblt. See the URL above... -- Marcel Moolenaar xcllnt@mac.com