From e51b6fe8ad1cd2c8dcb7db50e56910ea23899e6c Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 22 Jul 2023 16:54:36 +0200 Subject: correctly setting video modes (also with a local rdev copy from util-linux) --- README | 9 +- configs/linux-config | 8 +- patches/uflbbl-boot-options.patch | 4 +- scripts/build.sh | 2 + scripts/run_qemu.sh | 1 + scripts/run_qemu_direct.sh | 2 +- tools/rdev.c | 273 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 292 insertions(+), 7 deletions(-) create mode 100644 tools/rdev.c diff --git a/README b/README index 8fb52b8..4f8e6ad 100644 --- a/README +++ b/README @@ -31,6 +31,7 @@ local/ local adaptions and configurations which go into the ramdisk ramdisk/ the ramdisk being later compressed to ramdisk.img root/ the root filesystem later being used via NBD or directly as image tests/ test programs to test sanity of stages +tools/ various tools needed on the host to build the distro patches ------- @@ -260,6 +261,7 @@ tinyx/framebuffer: TODO: CONFIG_FB_VGA16=m => for lowest VGA mode => never got that one working + => not sure if that one is needed when choosing VGA in framebuffer TODO: looks optional for a simple running system - CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y @@ -278,7 +280,12 @@ TODO: looks optional for a simple running system - CONFIG_INPUT_EVDEV=m => /dev/input/eventX -TODO: CONFIG_SYSFB_SIMPLEFB=y +- CONFIG_SYSFB_SIMPLEFB=y + => so we get output after the vga= mode is set, so the output + continues on the VGA text console + +TODO: CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +TODO: FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y TODO FROM HERE: diff --git a/configs/linux-config b/configs/linux-config index 6bea05b..b281529 100644 --- a/configs/linux-config +++ b/configs/linux-config @@ -1574,7 +1574,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_ARC is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set -# CONFIG_FB_VGA16 is not set +CONFIG_FB_VGA16=y CONFIG_FB_VESA=y # CONFIG_FB_N411 is not set # CONFIG_FB_HGA is not set @@ -1605,7 +1605,7 @@ CONFIG_FB_VESA=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set -# CONFIG_FB_SIMPLE is not set +CONFIG_FB_SIMPLE=y # CONFIG_FB_SM712 is not set # end of Frame buffer Devices @@ -1616,6 +1616,8 @@ CONFIG_FB_VESA=y # CONFIG_BACKLIGHT_CLASS_DEVICE is not set # end of Backlight & LCD device support +CONFIG_VGASTATE=y + # # Console display driver support # @@ -1626,7 +1628,7 @@ CONFIG_DUMMY_CONSOLE_COLUMNS=80 CONFIG_DUMMY_CONSOLE_ROWS=25 CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set # CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set # end of Console display driver support diff --git a/patches/uflbbl-boot-options.patch b/patches/uflbbl-boot-options.patch index 91bb58b..ec4f51d 100644 --- a/patches/uflbbl-boot-options.patch +++ b/patches/uflbbl-boot-options.patch @@ -1,6 +1,6 @@ diff -rauN uflbbl/src/boot.asm uflbbl-boot-options/src/boot.asm --- uflbbl/src/boot.asm 2023-07-13 08:47:23.000000000 +0200 -+++ uflbbl-boot-options/src/boot.asm 2023-07-15 16:30:46.609197671 +0200 ++++ uflbbl-boot-options/src/boot.asm 2023-07-22 15:26:45.599157847 +0200 @@ -468,10 +468,10 @@ mov [READ_STATE], byte STATE_READ_INITRD ; qemu initrd start location 7fab000, 133869568 (this is 128MB) too high for us, @@ -20,7 +20,7 @@ diff -rauN uflbbl/src/boot.asm uflbbl-boot-options/src/boot.asm KERNEL_CMD_LINE: - db "debug loglevel=7 earlycon=uart8250,io,0x3f8,9600n8 console=tty0 console=ttyS0,9600n8 rdinit=/bin/sinit root=/dev/ram0 rootfstype=ramfs iommu=off", 0 -+ db "debug loglevel=7 earlyprintk=vga earlycon=uart8250,io,0x3f8,9600n8 console=tty0 console=ttyS0,9600n8 init=/init iommu=off vga=0x311", 0 ++ db "vga=ask debug loglevel=7 earlycon=vga earlycon=uart8250,io,0x3f8,9600n8 console=tty0 console=ttyS0,9600n8 init=/init iommu=off", 0 KERNEL_CMD_SIZE equ $-KERNEL_CMD_LINE diff --git a/scripts/build.sh b/scripts/build.sh index f6b9722..0415bd7 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -582,6 +582,8 @@ fi if [ ! -f "${BASE}/floppy.img" ]; then touch EOF cp "${BASE}/build/stage1/boot/bzImage" . + # old way of setting video mode on boot into real mode (0x317) + tools/rdev -v bzImage 791 tar cvf data.tar -b1 bzImage ramdisk.img EOF cat "${BASE}/build/stage1/boot/boot.img" data.tar > "${BASE}/floppy.img" split -d -b 1474560 floppy.img floppy diff --git a/scripts/run_qemu.sh b/scripts/run_qemu.sh index 06f8338..739d790 100755 --- a/scripts/run_qemu.sh +++ b/scripts/run_qemu.sh @@ -5,5 +5,6 @@ sleep 2 && \ qemu-system-i386 -cpu 486 -m 18M -machine isapc \ -drive "file=floppy00,if=floppy,format=raw" \ -netdev user,id=net0,net=10.0.0.0/24,host=10.0.0.2,dhcpstart=10.0.0.16,hostfwd=tcp::2222-:22 \ + -vga std \ -device ne2k_isa,iobase=0x300,irq=10,netdev=net0 pkill qemu-nbd diff --git a/scripts/run_qemu_direct.sh b/scripts/run_qemu_direct.sh index 974515e..603650e 100755 --- a/scripts/run_qemu_direct.sh +++ b/scripts/run_qemu_direct.sh @@ -4,7 +4,7 @@ qemu-nbd -f raw root.img -x ROOT & sleep 2 && \ qemu-system-i386 -cpu 486 -m 24M -machine isapc \ -kernel bzImage -initrd ramdisk.img \ - -append "debug loglevel=7 earlycon=vga earlycon=uart8250,io,0x3f8,9600n8 console=tty0 console=ttyS0,9600n8 iommu=off init=/init vga=0x311" \ + -append "debug loglevel=7 earlycon=vga earlycon=uart8250,io,0x3f8,9600n8 console=tty0 console=ttyS0,9600n8 iommu=off init=/init vga=0x317" \ -netdev user,id=net0,net=10.0.0.0/24,host=10.0.0.2,dhcpstart=10.0.0.16,hostfwd=tcp::2222-:22 \ -vga std \ -device ne2k_isa,iobase=0x300,irq=10,netdev=net0 diff --git a/tools/rdev.c b/tools/rdev.c new file mode 100644 index 0000000..227239f --- /dev/null +++ b/tools/rdev.c @@ -0,0 +1,273 @@ +/* + + rdev.c - query/set root device. + +------------------------------------------------------------------------- + +Date: Sun, 27 Dec 1992 15:55:31 +0000 +Subject: Re: rdev +From: almesber@nessie.cs.id.ethz.ch (Werner Almesberger) +To: Rik Faith + +There are quite a few versions of rdev: + + - the original rootdev that only printed the current root device, by + Linus. + - rdev that does what rootdev did and that also allows you to change + the root (and swap) device, by me. + - rdev got renamed to setroot and I think even to rootdev on various + distributions. + - Peter MacDonald added video mode and RAM disk setting and included + this version on SLS, called rdev again. I've attached his rdev.c to + this mail. + +------------------------------------------------------------------------- + +Date: 11 Mar 92 21:37:37 GMT +Subject: rdev - query/set root device +From: almesber@nessie.cs.id.ethz.ch (Werner Almesberger) +Organization: Swiss Federal Institute of Technology (ETH), Zurich, CH + +With all that socket, X11, disk driver and FS hacking going on, apparently +nobody has found time to address one of the minor nuisances of life: set- +ting the root FS device is still somewhat cumbersome. I've written a little +utility which can read and set the root device in boot images: + +rdev accepts an optional offset argument, just in case the address should +ever move from 508. If called without arguments, rdev outputs an mtab line +for the current root FS, just like /etc/rootdev does. + +ramsize sets the size of the ramdisk. If size is zero, no ramdisk is used. + +vidmode sets the default video mode at bootup time. -1 uses default video +mode, -2 uses menu. + +------------------------------------------------------------------------- + +Sun Dec 27 10:42:16 1992: Minor usage changes, faith@cs.unc.edu. +Tue Mar 30 09:31:52 1993: rdev -Rn to set root readonly flag, sct@dcs.ed.ac.uk +Wed Jun 22 21:12:29 1994: Applied patches from Dave + (gentzel@nova.enet.dec.com) to prevent dereferencing + the NULL pointer, faith@cs.unc.edu +1999-02-22 Arkadiusz Mi¶kiewicz +- added Native Language Support + +------------------------------------------------------------------------- + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* rdev.c - query/set root device. */ + +static void +usage(void) { + + puts("usage: rdev [ -rv ] [ -o OFFSET ] [ IMAGE [ VALUE [ OFFSET ] ] ]"); + puts(" rdev /dev/fd0 (or rdev /linux, etc.) displays the current ROOT device"); + puts(" rdev /dev/fd0 /dev/hda2 sets ROOT to /dev/hda2"); + puts(" rdev -R /dev/fd0 1 set the ROOTFLAGS (readonly status)"); + puts(" rdev -r /dev/fd0 627 set the RAMDISK size"); + puts(" rdev -v /dev/fd0 1 set the bootup VIDEOMODE"); + puts(" rdev -o N ... use the byte offset N"); + puts(" rootflags ... same as rdev -R"); + puts(" ramsize ... same as rdev -r"); + puts(" vidmode ... same as rdev -v"); + puts("Note: video modes are: -3=Ask, -2=Extended, -1=NormalVga, 1=key1, 2=key2,..."); + puts(" use -R 1 to mount root readonly, -R 0 for read/write."); + exit(-1); +} + + +#define DEFAULT_OFFSET 508 + + +static void +die(char *msg) { + perror(msg); + exit(1); +} + +/* Earlier rdev fails on /dev/ida/c0d0p1 so we allow for + recursion in /dev. -- Paul Clements */ +/* In fact devfs needs deep recursion. */ + +static int +find_dev_recursive(char *dirnamebuf, int number) { + DIR *dp; + struct dirent *dir; + struct stat s; + int dirnamelen = 0; + + if ((dp = opendir(dirnamebuf)) == NULL) + die("opendir"); + dirnamelen = strlen(dirnamebuf); + while ((dir = readdir(dp)) != NULL) { + if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..")) + continue; + if (dirnamelen + 1 + strlen(dir->d_name) > PATH_MAX) + continue; + dirnamebuf[dirnamelen] = '/'; + strcpy(dirnamebuf+dirnamelen+1, dir->d_name); + if (lstat(dirnamebuf, &s) < 0) + continue; + if ((s.st_mode & S_IFMT) == S_IFBLK && s.st_rdev == number) + return 1; + if ((s.st_mode & S_IFMT) == S_IFDIR && + find_dev_recursive(dirnamebuf, number)) + return 1; + } + dirnamebuf[dirnamelen] = 0; + closedir(dp); + return 0; +} + +static char * +find_dev(int number) { + static char name[PATH_MAX+1]; + + if (!number) + return "Boot device"; + strcpy(name, "/dev"); + if (find_dev_recursive(name, number)) + return name; + sprintf(name, "0x%04x", number); + return name; +} + +/* The enum values are significant, things are stored in this order, + see bootsect.S */ +enum { RDEV, VIDMODE, RAMSIZE, __swapdev__, __syssize__, ROOTFLAGS }; +char *cmdnames[6] = { "rdev", "vidmode", "ramsize", "", + "", "rootflags"}; +char *desc[6] = { "Root device", "Video mode", "Ramsize", "", + "", "Root flags"}; +#define shift(n) argv+=n,argc-=n + +int +main(int argc, char **argv) { + int image, offset, dev_nr, i, newoffset=-1; + char *ptr; + unsigned short val, have_val; + struct stat s; + int cmd; + + /* use the command name to figure out what we have to do - ugly */ + cmd = RDEV; + if ((ptr = strrchr(argv[0],'/')) != NULL) + ptr++; + else + ptr = argv[0]; + for (i=0; i<=5; i++) { + if (!strcmp(ptr,cmdnames[i])) { + cmd = i; + break; + } + } + + while (argc > 1) { + if (argv[1][0] != '-') + break; + switch (argv[1][1]) { + case 'R': + cmd = ROOTFLAGS; + shift(1); + break; + case 'r': + cmd = RAMSIZE; + shift(1); + break; + case 'v': + cmd = VIDMODE; + shift(1); + break; + case 'o': + if (argv[1][2]) { + newoffset = atoi(argv[1]+2); + shift(1); + break; + } else if (argc > 2) { + newoffset = atoi(argv[2]); + shift(2); + break; + } + /* Fall through. . . */ + default: + usage(); + } + } + + /* Here the only sensible way of using rdev */ + if (argc == 1) { + if (cmd == RDEV) { + if (stat("/",&s) < 0) die("/"); + printf("%s /\n", find_dev(s.st_dev)); + exit(0); + } + usage(); + } + + if (argc > 4) + usage(); + + /* Ancient garbage.. */ + offset = DEFAULT_OFFSET-cmd*2; + if (newoffset >= 0) + offset = newoffset; + if (argc == 4) + offset = atoi(argv[3]); + + have_val = 0; + + if (argc >= 3) { + if (cmd == RDEV) { + if (isdigit(*argv[2])) { + /* earlier: specify offset */ + /* now: specify major,minor */ + char *p; + unsigned int ma,mi; + if ((p = strchr(argv[2], ',')) == NULL) + die("missing comma"); + ma = atoi(argv[2]); + mi = atoi(p+1); + val = ((ma<<8) | mi); + } else { + char *device = argv[2]; + if (stat(device,&s) < 0) + die(device); + val = s.st_rdev; + } + } else { + val = atoi(argv[2]); + } + have_val = 1; + } + + if (have_val) { + if ((image = open(argv[1],O_WRONLY)) < 0) die(argv[1]); + if (lseek(image,offset,0) < 0) die("lseek"); + if (write(image,(char *)&val,2) != 2) die(argv[1]); + if (close(image) < 0) die("close"); + } else { + if ((image = open(argv[1],O_RDONLY)) < 0) die(argv[1]); + if (lseek(image,offset,0) < 0) die("lseek"); + dev_nr = 0; + if (read(image,(char *)&dev_nr,2) != 2) die(argv[1]); + if (close(image) < 0) die("close"); + fputs(desc[cmd], stdout); + if (cmd == RDEV) + printf(" %s\n", find_dev(dev_nr)); + else + printf(" %d\n", dev_nr); + } + return 0; +} -- cgit v1.2.3-54-g00ecf