|
Development Blog
The new boot manager is written from scratch. Planed features are
- Full USB 1.1/2.0/3.0 support (thumbs, hard disks, floppys, optical drives, keyboards, hubs, maybe mouse)
- PC-Card (PCMCIA) flash disk support
- PCI Express support
- VHD support
- (U)EFI support
- GPT support
- Simple text mode, enhanced text mode, gfx mode
- Support various file systems (FAT12/16/32, Ext2/3/4, limited NTFS, limited HFS+)
- Native Linux Kernel boot
- Native AHCI support
- Modular
- Simple shell
Donations are rare and welcome: Donate
2023-02-14 - PBM6 - EFI
See installation example in the video Install Plop Linux - Desktop - UEFI.
2023-02-06 - PBM6 - EFI
Minor fix: Hide message "Found ...." when booting in hidden mode.
2023-01-25 - GNU-EFI patch - UEFI functions with 11 parameters
gnu-efi 3.0.15 supports UEFI functions with at maximum ten parameters.
This is my patch for gnu-efi 3.0.15 to extend the support for UEFI functions that have eleven parameters.
I came over the problem when I added the USB gamepad support to PBM6-EFI last year. The
EFI_USB2_HC_PROTOCOL - USB Control
Transfer function has eleven parameters.
Sidenote: The EFI_USB2_HC_PROTOCOL works, but finally I used the EFI_USB_IO_PORTOCOL for the gamepad support.
Download: gnu-efi-3.0.15.patch

2023-01-25 - PBM6 - EFI: Some fixes
- QEMU: Text Output Protocol (top error) fixed. PBM6-EFI works now fine with QEMU EFI boot using TianoCore OVMF.fd
- User Interface: Active sub window is dark. Fixed.
- Config file: Config file not found when booting from CD/DVD. Fixed.
Download: pbm6-efi-20230125.zip
QEMU EFI: Download OVMF.fd from GitHub
(Clear Linux* Project Page).
Start command example: qemu -enable-kvm -smp 4 -m 4096 -bios OVMF.fd -cdrom pbm6-efi.iso
2022-11-18 - PBM6 - BIOS/Legacy: Bug fixes
The IRQ/INT handling for real mode <-> protected mode has been rewritten. This should solve a lot of issues.
Download: pbm6-test-20221118.zip,
pbm6-test-20221118-serial.zip
2022-11-04 - PBM6 - BIOS/Legacy: Native PXE boot, bug fixes
This release includes a new file called pbm6.pxe. Use it for native boot from network with PXE. Valdo H. asked for that feature.
Requirements and instructions: See pxe/README.txt
This release has some bug fixes but other fixes are still missing. A better version comes soon.
A lot of documentation is still missing.
Download: pbm6-test-20221104.zip,
pbm6-test-20221104-serial.zip
2022-11-04 - PBM6 - EFI: ISO fix
The ISO did not work under VMware. It is fixed now.
Download: pbm6-efi-20221104.zip
2022-10-25 - PBM6 - EFI: Xbox 360 Controller & PlayStation 3 Dualshock Controller
I received the request to add support for the SteamDeck to navigate through the menu with the SteamDeck controls. As
I have no SteamDeck, the development is a bit more complicated. But SteamDeck support will come. Meanwhile, today I
added two simple drivers to navigate with the Microsoft Xbox 360 Controller and the Sony PlayStation 3 Dualshock Controller through
the menu.
Mapping:
Left Stick, D-Pad: Up, down, left, right
Xbox 360 Controller buttons: A = Enter, B = Back, Y = Tab
PS3 Dualshock Controller buttons: X = Enter, Circle = Back, Triangle = Tab
Supported Vendor/Product IDs:
045e:028e - Xbox 360 Controller
054c:0268 - PS3 Dualshock Controller
Download: pbm6-efi-20221025.zip

2022-07-04 - Error - value too large for defined data type
During bug fixing of the serial console support I stumbled over a strange bug when booting Linux. I used two old laptops, connected with a serial cable.
To be sure that the serial ports are working fine, I booted Plop Linux 22.2 for i486. The laptops have 32 bit processors. Suddenly, booting stopped and I got the error "value too large for defined data type". I was surprised, because
booting Plop Linux worked always fine on those machines. So I tried older versions of Plop Linux and finally the version 19.4 booted fine. I figured out that newer glibc
versions causing the error. Plop Linux 19.4 is using glibc 2.30, later glibc 2.33 and 2.35 was used.
Another reason for the error is the hardware clock of the laptops. As they are very old and the CMOS battery is empty, they have a default date for example with the year 1998. A correct date does not matter for the serial test, so
I booted with the BIOS default values, which failed with the newer glibc (but worked with glibc 2.30). When I set the current date in the BIOS,
then booting worked fine with the newer glibc. I played around and saw that a year before 2000 is problematic.
In short, to avoid the glibc error 'value too large for defined data type' on old machines (32 bit) set a date with the year 2000 or later and recent glibc will work fine.
2022-07-03 - PBM6 - BIOS/Legacy: Serial Console Fix
Fixed serial console support. For testing the configuration is hard coded to COM1, 115200 baud, 8 bits, no parity, one stop bit.
Details coming tomorrow.
Download: pbm6-test-20220719-serial.zip -
Use this special version only when you want to try/use the serial console support!
2022-06-11 - PBM6 - BIOS/Legacy: Serial Console Support
Serial console support has been added. For testing the configuration is hard coded to COM1, 9600 baud, 8 bits, no parity, one stop bit. This will be configurable later.
VT100 codes are used for the interface.
When the serial console feature is used, then the boot manager automatically switches to the screen resolution text mode 80x25.
Download: Removed because of bugs
See the demonstration video. Note, keyboard input from serial console & remote computer.
External content blocked. Watch on YouTube
2022-05-29 - PBM6 - BIOS/Legacy bug fix release
exFAT fix
File Commander VHD/VHDX fix
Source Code: LocalClear macro disabled and replaced clearing the variables manually. This fixes also USB problems.
2022-05-06 - PBM6 - BIOS/Legacy: Temporary release notes
Windows boot from VHD works with this release. Instructions to create a Windows VHD coming soon. Basically just install Microsoft Windows as usual in Hyper-V or VirtualBox to a VHD disk and add a custom VHD boot entry.
Boot from VHDX should work too, but is untested at the moment. (Have no time)
This release has some boot fixes.
External content blocked. Watch on YouTube
2022-04-06 - PBM6 - BIOS/Legacy: Temporary release notes
Just an overview. Details coming soon....
Minor USB driver fixes.
Simple file commander added.
File system support added, read only: FAT12/16/32, extFAT, ext2/3, NTFS
Hex viewer / Text file viewer
VHD, VHDX support added.
Partial config file support added.
Kernel command line support added.
Various fixes, still buggy.
External content blocked. Watch on YouTube
2021-09-09 - PBM6 - BIOS/Legacy: USB 3 fixes
USB 3.0 driver updated.
2021-07-23 - PBM6 - EFI
Bugfix release + new setup options.
2021-06-16 - PBM6 - EFI
Initial test release of PBM6-EFI. Written in C using GNU-EFI.
2021-01-25 - Directories
I renamed the directories in the pbm6-test-20210119.zip.
The "native" directory is now the first one. That version
is using my drivers from start.
The BIOS version freezes on keypress on some computers.
2021-01-19 - USB 3 fixes, ACPI
Updated: USB 3.0 driver, USB HUB driver.
Added: ACPI driver, APIC / IO APIC driver (but currently disabled).
There was a break for many months, because I am working on other projects. The most interesting is the work with the Unreal Game Engine. Here are some screenshots, see more here.

A few weeks ago I started to fix the USB 3 problem.
I fixed the USB 3 initialization bug that I had with the ASMedia Technology Inc. ASM1142 chipset. One big problem was that the host did not fire an IRQ. I had no clue why.
I thought, maybe it works only with the APIC, but I didn't really believed that. Anyway I implemented ACPI which is the base requirement for APIC and then I added the support for
Local APIC and IO APIC. That worked fine, but the USB 3 host still did not fire an IRQ. So the bug search continued. Finally, the problem was that I initialized the ERSTBA register before the ERSTSZ register.
For easy handling of the specification documents, I always write the page number of the PDF to the comments. So I can find the related sections quickly. By luck I saw that the ERSTSZ init is one page before
the ERSTBA page. So I moved the ERSTSZ part up and the chip started to work. However, it wasn't easy to find that. It took days.
Here is the related code. Not easy to fix when you have no idea whats wrong.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
; Runtime Registers: Setup Interrupt Register Set. 5.5.2 page 424. ; Program the Interrupter Event Ring Segment Table ; Size (ERSTSZ) register (5.5.2.3.1) with the number ; of segments described by the Event Ring Segment ; Table. Page 427. ; Address: Runtime Base + 028h + (32 * Interrupter) ; where: Interrupter is 0, 1, 2, 3, ... 1023 ; See page 180 and 181. mov eax, [.runtime_base] add eax, 28h + 32 * 0 ; Address of Interrupter 0. mov dword [fs:eax], 1 ; Only one entry in the Event Ring Segment Table (ERST) mov edx, [fs:eax] ; Dummy read
; Program the Interrupter Event Ring Segment Table ; Base Address (ERSTBA) register (5.5.2.3.2) with a ; 64-bit address pointer to where the Event Ring ; Segment Table is located. ; Page 428. ; Note that writing the ERSTBA enables the Event ; Ring. Refer to section 4.9.4 for more information ; on the Event Ring registers and their initialization. mov eax, [.runtime_base] add eax, 30h + 32 * 0 ; Address of Interrupter 0. mov ebx, [.event_ring_segment_table] mov dword [fs:eax], ebx mov dword [fs:eax + 4], 0 mov edx, [fs:eax] ; Dummy read mov edx, [fs:eax + 4] ; Dummy read
|
With the working ASMEDIA chipset I was able to remove some other USB 3 bugs and I added USB 3 support to the USB HUB driver. Additionally, I fixed a HUB driver bug. With the ACPI driver, the shutdown function should work now fine.
APIC is disabled, because at first it works fine now with the classic PIC and the second reason is that there would be problems with starting DOS.
2020-04-08 - Minor updates
Fixed:
- No partition has been detected after an USB drive has been removed.
- USB Hub not detecting devices on startup fixed.
Known USB 3 driver issues:
The event ring does not report anything on ASMedia Technology Inc. ASM1142 and NEC Corporation uPD720200 host controllers. I don't know why at the moment.
2020-03-19 - USB 3 xHCI added, some IDE fixes, partition detection fix
USB 3 support added. The xHCI driver is almost complete. Booting USB 3 devices works. I tried some operating systems, all booted fine. Also Windows 10 PE and it booted from USB very fast without problems.
Finally USB 3 is a simple concept and easy to implement.
I like it. The xHCI driver adds only 9.5 KB.
USB 3 Status: USB drives and keyboards are working. But there is a problem with disconnecting and reconnecting a device.
USB HUBs are currently not working. They need a special handling. But HUB support for USB 3 will come.
Release fixes:
USB Mass Storage driver: Endpoint detection fix.
IDE:
Again a device detection fix.
Sector read on big drives fixed.
Partitions: Logical partition detection fix.
Some screenshots


2020-03-07 - USB 3 - xHCI
This week I started with USB 3. Reading the specification document of the USB Controller. The eXtensible Host Controller Interface for
Universal Serial Bus (xHCI). Very interesting and different to USB 1.1 and USB 2.0 controllers. It took some time to put all the information
together in my brain, but finally I understood it (the most I think).
I wrote a test program and SUCCESS - I am able to read data from an USB device. It was not so easy as it sounds, but thats past and doesn't matter now. The basics are done.
Next stage is to clean up the code, create a lot of functions and finally create the USB 3 driver. Thats a lot of work, but I have a good feeling.
Source code screenshot

2020-02-20 - Many bug fixes
I spent a lot of time for bug fixing and I am quite happy with the result. I made also important changes in the internal program structure.
Bug fixes:
Stack:
A wrong parameter size (word/dword) caused a wrong stack. Finding the problematic code line was very difficult. There are many thousand lines of code. The problem was that the effect of this
bug came silently.
I think it was also the reason for a 'General protection fault' error on some machines.
Wikipedia: Stack
USB:
I updated the interrupt handling for all USB drivers.
Some fixes.
IDE:
I fixed the IDE drive detection. On some machines, the drives haven't been detected.
Non standard I/O port configuration is now also supported.
I added the support for a second IDE controller chip, that allows up to 8 IDE drives.
AHCI/SATA:
There was a bad bug. Some controllers had no problem, others did not work correctly. On one of my machines,
booting with SATA resulted in a freeze. The sector read returned valid data at the first look, but
then I saw that it was displaced by one byte. It looked like a transfer buffer alignment problem. Data structures for
USB must be aligned too. So its nothing new. And finally it was really a wrong aligned buffer. For those who stumble
over the same problem. For the Physical Region Descriptor Table (PRDT), the data block (DBA) must be word aligned. See AHCI Specs Page 40.
There was also another problem with the sector read/write routine. Some data haven't been cleared completely during the initialization. The result could be invalid data. It has been fixed.
Keyboard:
The PS/2 keyboard driver has been updated.
The 16 bit and 32 bit Interrupt Service Routine has been rewritten completely. This affects the PS/2 and USB keyboard support. It should work fine now.
16 bit ISRs:
The 16 bit Interrupt Service routine handling at all has been rewritten. It was some work, but it will make things easier in the future.
And the ISRs are working better now.
Memory management:
There was a tiny bug in the initial routine that is responsible for all further memory allocation. Its fixed.
The test version is available for download.
2020-02-12 - Nightly build with fixes released
Official test release with bug fixes comes in a few days.
2020-02-05 - Nightly build with fixes released
Official test release with bug fixes comes in a few days.
2019-12-19 - USB 2.0 fix
A bug for some USB 2.0 controllers has been fixed. I forgot to check bit 0 of the HCCPARAMS register. If the bit is set, you have to use larger data structures (EHCI Specs. Apendix B).
Ignoring that was the reason that memory area has been suddenly overwritten which resulted in an error. Also some minor bugs have been fixed.
Download: See top of this page
2019-11-29 - Many fixes and beeps
This release has a lot of bug fixes. It comes also with the new PC Speaker support, see the post from 2019-11-17 for more information. Sound card support with additional features is planed.
Use CTRL-F5 to enable/disable the PC Speaker support. Pressing F5 will beep the current text as Morse Code.
Download: [removed - outdated]
2019-11-17 - PC Speaker
PBM6 has PC Speaker support for a simple screen reader and notifications. This will help blind and visually impaired people to use the boot manager.
The Morse Code is used for the text.
There is a sound notification when the boot manager is ready to use.
In the main menu, you hear a short information with two chars.
For boot entries, the first char is the drive type and the second char is the bus type. Example: Hard disk IDE is HI. CD-ROM SATA is CS. Hard disk USB is HU.
Static menu entries: Setup is SE. About is AB. Shutdown is SH.
With a hotkey, you hear the whole text of the menu entry.
Attaching and removing an USB drive gives a notification sound.
The PC Speaker feature will be available in the next Test Version.
Demonstration video:
External content blocked. Watch on YouTube
Download as MP3: pbm6-pcspeaker.mp3
Download as text: pbm6-pcspeaker.txt
2019-11-04 - Boot Manager Name - Test Release - Starting the boot manager - Download
At first I have to say, I have chosen a name for the new boot manager. Some people sent me various names, and I say thank you, but none made me happy.
The new boot manager will be called 'PBM6' (Plop Boot Manager Six). I know, not really extraordinary. You may ask why I searched for a different name. There are different reasons, but mostly to avoid just saying 'plop' to the boot manager.
I am still thinking about an alternative name, but I think 'PBM6' is fine.
Test Release
I think, the time has come to release a test version. The test version is not perfect, so don't expect too much. There is much left to do.
Many features are missing.
Known issues:
- Various orange chars on startup: Just debug stuff. Will be removed later.
- USB3: There is no driver included at the moment. I am working on it. To use a device with the boot manager, you have to connect the device to the USB 2 port. Also in a Virtual Machine.
- UEFI: There is no UEFI support at the moment. Starting the boot manager with UEFI will end in an error.
- There is no MBR installation at the moment. See 'Starting the boot manager' for various ways to start the boot manager.
- There is no configuration file to configure the boot manager.
- You can not configure the boot manager with Linux Command Line Parameters.
- Starting the boot manager from the Windows Boot Menu: Currently is only Windows Vista/7/8/10 supported, because "bcdedit" must be used.
- Floppy drive is not accessible after booting.
- Booting floppy from the boot manager is not supported at the moment. Neither a builtin nor an USB floppy drive.
- Licence: Currently, the boot manager is free personal use. It is not free for commercial use.
What should work:
- IDE: Hard disks, CD/DVD drives.
- SATA: Hard disks, CD/DVD drives.
- USB Controller: USB 1.1 UHCI/OHCI, USB 2.0 EHCI support.
- USB Device support for keyboard, HUB, thumb drives, hard disks, CD/DVD drives.
- USB read/write support.
- USB Hot-Plug.
- Boot drive partition.
- Start drive MBR.
- Boot CD/DVD in no-emulation mode.
- Eject CD/DVD.
- Show drive infos.
- Change screen resolution, also wide screen.
- Start PMB6 from Floppy, CD/DVD drive, network, Linux Boot Managers, Windows Boot Menu (Vista/7/8/10).
Some notes:
Main Menu: When you select a drive with "Enter", then the boot partition of the hard disk or the CD from the drive will be booted.
When you press the right key on a menu item that has the sign ">", then you open a Sub Menu.
Sub Menu hard disk: You can boot the MBR. You can choose a partition to boot. You can view some drive information.
Sub Menu CD/DVD: You can eject the disc. You can view some drive information.
Minimum requirements: CPU i386, 46 MB RAM.
Starting the boot manager
- Floppy - A classic way. Write the floppy image to the floppy disk with "dd" or "rawwrite.exe".
- CDROM - A classic way. Burn the ISO to the CDROM/DVD and boot.
- ISO - Use the ISO to start the boot manager in a virtual machine.
- Like a Linux Kernel - As the Plop Boot Manager 5, PBM6
can be started like a Linux Kernel from a Linux Boot Manager like
LILO, GRUB and Syslinux (also from network).
- Windows Boot Menu - Now its possible to start the boot manager directly
from the Windows Boot Menu without workarounds like plpbt4win. You have to use "bcdedit".
Its tested only on (NOT UEFI installed!) Windows 10.
Instructions for Linux Boot Managers
PBM6 can be started like a Linux Kernel by linux loaders.
You can start it over the network with Syslinux in the same ways as Plop Boot Manager 5.
SYSLINUX
You can start PBM6 with the keyword "linux" and "kernel".
Examples:
label pbm6
menu label ^Plop Boot Manager 6
linux plop/pbm6
label plp6
menu label ^Plop Boot Manager 6
kernel plop/pbm6
GRUB2
You can start PBM6 with the keyword "linux" and "linux16".
Examples:
menuentry "Plop Boot Manager 6" {
linux16 /boot/plop/pbm6
}
OR
menuentry "Plop Boot Manager 6" {
linux /boot/plop/pbm6
}
See also https://www.plop.at/en/ploplinux/desktop/grub2.html
Example /etc/grub.d/40_custom
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
insmod ext2
set root='(hd0,1)'
menuentry "Plop Linux" {
linux /boot/bzImage root=/dev/sda1
}
menuentry "Plop Boot Manager 5" {
linux16 /boot/plop/plpbt.bin
}
menuentry "Plop Boot Manager 6" {
linux /boot/plop/pbm6
}
menuentry "PlopKexec" {
linux /boot/plop/plopkexec
}
menuentry "Memtest" {
linux16 /boot/memtest/memtest
}
LILO
Example:
image=/boot/plop/pbm6
label="Plop Boot Manager 6"
Instructions for Windows Vista/7/8/10
UEFI is NOT supported at the moment and will end in an error!
Copy "pbm6nt" to c:\
Add to Windows Boot Menu:
=========================
Open the Command Prompt as "Administrator"
Run the following commands:
bcdedit /create {ntldr} /d "PBM6"
bcdedit /set {ntldr} device boot
bcdedit /set {ntldr} device partition=c:
bcdedit /set {ntldr} path \pbm6nt
bcdedit /displayorder {ntldr} /addlast
Remove the entry:
=================
Warning! Be careful with this command!
bcdedit /delete {ntldr} /f
Download
Download: [removed - outdated]

2019-08-28 - No special news
I had to do other various work over the last weeks, so no real progress. But the NTFS loader looks really good.
Today I fixed a bug in a simple program, that is used for the window development. Its also used as sample program.
Weeks ago, I did a heavy but needed code adjustment. A lot of code had to be modified. Required to put the program data on any RAM location.
I planed to do that earlier, but it it never happened. Meanwhile all works, also the sample program.
Parallel I spend this week to build a fresh Plop Linux release (Xfce 4.14 is here, yes). Not every updated program compiles flawless. I have to do a lot of things to make it flawless.
I have to do more with the new Blender 2.80, which is amazing. So many new things and changes. Although I have 10 years Blender experience, I feel like a beginner. Unfortunately, I have no time.
2019-07-19 - NTFS support
Since yesterday, I am working on a simple NTFS driver.
My goal is to simplify the process of adding the boot manager to the Windows Boot Menu.
Later, the NTFS driver could be used for other tasks too. My driver will not have full write support. Maybe I add some limited write access for
existing files to modify bytes and write to a config file. Support for compressed or encrypted files is not planed.
Over twenty years ago (1998, 1999) I also worked on a program with NTFS read access. A lot of analyzing with a Hexeditor
was required. Bytes, sectors and so on, figure out how the files are stored on the drive.
Nowadays, you find a lot of documentation in the web. This makes the programming much easier. But a Hexeditor is still used, some things will never change.
Today, I was looking at my source code from the past. The program was never finished, but important things worked. I was
wondering how fast the time goes by.
My goal for today was reading directories and files. A lot of important functions are still missing, but directory listing and file reading works. Goal for today reached.
2019-06-27 - Boot CD/DVD "El Torito"
I used four days exclusive to extend the INT 13h functions with "El Torito" functionality. This specification handles booting CD-ROMs.
The Plop Boot Manager supports only IDE drives. The new boot manager supports now
booting CD/DVD on IDE, SATA (AHCI) and USB (UHCI, OHCI, EHCI) without the help of a BIOS. At first, I support only the "No emulation" media type. It is the
standard media type since (maybe 20) years. First tests are looking good and disc reading is fast. I tested successful some Linux Distros and various Microsoft Windows install DVDs.
Next goal is to improve the user interface and some additional hardware tests. A first public test release is coming closer, but still so much left to do.
It seems, the new boot manager name won't be "ehBoot" or "eh-boot". Still searching for a name without "Plop".
2019-06-12 - USB 2.0 HUB and a video
At first, my USB HUB driver works great. The news are not really news. The most happened weeks ago. Lets talk about the USB HUB driver. I was worried about the split transactions, which are required on USB 2.0 HUBs to connect USB 1.1 devices to the USB HUB. But
it was no problem to implement it. So the USB Keyboard (USB 1.1) works also fine when its connected to the USB 2.0 HUB. Although the HUB driver was working properly,
I was not happy with the code. So I rewrote it completely a few weeks ago. It took two days, but I felt better.
I tested USB boot from a thumb drive with various operating systems. All booted fine. The USB Keyboard works as long as the OS did not grab it.
That means, you can use the keyboard with other boot managers and also with DOS when you boot from USB. Remember, thats not possible with the Plop Boot Manager 5.
There was a surprise with ReactOS. It booted very slow. Loading the RamDisk takes ages. That's also stated at the ReactOS Wiki RAM Boot
under "Known issues". It took much time with the BIOS USB and also with my new USB driver. But goes really fast with my old Plop Boot Manager 5. I was confused, because
usually, the new driver is faster than the old driver. Then I remembered, that I added a simple caching system to the boot manager. I did the same again with the new boot manager, and now it
boots also fast. It seems the ReactOS loader reads only one sector after another, instead of many sectors at once, which would be much faster. This could be the reason for the slow
RamDisk loading. Just a speculation. I did not check the code.
I created a not very spectacular video, comparing the USB boot process BIOS vs EH-BOOT.
Note, I am a fan of the ReactOS project. I hope they have enough power to create a stable MS Windows compatible release.
Meanwhile I think, I will call the new boot manager "eh-boot" or "ehboot".
But I don't know how it sounds from a native English speaker.
Checkout the video. At first, you see the setup with the Asus Eee PC, the USB 2.0 HUB which has the USB Keyboard and Thumb drive connected. Then comes the boot process with a timer that measures the USB part and some
time warps when it boots with the BIOS. Recorded by night, because of the lights. Spoiler alarm: BIOS takes 7:22, the new boot manager takes 0:51.
External content blocked. Watch on YouTube
2019-02-22 - Status update - USB Boot, USB Keyboard
I was busy with other work, but there was also some progress on the new boot manager.
Meanwhile, I wrote
the INT 13h handler required to boot native from hard disks without the help of a BIOS. It works native with IDE, SATA and USB hard disk drives.
CDROM and Floppy is left to do for for the INT 13 handler.
SATA is not tested very well.
USB drives bigger than 2 TB are supported, so you can even boot from an 8 TB USB drive. USB read and write is supported. For development purpose, I focused on UHCI. OHCI and EHCI will be added easily when all works fine with UHCI.
Currently, DOS and Linux boot fine. Under DOS I copied successful a lot of files using my USB driver,
but it has to be tested later by others too. USB write support is experimental.
Also, I almost finished the USB Keyboard driver and the INT 16h handler, required to use an USB keyboard under DOS or another
boot manager. It works fine under DOS and also reduces the CPU usage when DOS is idle, because of using the 'hlt' command.
For those who are interested how the driver looks like, find the source code of my USB Keyboard driver below. You have to collapse it :)
The PS/2 keyboard driver has been updated too.
Note: There is still no release date for the new boot manager!
Collapse source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
;================================ ; USB Keyboard driver by Elmar Hanlhofer (C) 2019 ; https://www.plop.at ;================================ ;bool USB_KBD_ClaimDevice (dword device) ;bool USB_KBD_ReportCallback (dword transfer) ;void USB_KBD_SetLeds (dword device, word led_bitmap) ;void USB_KBD_SetLedsCallback (dword transfer) ;void USB_KBD_SyncLedsWithBDA (dword device) ;bool USB_KBD_StatusFlagsHandlePress (word bios_key_code) ;void USB_KBD_HandleReports (dword device, dword current_report, dword previous_report) ;void USB_KBD_BDA_SetModifierFlags (word kbd_flags) ;word USB_KBD_TranslateToBiosCode (word kbd_scan_code) ;================================
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
|
;================================ ; USB Keyboard driver by Elmar Hanlhofer (C) 2019 ; https://www.plop.at ;================================ ;bool USB_KBD_ClaimDevice (dword device) ;bool USB_KBD_ReportCallback (dword transfer) ;void USB_KBD_SetLeds (dword device, word led_bitmap) ;void USB_KBD_SetLedsCallback (dword transfer) ;void USB_KBD_SyncLedsWithBDA (dword device) ;bool USB_KBD_StatusFlagsHandlePress (word bios_key_code) ;void USB_KBD_HandleReports (dword device, dword current_report, dword previous_report) ;void USB_KBD_BDA_SetModifierFlags (word kbd_flags) ;word USB_KBD_TranslateToBiosCode (word kbd_scan_code) ;================================
%define USB_KBD_DEBUG_CLAIM ;%define USB_KBD_DEBUG ;%define USB_KBD_DEBUG_TD %define USB_KBD_DEBUG_KEY
;----------------------------------------------------------------------------- ; HID1_11.pdf Page 56, Modifier Keys Bitmap ;----------------------------------------------------------------------------- ; Bit Key ; 0 LEFT CTRL ; 1 LEFT SHIFT ; 2 LEFT ALT ; 3 LEFT GUI ; 4 RIGHT CTRL ; 5 RIGHT SHIFT ; 6 RIGHT ALT ; 7 RIGHT GUI ; ;----------------------------------------------------------------------------- ; HID1_11.pdf Page 60 ;----------------------------------------------------------------------------- ; The following table represents the keyboard input report (8 bytes). ; ; Byte Description ; 0 Modifier keys ; 1 Reserved ; 2 Keycode 1 ; 3 Keycode 2 ; 4 Keycode 3 ; 5 Keycode 4 ; 6 Keycode 5 ; 7 Keycode 6 ; ; Byte 1 of this report is a constant. This byte is reserved for OEM use. The ; BIOS should ignore this field if it is not used. Returning zeros in unused fields is ; recommended. ; ; The following table represents the keyboard output report (1 byte). ; ; Bit Description ; 0 NUM LOCK ; 1 CAPS LOCK ; 2 SCROLL LOCK ; 3 COMPOSE ; 4 KANA ; 5 to 7 CONSTANT ; ; The LEDs are absolute output items. This means that the state of each LED ; must be included in output reports (0 = off, 1 = on). Relative items would permit ; reports that affect only selected controls (0 = no change, 1= change). ;-----------------------------------------------------------------------------
USB_KBD_LEFT_CTRL equ 0 USB_KBD_LEFT_SHIFT equ 1 USB_KBD_LEFT_ALT equ 2 USB_KBD_LEFT_GUI equ 3 USB_KBD_RIGHT_CTRL equ 4 USB_KBD_RIGHT_SHIFT equ 5 USB_KBD_RIGHT_ALT equ 6 USB_KBD_RIGHT_GUI equ 7
USB_KBD_LED_NUM_LOCK equ 0 USB_KBD_LED_CAPS_LOCK equ 1 USB_KBD_LED_SCROLL_LOCK equ 2
%include "keyboard/keyboard.h"
;====================================== ;bool USB_KBD_ClaimDevice (dword device) ;====================================== USB_KBD_ClaimDevice: M_Vars
M_Arg device, S_DWORD
M_Local buffer, S_DWORD M_Local device_data, S_DWORD M_Code push eax push esi mov dword [.device_data], 0
; Check if the device is a keyboard and it supports the boot protocol.
push dword USB_DEVICE.wType push dword [.device] call GetValueWord cmp ax, TYPE_USB_DEVICE jne .wrong_device
push dword USB_DEVICE.bDeviceClass push dword [.device] call GetValueByte cmp al, 0 je .check_interface cmp al, 3 ; Human Interface Device jne .wrong_device
push dword USB_DEVICE.bDeviceSubClass push dword [.device] call GetValueByte cmp al, 1 ; Boot Interface Subclass jne .wrong_device
push dword USB_DEVICE.bDeviceProtocol push dword [.device] call GetValueByte cmp al, 1 ; Keyboard jne .wrong_device jmp .is_keyboard .check_interface: push dword USB_DEVICE.dConfigurationDescriptor push dword [.device] call GetValueDword or eax, eax je .wrong_device ; Pointer to Interface Descriptor. mov esi, eax add esi, USB_CONFIGURATION_DESCRIPTOR.size cmp byte [fs:esi + USB_INTERFACE_DESCRIPTOR.bInterfaceClass], 3 ; Human Interface Device jne .wrong_device
cmp byte [fs:esi + USB_INTERFACE_DESCRIPTOR.bInterfaceSubClass], 1 ; Boot Interface Subclass jne .wrong_device
cmp byte [fs:esi + USB_INTERFACE_DESCRIPTOR.bInterfaceProtocol], 1 ; Keyboard jne .wrong_device
.is_keyboard: %ifdef USB_KBD_DEBUG_CLAIM M_PrintfNL "USB_KBD_ClaimDevice: Keyboard detected" %endif
push word HID_USB_KEYBOARD push dword USB_DEVICE.bIsHid push dword [.device] call SetValueByte
; Create Pipe and add it to the device, register the endpoint descriptor. push word 50 push word 8 push word 0x81 push dword [.device] call OpenInterruptPipe ; (dword device, word endpoint_address, word word maximum_packet_size, word interval) jc .error
; Allocate buffer for the report. push dword USB_KEYBOARD_REPORT_SIZE call MEM_Allocate jc .error
mov [.buffer], eax
; Allocate memory for keyboard related device data. push dword USB_KEYBOARD_DEVICE_DATA.size call MEM_Allocate jc .error mov [.device_data], eax mov esi, [.device] mov [fs:esi + USB_DEVICE.dDeviceData], eax
mov eax, [.buffer] mov esi, [.device_data] mov [fs:esi + USB_KEYBOARD_DEVICE_DATA.dReport], eax
push dword 0 push dword USB_KBD_ReportCallback push dword USB_KEYBOARD_REPORT_SIZE push dword [.buffer] push word 0x81 push dword [.device] call QueueDataTransfer ; (dword device, word endpoint_address, dword buffer, dword buffer_len, dword callback dword callback_data) jc .error
push dword [.device] call USB_KBD_SyncLedsWithBDA ; (dword device)
mov eax, [.device] mov byte [fs:eax + USB_DEVICE.bClaimedByDriver], TRUE
clc jmp .exit .error: push dword [.device_data] call MEM_Free
%ifdef USB_KBD_DEBUG_CLAIM M_PrintfNL "KBD_ClaimDevice: Error." %endif stc jmp .exit
.wrong_device: %ifdef USB_KBD_DEBUG_CLAIM M_PrintfNL "KBD_ClaimDevice: INFO: Device is not a keyboard with boot protocol." %endif stc .exit:
pop esi pop eax M_Ret
;====================================== ;bool USB_KBD_ReportCallback (dword transfer) ;====================================== USB_KBD_ReportCallback: M_Vars M_Arg transfer, S_DWORD M_Local device, S_DWORD M_Local buffer, S_DWORD M_Code push eax push esi %ifdef USB_KBD_DEBUG M_PrintfNL "REPORT ooooooooooooooooooooooooooooooo" %endif
push dword TRANSFER.dLastTD push dword [.transfer] call GetValueDword ; (dword address, dword offset) %ifdef USB_KBD_DEBUG_TD push eax call PrintTransferDescriptorInfo %endif
push dword TRANSFER.dDevice push dword [.transfer] call GetValueDword ; (dword address, dword offset) mov [.device], eax
push dword TRANSFER.dBuffer push dword [.transfer] call GetValueDword ; (dword address, dword offset)
%ifdef USB_KBD_DEBUG push word USB_KEYBOARD_REPORT_SIZE push eax call PrintHexBuffer32 %endif
push dword [.device] call USB_GetDeviceData ; (dword device) mov esi, eax ; Check reports push dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dPrevReport] push dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dReport] push dword [.device] call USB_KBD_HandleReports ; (dword current_report, dword previous_report)
; Free old report push dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dPrevReport] call MEM_Free
; Set current report to old report push dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dReport] pop dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dPrevReport]
; Allocate buffer for the report push dword USB_KEYBOARD_REPORT_SIZE call MEM_Allocate jc .error
mov [.buffer], eax ; Save report memory mov [fs:esi + USB_KEYBOARD_DEVICE_DATA.dReport], eax
push dword 0 push dword USB_KBD_ReportCallback push dword USB_KEYBOARD_REPORT_SIZE push dword [.buffer] push word 0x81 push dword [.device] call QueueDataTransfer ; (dword device, word endpoint_address, dword buffer, dword buffer_len, dword callback dword callback_data) jnc .no_error
.error: ;M_PrintfNL "Report error"
.no_error: pop esi pop eax M_Ret
;====================================== ;void USB_KBD_SetLeds (dword device, word led_bitmap) ;====================================== USB_KBD_SetLeds: M_Vars M_Arg device, S_DWORD M_Arg led_bitmap, S_WORD
M_Local buffer, S_DWORD M_Local leds, S_WORD M_Local setup, S_DWORD M_Code push eax push bx
mov dword [.buffer], 0
; Allocate 1 byte for the led report push dword 1 call MEM_Allocate jc .error mov [.buffer], eax mov bl, [.led_bitmap] mov byte [fs:eax], bl
; Setup Packet push word 1 push word 0000h ; 00 = keyboard HID push word 0200h ; 02 = output report, 00 = report ID push word USB_REQUEST_SET_REPORT ; 09h push word USB_BM_REQUEST_TYPE_HOST_TO_DEVICE | \ USB_BM_REQUEST_TYPE_CLASS | \ USB_BM_REQUEST_TYPE_INTERFACE ; 21h call CreateSetupPacket ; (word bmRequestType, word bRequest, word wValue, word wIndex, word wLength) jc .error
mov [.setup], eax
push dword 0 push dword USB_KBD_SetLedsCallback push dword 1 push dword [.buffer] push dword [.setup] push dword [.device] call QueueControlTransfer ; (dword device, dword setup, dword buffer, dword buffer_len, dword callback, dword callback_data) jnc .done
.error: push dword [.buffer] call MEM_Free
;M_PrintfNL "Error"
.done: pop bx pop eax M_Ret
;====================================== ;void USB_KBD_SetLedsCallback (dword transfer) ;====================================== USB_KBD_SetLedsCallback: M_Vars M_Arg transfer, S_DWORD
M_Code push esi
; Free the buffer with the led data mov esi, [.transfer] push dword [fs:esi + TRANSFER.dBuffer] call MEM_Free pop esi M_Ret
;====================================== ;void USB_KBD_SyncLedsWithBDA (dword device) ;-------------------------------------- ; Set leds according to the Bios Data Area Keyboard Flags ;====================================== USB_KBD_SyncLedsWithBDA: M_Vars M_Arg device, S_DWORD
M_Code push eax push bx push word BDA_KEYBOARD_STATUS_FLAGS call BDA_GetByte ; (word offset)
xor bx, bx test al, b(BDA_KBD_SCROLL_LOCK_ON) je .test_num_lock or bl, b(USB_KBD_LED_SCROLL_LOCK)
.test_num_lock: test al, b(BDA_KBD_NUM_LOCK_ON) je .test_caps_lock or bl, b(USB_KBD_LED_NUM_LOCK)
.test_caps_lock: test al, b(BDA_KBD_CAPS_LOCK_ON) je .tests_done or bl, b(USB_KBD_LED_CAPS_LOCK)
.tests_done: push bx push dword [.device] call USB_KBD_SetLeds ; (dword device, word led_bitmap)
pop bx pop eax M_Ret
;====================================== ;bool USB_KBD_StatusFlagsHandlePress (word bios_key_code) ;-------------------------------------- ; Return zero flag, NZ = Shift ;====================================== USB_KBD_StatusFlagsHandlePress: M_Vars M_Arg bios_key_code, S_WORD M_Code push eax push bx push dx xor dl, dl mov bx, [.bios_key_code]
push word BDA_KEYBOARD_STATUS_FLAGS call BDA_GetByte ; (word offset)
cmp bh, 45h ; Num Lock Scan Code jne .check_caps_lock
xor al, b(BDA_KBD_NUM_LOCK_ON) jmp .update_bda
.check_caps_lock: cmp bh, 3Ah ; Caps Lock Scan Code jne .done
xor al, b(BDA_KBD_CAPS_LOCK_ON) .update_bda: push ax push word BDA_KEYBOARD_STATUS_FLAGS call BDA_SetByte ; (word offset, word value) mov dl, 1
.done: ; Return zero flag or dl, dl
pop dx pop bx pop eax M_Ret
;====================================== ;void USB_KBD_HandleReports (dword device, dword current_report, dword previous_report) ;-------------------------------------- ; Compare previous report with the current report to find ; the keys that have been pressed and released. ;====================================== USB_KBD_HandleReports: M_Vars M_Arg device, S_DWORD M_Arg current_report, S_DWORD M_Arg previous_report, S_DWORD
M_Local report_code, S_WORD M_Code push eax push ecx push edx push esi push edi mov esi, [.current_report] mov edi, [.previous_report]
;=============================== ; Handle Modifier Keys. ;=============================== ; Update BDA Flags on change. ; Related bytes: ; 0 Flag byte ; 1 Reserved ;-------------------------------
mov al, [fs:esi] cmp [fs:edi], al je .no_change
%ifdef USB_KBD_DEBUG_KEY M_Printf "Modifier Keys: " call PrintHex8 M_PrintfNL "" %endif push ax call USB_KBD_BDA_SetModifierFlags ; (word kbd_flags)
.no_change:
;=============================== ; Scan Keycode 1-6 for press. ;=============================== ; Check: Key is in new report, but not in previous report. ; Related bytes: 2 to 7 ;-------------------------------
; Start with offset of Keycode 1, current report. mov ecx, 2 .loop_press_current: mov al, [fs:esi + ecx] or al, al je .no_key_data_press
; Start with offset of Keycode 1, previous report, old keys. mov edx, 2 .loop_press_previous: ; Is the key from the previous report in the current report? ; If yes -> skip, key was pressed. cmp [fs:edi + edx], al je .key_was_pressed ; Next key in previous report. inc dl
; End of report reached? cmp dl, USB_KEYBOARD_REPORT_SIZE jne .loop_press_previous ; Key is not in the previous report -> Key pressed.
%ifdef USB_KBD_DEBUG_KEY M_Printf "Key press: " call PrintHex8 M_Printf " " %endif mov [.report_code], al
; Get SCAN CODE|ASCII CODE to AX push word [.report_code] call USB_KBD_TranslateToBiosCode ; (word kbd_scan_code)
push word ax call USB_KBD_StatusFlagsHandlePress ; (word bios_code) je .skip_leds
push dword [.device] call USB_KBD_SyncLedsWithBDA ; (dword device)
.skip_leds:
%ifdef USB_KBD_DEBUG_KEY call PrintHex16 M_Printf " " call PrintChar M_PrintfNL "" %endif
xchg ah, al ; Scan Code to AL and al, 7Fh ; Remove bit 8 call KBD_AddScanCodeToBuffer
.key_was_pressed: .no_key_data_press:
; Next key in current report. inc cl
; End of report reached? cmp cl, USB_KEYBOARD_REPORT_SIZE jne .loop_press_current ;=============================== ; Scan Keycode 1-6 for release. ;=============================== ; Check: Key is in previous report, but not in current report. ; Related bytes: 2 to 7 ;-------------------------------
; Start with offset of Keycode 1, previous report, old keys. mov ecx, 2 .loop_release_previous: mov al, [fs:edi + ecx] or al, al je .no_key_data_release
; Start with offset of Keycode 1, current report. mov edx, 2 .loop_release_current: ; Is the key from the current report in the previous report? ; If yes -> skip, key is still pressed. cmp [fs:esi + edx], al je .key_is_still_pressed ; Next key in current report. inc dl
; End of report reached? cmp dl, USB_KEYBOARD_REPORT_SIZE jne .loop_release_current
; Key is not in the current report -> Key released.
%ifdef USB_KBD_DEBUG_KEY M_Printf "Key released: " call PrintHex8 M_PrintfNL "" %endif
.key_is_still_pressed: .no_key_data_release:
; Next key in previous report. inc cl
; End of report reached? cmp cl, USB_KEYBOARD_REPORT_SIZE jne .loop_release_previous
pop edi pop esi pop edx pop ecx pop eax M_Ret
;====================================== ;void USB_KBD_BDA_SetModifierFlags (word kbd_flags) ;====================================== USB_KBD_BDA_SetModifierFlags: M_Vars M_Arg kbd_flags, S_WORD M_Code push eax push bx
; Get current keyboard status flags from the Bios Data Area push word BDA_KEYBOARD_STATUS_FLAGS call BDA_GetWord
; Clear flags that might be set and ax, ~( b(BDA_KBD_CTRL) | b(BDA_KBD_SHIFT_LEFT) | b(BDA_KBD_SHIFT_RIGHT) | \ b(BDA_KBD_ALT) | b(BDA_KBD_ALT_LEFT) | b(BDA_KBD_ALT_RIGHT) )
mov bl, [.kbd_flags]
; Detect flags. test bl, b(USB_KBD_LEFT_CTRL) je .1 or al, b(BDA_KBD_CTRL)
.1: test bl, b(USB_KBD_RIGHT_CTRL) je .2 or al, b(BDA_KBD_CTRL)
.2: test bl, b(USB_KBD_LEFT_SHIFT) je .3 or al, b(BDA_KBD_SHIFT_LEFT)
.3: test bl, b(USB_KBD_RIGHT_SHIFT) je .4 or al, b(BDA_KBD_SHIFT_RIGHT)
.4: test bl, b(USB_KBD_LEFT_ALT) je .5 or al, b(BDA_KBD_ALT) or ah, b(BDA_KBD_ALT_LEFT)
.5: test bl, b(USB_KBD_RIGHT_ALT) je .6 or al, b(BDA_KBD_ALT) or ah, b(BDA_KBD_ALT_RIGHT)
.6: ; Write back to the Bios Data Area push ax push word BDA_KEYBOARD_STATUS_FLAGS call BDA_SetWord
pop bx pop eax M_Ret
;====================================== ;word USB_KBD_TranslateToBiosCode (word kbd_scan_code) ;-------------------------------------- ; Return: ; AL = ASCII Char ; AH = Scan Code ;====================================== USB_KBD_TranslateToBiosCode: M_Vars M_Arg kbd_scan_code, S_WORD M_Code push esi
movzx eax, byte [.kbd_scan_code] cmp al, USB_KBD_TRANSLATION_TABLE_LAST_USB_CODE ja .unsupported_code shl eax, 2 mov esi, USB_KBD_TRANSLATION_TABLE - 4 * 4 add esi, eax ; Get PS/2 Scan Code. mov ah, [esi + 3] ; Get ASCII and check shift and caps lock. call KBD_HasShift je .no_shift
inc esi ; Use shift column.
.no_shift: mov al, [esi] jmp .done
.unsupported_code: mov ax, 0
.done: pop esi M_Ret
USB_KBD_TRANSLATION_TABLE: %include "usb/hid/codes/code_table.inc" ; Recalculate the last code: The table has 4 bytes per row and starts with the code 4 USB_KBD_TRANSLATION_TABLE_LAST_USB_CODE equ ($ - USB_KBD_TRANSLATION_TABLE) / 4 + 3
|
Download: usb_kbd.inc, code_table.inc
2018-12-15 - Status update - ISO 9660 File System, Boot Menu
The ISO 9660 file system has been implemented quickly two weeks ago. What a nice file system. My driver supports also the Rock Ridge extension. That means long file names and so on.
Currently I am working on the menu. A few boot modes are now working, but you have to wait for a test release!
As in the Plop Boot Manager, there is a fallback mode to an amazing text mode 80x50. See the screen shot. There will be also a Plop Boot Manager theme with the modified borders.
Using the menu When you press Enter at the drive entry, then the device will be booted in the standard way. This is for hard disks the MBR, for CDROMs the boot volume and for floppies the boot sector.
When you press the key "right" on menu entries with ">", then you open a context menu. So you can also boot a partition (as the hotkey "q" in the Plop Boot Manager) and view the device information.

Pressing key right.

I know, it looks similar to the graphic mode, but its text mode and this is the amazing part, as it was in the Plop Boot Manager :)
The binary size is currently 57 KB. Without textures, no USB, but native IDE and SATA and a lot of other important things. I have to be careful to add one driver after another.
The USB drivers needs some adaptions and will be added later.
Note: I saw the new features of Blender and also the new features of the Unity Game Engine. Wow, especially Blender!!! I have to finish the boot manager to continue with my Armored Eye Story/Game. Cyberpunk :)
2018-11-29 - Loader for CDROM
Implementing the loader to start the boot manager from CDROM was quite easy. Now continuing with the ISO 9660 file system. Its a simple file system and I am sure, I will need it later.
Great to see that old and simple concepts like ISO 9660, El Torito and also FAT FS are still important nowadays.
2018-11-27 - Window based menu system
USB HUB driver
The driver for USB 1.1 works fine. The driver for USB 2.0 is left to do.
Window based menu
I wrote routines for a window based menu system. As the Plop Boot Manager, it supports text and graphic mode, various resolutions (also wide screen), various fonts.

The new system supports background images and textures with alpha support to enable window shadows.

Todo
• Theme system to customize the look easily.
• Custom fonts.
• Font upscale on high resolutions.
• Window animation.
• Dynamic background.
• And a few other things...
This is a list of the functions from the current window library.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
dword W_GetX (dword object) dword W_GetY (dword object)
byte W_GetType (dword object) dword W_GetParent (dword object) void W_SetIsActive (dword object, word status) bool W_IsActive (dword object)
dword W_CreateWindow (word x, word y, word width, word height, word color, dword texture) void W_WindowAddItem (dword window, dword item)
void W_DrawWindowNoBorders (dword window) void W_DrawWindowWithBorders (dword window) void W_DrawWindowWithTexture (dword window) void W_ClearWindow (dword window)
dword W_CreateString (dword parent, word x, word y, word color, dword string) void W_DrawString (dword string) void W_DrawStringColor (dword string, word color)
dword W_CreateMenu (dword window, word x, word y, word width, word color, word bar_color) void W_MenuAddItem (dword menu, dword item) dword W_MenuAddEntry (dword menu, dword string, dword function, word barskip, dword data) void W_MenuMoveBar (dword menu, word action) void W_MenuUpdateItemsXY (dword menu) void W_DrawMenu (dword menu) dword W_MenuGetActiveEntry (dword menu) void W_MenuRunEntryFunction (dword menu)
void W_Main (dword menu)
void W_Draw (dword object) void W_DrawAll()
dword W_CreateBackground () void W_DrawBackground (dword dummy)
void W_DestroyMenuEntry (dword entry) void W_DestroyString (dword string) void W_Destroy (dword object)
|
Hello world window code sample
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
; Create the window object push dword [.window_texture] push word COLOR_BG (COLOR_GREEN) | COLOR_WHITE ; Background color | Foreground color push word 20 push word 50 push word 10 push word 10 call W_CreateWindow ; (word x, word y, word width, word height, word color, dword texture) jc .error mov [.window], eax
; Add a string to the window. ; Use text color from the parent window. push dword TxtHelloWorld push word 1 push word 2 push dword [.window] call W_CreateString ; (dword window, word x, word y, dword string) jc .error
mov [.wstring], eax
; Draw all objects call W_DrawAll
; Main loop, wait for input and handle menu system. ; This sample has no menu. push dword 0 call W_Main ; (dword menu)
; Remove the window and free the memory of the window and its childrens. push dword [.window] call W_Destroy ; (dword object)
|
I am coming closer to put all together. The window based menu system is good enough for the moment. It will be improved later. Now, I focus on booting.
I have to write a simple loader to start the menu from CD-ROM.
2018-10-05 - USB HUB driver status - continued
Device enumeration works. The driver works for USB 1.1.
Next: Improving and cleanup the code. Do some testing. Add support for USB 2.0 to the driver.
2018-10-04 - USB HUB driver status
The USB HUB driver is still under development. Yesterday, I found myself in some kind of a dead end. The HUB worked and I
was able to enumerate a fresh connected device. But my code was not good enough to run in an Interrupt Service Routine (ISR).
Today, I rewrote mostly and now I am a big step forward. Device connect/disconnect on any port is recognized in the ISR.
Device enumeration does not work at the moment, but this comes tomorrow.
Here are two pictures of my current test machine running the HUB driver. It is my old Gericom Webboy, bought (I think) in the year 2000.


2018-09-18 - UHCI, USB HUB, Synthetic DNA Menu
For a long time nothing Boot Manager related happened. But last week, I made the required code update for the UHCI driver.
Then I started to write the USB HUB driver. For testing, I want an USB HUB that supports only USB 1.1.
I gave my old USB 1.1 HUB away for a few cents many years ago :(. So bought and received a new one last week.
Last week (Thursday), I also had an idea about an extra ordinary menu. The Synthetic DNA Menu. I realized a concept with Blender.
But it's only an idea/dream. Too heavy for a boot manager that has only some basic 3D processing routines. It's just a boot manager :)
Maybe, I use this menu with the Armored Eye project. More about the Synthetic DNA Menu is here.
Video
External content blocked. Watch on YouTube
Images


2018-08-07 - USB mass storage with UHCI/EHCI and the USB floppy drive
The mass storage function call synchronization for UHCI, OHCI and EHCI is almost complete. Hard disks, thumb drives and CDROM drives
are working fine with the same function calls for all three controller types.
My USB 1.1 floppy drive did not work on OHCI and UHCI. My fault was to ignore the Interface Protocol value from the device. This drive
has to be accessed in another way than Bulk-Only drives.
You have to send the ATAPI Command Block over the Control Endpoint and send/receive the data over the Bulk Endpoints. Now, the floppy drive access works fine for OHCI.
Some code cleanup and updating the UHCI code is needed.
What comes after the code update? There is still the USB HUB driver missing. The USB keyboard driver needs a lot of updates.
2018-07-24 - USB DVD drive
The first work I did today was to check why the USB DVD drive did not work. I found the problem quickly. I allocated only 512 bytes instead of 2048 bytes for
the sector read destination buffer. 2048 bytes is the block size of CD ROMs. Because of the wrong size there was overlapped memory that created invalid data. The invalid data was the reason for the drive reset.
Now the drive works perfect.
The USB Floppy drive still makes problems. I have to check whats going on on the USB bus. But now there is some work to do for EHCI and UHCI.
2018-07-23 - Just a status update
I synchronized the OHCI and EHCI code that the access to the shared USB functions works in the same way. UHCI is left to synchronize. The base programs for those drivers lived in their own environment and
function calls changed during development. Word sized parameters became dword size, here and there is an additional parameter required. Assembler is not flexible as a high
level language, even with my macros ;). So you have to take care by yourself to submit the correct parameters in the correct size to a function call. That means more and overall a clean work, but at the end
its also more fun for the software developer, in a funny or strange matter ;).
I also cleaned up and simplified the USB Bulk driver, needed to access mass storage devices. I added nearly all required functions like inquiry, read capacity, read sector, write sector and so on.
It works fine with the OHCI driver and hard disks/thumb drives. I also tried my USB Floppy Drive and USB DVD Drive. Unfortunately, one drive hung and the other resets itself. In other words,
both did not work. That's life. It was a bit disappointing, but I will fix it. For EHCI, I have to update the USB Pipe logic and then test the bulk driver. But that comes later.
2018-07-21 - ReactOS/FreeLoader/Plop Boot Manager
It has partially to do with the new boot manager. But its also important. I created a dirty fix to start the Plop Boot Manager from the FreeLdr boot menu. It has to be tested.
See https://forum.plop.at/index.php/topic,1840.msg7424.html
Some notes about ReactOS
ReactOS error message "Userinit failed to start the installer!". You are using the wrong ReactOS CD for installation. Don't use the ReactOS Live CD, choose the other one.
ReactOS boot error message "hive header failed" or blue screen. Maybe your virtual hard disk is too small. Use at least a size of 4 GB.
2018-07-11 - USB OHCI driver 16/32 bit test
Today, I tested my USB OHCI code in my 32 bit environment. The code was written and tested in a 16 bit environment. The plan was/is to run the code in 16 and 32 bit CPU mode.
In this experimental stage, the driver is not loaded dynamically. I had to prepare and hard code a few things and then.... It gave me a chill!
It was great to see that the code worked fine in the same way as in the 16 bit environment. I am really happy :)
Note: 16/32 bit code runs also on a 64 bit CPU.
2018-07-09 - USB OHCI driver implementation
I started to add the USB OHCI routines to the boot manager test program as a driver.
I was struggling for many hours with a mysteries bug. Finally I fixed the bug (again).
The bug was an old "friend".
Elmar, just set the device as PCI bus master! Rolling eyes! That was the problem.
That hurts.
Okay, now I can continue with the driver stuff. There are still tests
and a stable workflow required to implement a dynamic driver loading.
The OHCI routines have to be tested in various CPU modes too. Its time for a Pizza...
2018-07-06 - Minor updates
I finished only a few things. INT 13h hook for drive swapping works fine. I extended the FAT read support to FAT12 and FAT32.
2018-06-18 - FAT16, Linux Kernel, NTLDR
No update since one month. What happened? Nothing special. Just some booting. But don't expect too much!
FAT16 reading works fine. I can change directories and read files. FAT16 writing and FAT12/32 support is left to do. But with the FAT16 reading support, I was able to do some interesting things.
Native Linux Kernel booting works (from FAT16). I can load the kernel and an initrd file and boot Linux. I can also set the Linux Kernel Command Line.
Native Windows XP booting with direct loading of the NTLDR works (from FAT16). More recent Windows booting should work too. That's not an important feature, but nice to have.
MBR loading and booting works too.
What comes next? There are still a lot of things to do. I am far away from any beta testing. Many things that are working are splitted up in own parts and have to put together. But this comes later.
Next steps are
• Boot sector loading and booting. That should not be difficult.
• Writing various loaders to start the Boot Manager Test Program from different locations (MBR, boot sector, floppy, CDROM, ...).
• FAT16 write support.
• FAT12/32 support.
• Some INT 13h hooks for testing. For example drive swapping to boot from the second hard disk.
• Trying to add the USB drivers carefully.
• Looking forward to Ext and NTFS drivers.
That's a heavy to-do list for the next steps!
2018-05-07 - Are you dreaming in hex?
Maybe sometimes! Hexadecimal is part of my life. File Allocation Table Artwork :)
I started with FAT file system support. Currently required for native Linux kernel loading tests.
The boot manager will need FAT support too.
I began with FAT16.
Directory listing works. Of course with long file name support (optional only 8.3 format). Cluster reading works too. Next step is a working "read file" routine. And then
modify the code for FAT12 and FAT32.
2018-05-03 - MBR Partition Table / GUID Partition Table
The Master Boot Record partition table support has been finished. Classic and cascaded extended partitions are supported. Now, I am numbering the partitions
in the same way as Linux. Primary partitions get a number from 1 to 4, according to the position in the partition table. The first logical partition starts with 5.
I also wrote the support for GUID Partition Tables (GPT).
All various partitions are accessed by the same shared ReadSector/WriteSector function call. It works very well :)
2018-04-28 - Drive access layer
I did some code cleanup and various fixes. I also
added a layer to access various drives with the same function call. Now it doesn't matter if its a DVD drive or a hard disk (floppy is not done yet).
The drives are registered during PATA/SATA enumeration. I also added a simple support for the classic MBR to access primary partitions.
The partitions are registered too and can be also accessed by a shared function call. Full MBR support and GPT support will be implemented on Monday/Thursday.
Read boot sector of partition 1 from drive 3.
Note: Drive number and partition number starts with "0".
1
2
3
4
5
6
7
8
9
10
11
12
|
push dword 512 call MEM_Allocate jc .error mov dword [.buffer], eax
push eax push word 1 push dword 0 push word 0 push word 2 call PReadSector28 ; (word drive_number, word partition_number, dword lba, word num_sectors, dword buffer) jc .error
|
Drive registration. Using wrapper functions for
standardized calls. Dynamic registering for USB drives is not done yet.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
M_PrintfNL "SATA device found."
push word ATA_CMD_IDENTIFY push esi call AHCI_Identify ; (dword port_address, word identify_command) jc .check_for_atapi mov [.identify], eax
; Register drive push esi push word 0 push word 0 push dword AHCI_Write28Wrapper push dword AHCI_Read28Wrapper push word 512 push dword [.identify] push word DRIVE_SATA call RegisterDrive ; (word drive_type, dword identify, word bytes_per_sector, ; dword read_sector_28, dword write_sector_28, ; word pata_channel, word pata_drive, ; dword ahci_port)
|
Current drive register routine
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
;===================================== ;dword RegisterDrive (word drive_type, dword identify, word bytes_per_sector, ; dword read_sector_28, dword write_sector_28, ; word pata_channel, word pata_drive, ; dword ahci_port) ;------------------------------------- ;Returns drive structure address ;Carry on error ;===================================== RegisterDrive: M_Vars
M_Arg drive_type, S_WORD M_Arg identify , S_DWORD
M_Arg bytes_per_sector, S_WORD
M_Arg read_sector_28 , S_DWORD M_Arg write_sector_28, S_DWORD
M_Arg pata_channel, S_WORD M_Arg pata_drive , S_WORD
M_Arg ahci_port, S_DWORD
M_Local drive, S_DWORD M_Code push ebx push edi
mov dword [.drive], 0 ; Allocate memory for the drive structure push dword SYS_DRIVE.size call MEM_Allocate jc .error
mov edi, eax ; edi became the drive address mov [.drive], eax
; Fill the structure mov word [fs:edi + SYS_DRIVE.wType], SYS_TYPE_DRIVE
mov bx, [.drive_type] mov [fs:edi + SYS_DRIVE.wSubType], bx
mov ebx, [.identify] mov [fs:edi + SYS_DRIVE.dIdentify], ebx
mov bx, [.bytes_per_sector] mov [fs:edi + SYS_DRIVE.wBytesPerSector], bx
mov ebx, [.read_sector_28] mov [fs:edi + SYS_DRIVE.dReadSector28], ebx mov ebx, [.write_sector_28] mov [fs:edi + SYS_DRIVE.dWriteSector28], ebx mov bx, [.pata_channel] mov [fs:edi + SYS_DRIVE.wChannel], bx
mov bx, [.pata_drive] mov [fs:edi + SYS_DRIVE.wDrive], bx
mov ebx, [.ahci_port] mov [fs:edi + SYS_DRIVE.dAHCI_Port], ebx
call GetFreeDriveNumber jc .error mov [fs:edi + SYS_DRIVE.bDriveNumber], al
; Add the drive to the drives list mov ebx, SYS_RAM add ebx, SYS_KERNEL.dDrives
push edi push ebx call LIST_AddEntry ; (dword list, dword entry) jc .error
; Return drive address mov eax, edi jmp .done
.error: ; Release allocated memory push dword [.drive] call MEM_Free ; Set carry for error stc .done: pop edi pop ebx M_Ret
|
2018-04-19 - ATAPI CDROM drive drivers
The ATAPI drivers for IDE (PATA) and AHCI (SATA) for CDROM (and similar) drives are almost done. There is a strange behavior with the AHCI ATAPI driver. The first ATAPI command ends in an
error. After this, all tested ATAPI commands are working fine. At the moment, I have no idea why the first command fails.
Drivers tested only on two machines.
BIOS INT 13h implementation is not done.
2018-03-28 - Relocate addresses for program/driver loading
For long time, nothing important happened.
Now, I spent two days for a simple address relocation system
which is needed to support dynamic loading of programs and drivers.
I wrote two PHP scripts which are analyzing the list file, generated by NASM with the '-l' parameter.
The first PHP script (syscalls.php) generates a file with jumps to the kernel system functions (syscalls.inc).
This generated file is included by the program/driver (my_program.asm) to make it easy to call
the kernel functions. NASM generates all addresses according to the ORG command. Those addresses must be updated
when the program/driver has been loaded into the memory.
The second PHP script (relocate.php) creates a file with
two tables (relocate_table.inc). This tables are holding the positions of all addresses used by the program/driver. This file has to be included too.
The addresses, which are now stored in the header of the program, are updated by a simple routine in the kernel (relocation code),
before the kernel can start the program.
Here is an overview with source codes. It may change in the future. It is just the first version. Maybe it looks difficult, but I tried to keep it simple. Explaining is not my strength.
Sample code to load a program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
; Allocate memory for the program push dword [.file_size] call MEM_Allocate jc .error mov [.address], eax ; Load the program push dword [.address] push dword [.file_size] push dword [.file_name] call SYS_LoadFile jc .error
; Update addresses push dword [.address] call PROGRAM_AddressRelocate ; Start the program call dword [.address]
|
Simple program header:
1
2
3
4
5
6
7
8
9
10
11
|
struc PROGRAM_HEADER
.jump resb 5 .align_bytes resb 3
.reloc_table_syscalls_size resd 1 .reloc_table_local_size resd 1
.reloc_table_syscalls:
endstruc
|
Address relocation code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
;===================================== ;void PROGRAM_AddressRelocate (dword program_address) ;===================================== PROGRAM_AddressRelocate: M_Vars M_Arg program_address, S_DWORD
M_Code push ebx push ecx push esi push edi
; Address of the relocation table. mov esi, [.program_address] add esi, PROGRAM_HEADER.reloc_table_syscalls
; Get number of syscall addresses. mov ebx, [.program_address] mov ecx, [ebx + PROGRAM_HEADER.reloc_table_syscalls_size] shr ecx, 2 ; We have 4 byte addresses, so divide with 4. je .skip_syscall_addr ; Skip if we have no address.
.relocate_syscall_addr_loop: ; Get the address in the program. mov edi, [esi]
; All syscall addresses are lower than the program address. ; Substract the program memory address to restore the kernel address. sub dword [ebx + edi], ebx
; Next entry. add esi, 4 dec ecx jne .relocate_syscall_addr_loop
.skip_syscall_addr:
; The table with the program addresses comes directly after the syscall table, ; there is no need to set ESI.
; Get number of program addresses. mov ecx, [ebx + PROGRAM_HEADER.reloc_table_local_size] shr ecx, 2 ; We have 4 byte addresses, so divide with 4. je .skip_program_addr ; Skip if we have no address.
.relocate_program_addr_loop: ; Get the address in the program. mov edi, [esi]
; All addresses have to be set relative to the new memory address of the program. ; Add the program memory address. add dword [ebx + edi], ebx
; Next entry. add esi, 4 dec ecx jne .relocate_program_addr_loop
.skip_program_addr:
pop edi pop esi pop ecx pop ebx M_Ret
|
Sample syscalls.inc:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
; 0000003D MEM_Allocate: MEM_Allocate: jmp 0000003Dh
; 000000FE MEM_AllocateAligned: MEM_AllocateAligned: jmp 000000FEh
;----------- SNIP ---------------
; 00000FCC PrintHex16p: PrintHex16p: jmp 00000FCCh
; 00000FFC PrintHex16: PrintHex16: jmp 00000FFCh
; 0000100F PrintHex32: PrintHex32: jmp 0000100Fh
; 00001021 PrintInt8: PrintInt8: jmp 00001021h
|
Sample program (my_program.asm):
Command: nasm -f bin my_program.asm -o my_program.bin -l my_program.lst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
%include "sys32/sys32.inc"
%define STRING_END 0 %include "macro/printf.inc"
[ORG 0h] ; Simple program header jmp start ; Initial jump db 0, 0, 0 ; Align bytes
%include "relocate_table.inc"
%include "syscalls.inc"
var1 dw 3344h ; Sample variable
;====================== ; Program start ;====================== start:
; Use a kernel function push word [var1] call PrintHex16p
; Start a function of the program call TestRoutine
; End program ret
TestRoutine:
; Use kernel system print M_PrintfNL "Test"
; Use another system call mov ax, [var2] call PrintHex16
ret
var2 dw 2244h ; Sample variable
|
Simple PHP script to export kernel function calls (syscalls.php):
Command: php syscalls.php kernel.lst > syscalls.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
<?php /* Generate jump instructions for kernel system calls. Source file is the list file generated by NASM with -l.
Written by Elmar Hanlhofer 2018/03/28 Free to use. Using: php syscalls.php kernel.lst > syscalls.inc */ if (!$argv[1]) { die ("No input file!"); }
$f = file ($argv[1]);
foreach ($f as $v) { $v = str_replace ("\n", "", rtrim ($v));
$line_nr = substr ($v, 0, 7); $addr = trim (substr ($v, 7, 8)); $opcode = substr ($v, 16, 19); $asm = trim (substr ($v, 40));
if (strpos ($asm, ":") && ($asm[0] == strtoupper ($asm[0]))) // Use only labels which have // an upper char at the beginning { $label = $asm; }
if (strpos ($opcode, "<") !== false) { unset ($label); }
if ($addr && $label) { if (strpos (" .;%", $label[0]) === false) // Skip various { echo "; $addr $label\n"; echo "$label\n"; echo " jmp $addr" . "h" . "\n\n"; } unset ($label); }
}
echo "SYSCALLS_End:\n\n";
// Sample input: // 87 <1> MEM_Allocate: // 93 0000003D C8040000 <1> M_Code
?>
|
Simple PHP script to create the relocation table (relocate.php):
Command: php relocate.php my_program.lst > relocate_table.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
<?php /* Generate the relocation address table. Source file is the list file generated by NASM with -l.
Written by Elmar Hanlhofer 2018/03/28 Free to use. Using: php relocate.php my_program.lst > relocate_table.inc */
define ("SYSCALLS_END", "SYSCALLS_End:"); // Marker, written by syscalls.php
function TableEntry ($code_addr, $opcode, $char_begin, $char_end, $address_size) { if ($offset_addr = strpos ($opcode, $char_begin)) // Is there an address in the opcode? { $end = strpos ($opcode, $char_end); $size = $end - $offset_addr - 1; if ($size == $address_size) // Is it the requested size? { echo " dd 0$code_addr" . "h + " . ($offset_addr / 2) . "\n"; // OPCODE COMMAND + POSITION OF ADDRESS // div 2 because 1 byte is 2 chars } } }
if (!$argv[1]) { die ("No input file!"); } $f = file ($argv[1]); echo "RelocateTableSize_Syscalls dd RelocateTableEnd_Syscalls - RelocateTableStart_Syscalls\n"; echo "RelocateTableSize_Local dd RelocateTableEnd_Local - RelocateTableStart_Local\n\n";
echo "RelocateTableStart_Syscalls:\n"; foreach ($f as $v) { $v = str_replace ("\n", "", rtrim ($v)); $line_nr = substr ($v, 0, 7); $addr = trim (substr ($v, 7, 8)); $opcode = substr ($v, 16, 19); $asm = substr ($v, 40);
if ($asm == SYSCALLS_END) // End of syscalls reached? { break; }
// Build the table for the syscall addresses TableEntry ($addr, $opcode, "(", ")", 8); TableEntry ($addr, $opcode, "[", "]", 8); } echo "RelocateTableEnd_Syscalls:\n\n";
$syscalls = true; echo "RelocateTableStart_Local:\n"; foreach ($f as $v) { $v = str_replace ("\n", "", rtrim ($v)); $line_nr = substr ($v, 0, 7); $addr = trim (substr ($v, 7, 8)); $opcode = substr ($v, 16, 19); $asm = substr ($v, 40);
if ($asm == SYSCALLS_END) // End of syscalls reached? { $syscalls = false; } if (!$syscalls) // Build the table for program addresses { TableEntry ($addr, $opcode, "(", ")", 8); TableEntry ($addr, $opcode, "[", "]", 8); } } echo "RelocateTableEnd_Local:\n";
?> |
2017-12-29 - NASM Helper
At the beginning of the new boot manager development, I wrote some macros
to make the use of function calls easier in Assembler. The macros are written for NASM. Now, I released them under the name "NASM Helper".
NASM Helper
At the bottom of the page, you will find a complex routine called QueueControlTransfer. Its from my OHCI USB driver.
I know, its useless without the other functions, but its a nice example for a more complex function.
2017-12-20
OHCI Enumeration bug fixed.
Rewriting UHCI code done.
2017-12-18 - Bug killed
I found the bug, without converting the old code. I figured out that the host suddenly stopped sending frames. Very mysterious. Finally
I found the reason for this behavior. Unintentionally, I set the USB port into suspend mode. I used "OR"
to write a bit, without modifying the other bits,
in the port register. But for this register, its required to set the bit with "MOV"
without other bits set. The strange thing is, that the "OR" works on other hardware, which seem to be more tolerant in this case.
This bug wasted a lot of time, but it works now. Now there is a new issue with the enumeration process on that machine, but it should not be difficult to fix it.
Asking again, is the code from 2007 better? No, the new code is better now :)
2017-12-16 - Hmm, bugs
Hmm, what should I say. I hoped to have finished a lot of things. But I didn't. I was ill in November. Then I had various things to do
in the rest of November and in December. And now I am struggling with a crazy "new boot manager" driver bug since a week. Its the OHCI USB driver.
I thought it works fine, but then I used it on my old Gericom Webboy Laptop. A simple USB resquest ends in a DeviceNotResponding error. The frustrating thing is,
my driver of 2007 works flawless. I cannot figure out whats wrong. Data structures and register values are the same. Frustrating.
I am not able to fix that for one week!!!! The old code was written for LZASM. Now I am using NASM.
Since days I try to find the bug without converting the old code to NASM. But I fear, I reached the point to accept that I have to convert the old code to find the difference....
Is the code from 2007 better? Hmmm, yes and no.
2017-10-13 - What do I have so far
Its time for a development status.
The code is written in pure assembler. I am using NASM. The goal is to operate in various CPU modes on i386 CPUs and better. Most of the code is currently tested
in the 'unreal mode' (16/32 bit). With just a few modifications, the code will run in native 32 bit too. This code will also run fine on 64 bit CPUs.
The device access (except video mode switching) happens native without BIOS. This is required to work in various CPU modes in the same way, regardless if I have a BIOS in the background
or not. Why do I need various
CPU modes? Because I want to support old and modern computers. DOS should be able to use the boot manager drivers without additional software.
But don't dream about DOS and UEFI. This will not work.
Basic system routines
Memory management: Done.
PCI device enumeration: Done.
CPU mode switching: Done.
Basic text mode output routines: Done.
Graphic mode (VBE): Mode detection, initialization, pixel drawing, text drawing done.
Image files: Reading and display TIFF images done. TIFF format: uncompressed, RGB, Intel.
Driver development stage 1
Keyboard PS/2: Key read done.
PATA (IDE) HDD: Read and write.
PATA (IDE) optical drives: Not done.
SATA AHCI HDD: Read and write.
SATA AHCI optical drives: Not done.
Classic floppy drive: Not done.
USB 1.1 UHCI: Most done, but I am unhappy with the code. I have to rewrite the most.
USB 1.1 OHCI: Initialization, control transfers, interrupt transfers, bulk transfers, USB device enumeration done. Some things are left to do.
USB 2.0 EHCI: Initialization, control transfers, bulk transfers, USB device enumeration done. Lets say over 50% is done. Difficult things like split transactions and other things are left to do.
USB 3.x: Not started.
USB Keyboard: Detection and key read works. TODO: Key mapping.
USB Mass Storage: Basic functions like device identify works. This implementation shouldn't be a big deal.
USB HUB: Starting in the next days.
What means development stage 1? In this stage the drivers are working in their own environment. But its too early to put them together.
2017-10-06 - A driver development adventure
Last week I started to write the USB 2.0 EHCI driver from scratch. Everything looked fine and worked as expected, but then I tried it
with VirtualBox. You know, the Plop Boot Manager 5.0.x hangs when you use the USB 2.0 EHCI driver to boot from USB in
VirtualBox. I tried my new code and ........... it hangs too.
I said okay, I try to figure out whats wrong. I am motivated and I want to fix this problem.
Then I
struggled with the problem for one week. It was frustrating. The queue heads haven't been processed. Only
malformed queue heads resulted in a transaction error. But nothing happened on correct queue heads with
correct transfer descriptors. For some time I thought the port reset is the problem and the USB device is
in a problematic state. You have to know, in VirtualBox, the port reset ends immediately after starting the reset. According
to the EHCI Specification, the reset has to be ended by the software and not the host. Then I thought that
the host cannot transmit to device 0 because the USB device is still configured with an address
because of the strange port reset behavior. So I created queue heads for every possible device number. Hmmmm,
I received no errors and no transactions. Nothing! When there is no response, then its really frustrating.
Accepting that my code does not work in VirtualBox became an option for me. But finally I can not accept it. Meanwhile
it looks like I am in an endless loop. Doing the same things with the same disappointing result.
Then by luck, I made a mistake. And now comes an important information for those who plan to
write an EHCI driver. As first transfer descriptor, I linked a transfer descriptor without any data except the 'Next qTD Pointer'
to a SETUP transfer descriptor. And suddenly, the SETUP transfer descriptor has been processed as expected. Strange.
When the first transfer descriptor is empty, then the following transfer descriptors are processed.
I don't know why, but this
works on other EHCI controllers too, so I accept that and I am happy that my code works now also in VirtualBox.
I will fix the EHCI driver of the Plop Boot Manager 5.0.15 that the USB 2.0 boot works also in VirtualBox.
But thats enough for today.
2017-09-17 - UEFI
I spent some time for UEFI and created a
simple menu to boot Plop Linux and Windows with UEFI. This was just a funny test. There is no dynamic OS detection or config file. All is hard coded, just to see how software development with UEFI works.
External content blocked. Watch on YouTube
2017-07-12
Programming the new boot manager, but it's a slow process. Nothing to show at the moment...

2017-02-12
New development start is April 2017.
2016-07-29
My desk. Developing a driver at night.

During rewriting the USB drivers, I found some bugs in the old code. The chances are good, that I release a 5.1 version of the old 5.0.15 boot manager with fixed USB drivers. But who knows...
2016-06-28
No news, no time to update this page. Coding has been stop at beginning of 05/2016. Maybe I find time in august 2016.
2016-04-22
Continue coding :)
2016-03-14
Coding paused because of other work.
2016-03-13
I created a concept art of the GUI. The final product will look different, but this could be a nice design. No line of code has been written for the GUI, booting has priority ;) A release date is far far away.


There will be also a hidden mode and a simple text mode interface like in the current Plop Boot Manager.
2016-02-02
Work in progress...
© 2023 by
Elmar Hanlhofer
|