mmlr's blog

makebootable - What and why and how to do it manually

Blog post by mmlr on Sun, 2009-02-08 16:12

Usual question: "I've dd'ed the image to somewhere and now it doesn't boot". Usual advice: "You have to make it bootable by using makebootable". Usual reaction: "Ehm, ok how do I do that?". Since this type of question comes up quite frequently, let me try to explain a bit of background on that pseudo-mystical tool "makebootable", how you can get it and how you can manually make a partition bootable without even needing makebootable.

The Stage 1 Bootloader

Ok, what we are really talking about here is the stage 1 bootloader. It is a tiny bit of software that is written to the start of a partition or disk. It is where either the BIOS or the boot manager will jump to to get the OS booted. In the case of Haiku this stage 1 bootloader loads a bit of the BFS partition the installation is on and locates /beos/system/zbeos. zbeos is the stage 2 bootloader, which provides the boot menu and loads the kernel. In the case of a missing makebootable we never get to that stage 2 bootloader.

If you want to look at it from the code side you should check out "src/system/boot/platform/bios_ia32/stage1.S". It's nicely commented and pretty straight forward to follow. But let me just explain the rough outline:

  • 1. Set up a few basics, clear registers and store the drive id
  • 2. Check if we have disk extension provided by the BIOS
  • 3. Load the rest of the stage 1 bootloader
  • 4. Validate the BFS superblock
  • 5. Search the stage 2 bootloader on disk
  • 6. Load the stage 2 bootloader into memory
  • 7. Run the stage 2 bootloader

When we enter the stage 1 bootloader we have the following available: the first block of the stage 1 bootloader, so the first 512 bytes. What we do from there is execute steps 1-3. Even though the stage 1 bootloader is only a tiny bit of software, it's not tiny enough to fit completely into one 512 byte block. That's why it is split across the first and second block of a partition (with the BFS superblock sandwiched between the two parts at the start of the second block).

Where we fail with a missing makebootable is step 3. This is the first time we need to load something from disk. To do that we use the BIOS disk services that provide us with a simple interface to load stuff from disk into memory. We are always accessing the disk here, and not the partition. This means, when we want to load the second part of the stage 1 bootloader, we need to instruct the BIOS to load the block "where we are" + 1. And that's exactly the important part here "where we are", i.e. where the first part of the stage 1 bootloader is. The thing is, we do not know where the first part of the stage 1 bootloader is on disk. We don't know the needed offset to get from the start of the disk to the partition we are booting from. Therefore we can't calculate the location of the second block and subsequently the location of the BFS structures.

So how do we get to know that offset? Simple: it is written into the stage 1 bootloader using makebootable. The only thing makebootable does is to find exactly that partition offset and write it into the bootloader at a specific place (bytes 506-510 to be exact), so that the first part of the stage 1 bootloader is able to calculate the correct offsets into the disk.

When you start out with a normal Haiku disk image, the offset is simply initialized to 0. With that background you should now be able to understand why it works to dd a raw image to a raw device and get it booted. It works because if you write the image at offset 0, this is the same offset that is present in the image. If you write it to somewhere else, i.e. you write the image to a partition instead, meaning the disk offset is not 0, the stage 1 bootloader will still try to read from offset 0 + 1, because that's what is written into the bootloader. So this won't boot.

The makebootable Tool

As mentioned the purpose of makebootable is to write a stage 1 bootloader to a partition and supply it with the correct partition offset. The problem makebootable has to solve is to be available on different platforms and be compatible with the different ways of finding the partition offset. Each OS has its own API for that, that's why makebootable has to be explicitly ported to make writing directly to a partition work. So far it's been ported to linux, FreeBSD, Darwin and of course BeOS and Haiku. On unsupported platforms (like on Windows or Solaris for example) you therefore can't use makebootable to do it automatically for you.

On supported platforms however you can build makebootable using the command "jam run :\<build\>makebootable /dev/sdc4". This will build and run makebootable for your host platform, giving it the partition you want to make bootable ("/dev/sdc4" for example). This will output the partition offset that is written to the stage 1 bootloader.

Note that if you have a BeOS or Haiku installation you can use makebootable from there. The BeOS stage 1 bootloader is a bit different, but it's compatible with the Haiku stage 1 bootloader, as it loads the stage 2 from /beos/system/zbeos as well. So on these platforms just run "makebootable /dev/disk/...". You can run makebootable with a path of a mounted volume as well, so if you mounted the target partition at "/HaikuStick" you can as well do "makebootable /HaikuStick".

If You Can't Use makebootable

If you can't use, or don't want to use makebootable, you can of course do the partition offset thing manually. For example if you are on Windows and want to make the second partition of your USB drive where you dd'ed the image to bootable. What you need for that is a hex editor. If you can get one where you can access the raw disk directly that's the best situation, otherwise you have a few steps more.

The first step is to find out what the partition offset in blocks is. If you have some tool to get that information from, get it from there. You either need the offset in 512 byte blocks or the offset in bytes and then divide that by 512. If you don't have a tool that can display the offset, you should be able to read it from the partition table in the master boot record (MBR). If you have a hex editor allowing you to access the raw device at offset 0 (where the MBR is located) point it there. If not, use dd to read the MBR into a file (something along "dd if=/dev/sdc of=mymbr.bin bs=512 count=1" in case of Windows take the "Partition0" thing, they really mean raw device by partition 0) and open that in the hex editor. Now when you're looking at that MBR you gather the partition offset from the partition table. The layout is documented for example at Wikipedia, but since that is a lot of info for a small task, let me explain that the partition table starts at offset 446 (0x1be) and has 4 entries of 16 bytes. Each entry being:

  • 1. Active flag (1 byte, 0x80 = active 0x00 = not active)
  • 2. Start offset in cylinder/heads/sectors (CHS) format (3 bytes)
  • 3. Partition type (1 byte, 0xeb for BFS, but it doesn't really matter)
  • 4. End offset in CHS format (3 bytes)
  • 5. Start offset in logical block address (LBA) format (4 bytes)
  • 6. Partition length in blocks (4 bytes)

What we need from that is the partition start offset in blocks. This is exactly what field 5 holds for us. Note that this is a little endian 32 bit integer, but as the format is the same in the stage 1 bootloader it doesn't matter at all. Just note down that number for the partition you want to make bootable. The direct offsets to those numbers are 454, 470, 486 and 502 for primary partitions 1, 2, 3 and 4 respectively. If you're doing logical partitions here, you'll have to figure out how to get that offset yourself, sorry.

When you finally have that offset, you can either patch it directly on the partition if you have a hex editor that allows that or you simply patch it in the haiku image you started with and afterwards dd it to your partition again. In any case you point the hex editor to the first block of the stage 1 bootloader (the first block in the image file or on the partition) and write down the partition offset number at offset 506, just so that you don't touch the 0x55 0xaa at the very end of that block. If you have the partition offset as a number read from a tool, convert it to hex and write it there as a 32 bit little endian integer (i.e. reversed so an offset of 0x01020304 would result in the bytes 0x04 0x03 0x02 0x01 at offset 506). Just to explain it a bit more graphically here's a screenshot of DiskProbe under Haiku with the two relevant parts selected. On the left the MBR and on the right the partition with the same offset.
manual makebootablemanual makebootable

Native GCC 4.3.3 for Haiku - Tales of updating the GCC4 port

Blog post by mmlr on Sun, 2009-02-01 02:38

Out of no real particular motivation I wanted to build a native GCC4 for Haiku. We've had a GCC 4.1.2 cross-compiler for a pretty long time now, but since there were some issues with GCC4 built Haiku installations and especially since there never was a native toolchain for GCC4 based Haiku, it has always been a second class citizen. You could experiment around with it and we've had hybrid builds able to use software for both GCC2 and GCC4 Haiku on the same install, but since you had to use the cross-compiler to build GCC4 Haiku apps it's always been a bit less convenient that just building for GCC2 Haiku. But there's a lot of software around that simply can't be built using GCC2 anymore. The reason for that being the use of coding conventions or simply features that weren't available in GCC2. So a native GCC4, meaning a GCC4 running inside Haiku and building GCC4 Haiku apps, is a really important thing to have for porting and building many future applications.

Since I briefly looked into updating the GCC4 cross-compiler in summer 2008 already (without getting very far because of lack of time), I already knew pretty much what to get and where to get it. I also already built a diff between the vendor and trunk version of the 4.1.2 cross-compiler in the buildtools repository. So I had a rough idea of what I needed to touch to get things going.

I was about to build a native GCC4. This means that I was going to build it on Haiku itself. Of course you could actually cross-compile a native compiler in a two step process on another platform as well. But since I use Haiku as my main and only operating system here, this was no real option. So this meant that a GCC2 Haiku with a GCC2 compiler would be the host for all the fun. Considering that GCC is a huge project, consisting out of many subprojects and thousands of source files, this would be a pretty tough stress test for Haiku. I wasn't even sure if the GCC 2.95.3 we are using was up to the task, but it turned out that this didn't pose any real problem.

One of the less convenient things about the GCC 4.3 series is that they require two external libraries: GMP and MPFR. Both are multiple precision math libraries. I won't pretend to have any idea on what they do or what they're used for, so I just accepted the fact that those were two dependencies to get first. Luckily both libraries are pretty much self contained and easy to port. The only thing I needed to do was to update the config.guess and config.sub scripts to a version that knew about Haiku as a target platform. The rest was the usual "configure; make; make check; make install". I configured them with just "--prefix=/boot/common" and they built and installed fine.

Encouraged by that smooth process I went on to GCC. The first questions come up right away when configuring. GCC has lots of configurable parameters and I wasn't really sure what to put there. Luckily I could just peek at how the cross-compiler scripts in the repository configured GCC 4.1.2. So I came up with "CFLAGS="-O2" CXXFLAGS="-O2" configure --prefix=/boot/develop/tools/gcc-4.3.2-haiku-090121 --target=i586-pc-haiku --disable-nls --disable-shared --enable-languages=c,c++" as my configure line. Yes, that's a configure invocation directly in the GCC source dir. Not really having any experience with this type of build system and of course only reading the (very good) configuration instructions after the fact, lead me to do the configure directly in the root source dir. The funny thing is that this little error later on would uncover a bug in libiberty that is now reported in the GCC bug tracker with a patch attached.

Since we are on platform "i586-pc-haiku" and are compiling a GCC for target "i586-pc-haiku" this means we're doing a native build. This also means that bootstrapping will be enabled resulting in a three step process: First a pseudo GCC is built that is a subset of a complete GCC just capable enough to actually build the full GCC. Through that process you don't actually compile GCC4 directly with your host compiler. This means that using our GCC 2.95.3 as host and more exotic compilers on other platforms just have to be able to build a working subset of GCC. This lessens the dependency on the host compiler and exposure to any potential issues in them.

The second so called "stage" is then to build a full GCC4 using the compiler built in stage 1. When creating a cross-compiler the process would end here. But since we're bootstrapping, there is a stage 3. Stage 3 essentially rebuilds the whole GCC4 again, this time using the compiler built in stage 2. This is to verify that the compiler that was built is actually able to build working programs. And this also explains why the process can't have a stage 3 for cross-compilers - if the compiler created in stage 2 is a cross-compiler creating binaries for other platforms you obviously can't use it to build a stage 3 compiler running on the host again. When the stage 3 compiler is built, the build system will verify that both compilers are valid. It does that by simply comparing the object files created by both stages. As both stage 2 and stage 3 compiler are built essentially by the same code, the resulting object files should be identical. If this verification passes, optional parts of the GCC4 package like the libstdc++ are built and the process is done - that's our goal.

I started out with a plain unzipped tree of GCC 4.3.2 (yep .2) sources. So before going anywhere I would need to actually port that GCC of course. Using the diff I had produced of GCC 4.1.2 this was pretty straight forward though. Some things have moved, but you could easily track them down.

Now I could start the whole process and it would actually get pretty far already. Some minor tweaks here and there and it would build the stage 1 compiler. This was the easy part, because now things started to go strange. Since the GCC built in stage 1 uses the config that you set up, you will notice misconfiguration when building the stage 2 compiler with it. And it seemed pretty misconfigured. First, things were found that weren't actually there and I started patching and changing ifdefs in some of the files. This was about when I really needed to go to bed and leaving it for that day. Thinking about it more and more while in bed and in the morning I came to the conclusion that this can't be it, that this would never create a proper patch and that there must be a root cause why things were failing this way. So instead of any further patching I started looking at the config.log to find out why configure would detect stuff that wasn't there. Now there are basically two things that are commonly done: 1. checking if a certain header/function/variable/define is present and 2. whether or not a certain symbol (function entry point in a library) is available. The checks that were looking for headers and prototypes did work. It does the checks by spitting out small source files and trying to compile them. So if you are looking for a header that isn't there compilation of the test program will just fail. The checks for available symbols however did not fail, the test programs simply compiled and linked.

That was when it became pretty obvious. Knowing from prior experinece that there was the option to allow or disallow missing symbols I figured that the configuration I set up would simply allow missing symbols. This meant that the test programs would compile and link, but wouldn't be able to run, because the stuff they refer to simply isn't in any library the system provides. This does however go unnoticed, because configure doesn't try to run the binaries, it simply checks if they compile and link. I then took a look at the specs and the theory turned out to be true, there was no -no-undefined present. BeOS did partially allow undefined symbols, that is they allowed undefined symbols in libraries but not in executables. This was done because they were linking their libraries with symbols not available at compile time. They were later runtime patched to be available. Some might remember the libroot.so.patch which patched the memset/memcpy to an optimized version depending on the CPU found. So -no-undefined was conditionally added for executables in the BeOS specs. Since we don't really want undefined symbols for Haiku, I've just added -no-undefined to the specs unconditionally. Should this later pose a problem, this can easily be changed in the sources or overridden in a custom specs file.

So with the updated builtin-specs I restarted the process, rebuilding much of the pseudo-gcc as well as starting the stage 2 compilation again. Now the configure looked much better, it only found what was there and I could remove all the hacks I've put in the different files. But of course this wasn't the only problem. Now it started with undefined stuff like "NAME_MAX" and "PATH_MAX". Anyone more or less familiar with the matter should now be able to tell: your limits.h is missing or messed up. And it was missing of course. I checked the diff and saw that there was an overridden variable for the test to find limits.h. For some reason I don't clearly remember I removed that line and replaced it with NATIVE_SYSTEM_HEADER_DIR instead. I think it was because the GCC build system tried to find the system headers in the default "/usr/include", which is of course not correct for Haiku. Anyway I got it working by moving some stuff around. Since I did all of that mostly during the timeframe I should have slept instead you have to bear with the fact that I wasn't always fully awake and don't remember all the details. After all they are pretty boring anyway.

So after the basic config was corrected I actually got the stage 2 compiler built. And since the stage 3 is essentially the same as stage 2, this one ran through equally well. This meant I finally had a native GCC 4.3.2 for Haiku. We're done, start the party! Ehm not quite of course. Having GCC 4.3.2 was of course a big step, but the real goal was to have a GCC4 Haiku running the GCC4 compiler natively. And I was still on GCC2 Haiku and since this wasn't even a hybrid build, the new GCC4 couldn't even compile anything runable that used C++.

Instead of party the goal now changed to get Haiku compiled with that new GCC. Since, as mentioned, we're on a non-hybrid GCC2 Haiku, the compiler can't be just dropped in as a replacement for GCC2. You still have to use GCC2 for compiling the host tools required by Haiku. This means setting up the Haiku build using GCC2 as the host compiler and just using the native GCC4 as if it was a cross-compiler. Since the Haiku build system supports such a setup, this was not very hard to do. But of course this is the latest point you could possibly notice that you forgot something. I didn't forget it, but mostly didn't care so far. Having GCC is by far not everything you need to build binaries. The only thing GCC does is it produces assembler output for the target architecture. It does that through the GCC frontend and it's language backends and a lot of optimization tricks and maybe a bit of black magic, but in the end it only produces assembler output. The rest of the process, meaning creating object files from that, archiving them into a static library or linking them into a binary is done by the binutils. The binutils are run as a separate project and provide the ld, as, ar, nm, objdump, ranlib and strip. It's the binutils that actually understand the ELF format for example. The good thing about the binutils being separate is that you can update them individually. Since I knew that we had more or less up to date binutils already (2.17) I was just lazy and instead of building the current version (2.19) I just copied the old ones into place so they could be used with the GCC4 I had set up.

So off you go with the Haiku build. But I didn't get very far. Of course Haiku was buildable with GCC 4.1.2, but we are updating two minor versions here. Many things have changed and especially many things have become more strict than in previous versions of GCC. So this meant that I wouldn't only have to update GCC and eventually the binutils, but that I would have to fix all the issues to make the Haiku tree compilable with the GCC 4.3 series as well. Luckily I've found porting guide explaining most of the issues I ran into and offering solutions. You can see the process in Haiku r28981 through r28995.

Success, I now got a bootable GCC 4.3.2 built Haiku. I've set it up to produce a hybrid build and then I was shutting down to go to the "other side" booting into the GCC4 Haiku. Just to add some emphasis to this, I did that whole process up to now in two sessions. I used Haiku to build a monster project, did update Haiku sources and checked them in while always reading webmail in Firefox, doing research to find solutions to the upcoming problems, chatting on #haiku and listening to music. All under Haiku, a still pre-alpha operating system. We're talking heavy workloads and uptimes of up to 20 hours here after all.

Surprisingly booting into that GCC4 installation worked out of the box. There have always been some stability issues with GCC4 built Haiku installations, so I didn't expect too much stability. But it turned out that besides three unexpected sudden reboots, things would go smoothly. Again we're talking uptimes of up to 20 hours. In principle I wouldn't have had to rebuild GCC4 again, because this thing is pure C code. So even though it was compiled on and for a GCC2 host, it wouldn't matter at all. Call me paranoid, but I still wanted to rebuild GCC4 on GCC4 just to make extra sure that we really have a fully native toolchain in the end. So I created a fresh unzipped tree and applied the patch I made for my final GCC 4.3.2 sources. Expecting to just start the process again and ending up with a proper fully native GCC4. After all this should pretty much exactly the situation of the stage 2 in the previous build, so why should it fail?

But of course it failed miserably. It failed even before compiling anything, because it claimed that the C compiler wasn't able to build binaries. Huh? OK, going through config.log it seemed as if the compiler toolchain wouldn't work. The C compiler backend "cc1" wasn't found. Tried to reproduce that testcase, I wasn't able to. It worked perfectly fine, with exactly that file. So, running a pre-alpha OS I started suspecting a problem with Haiku. Of course it was strange that this wouldn't turn up when compiling Haiku with exactly that compiler. So I was digging into the sources and added debug output here and there. Chatting with Rene Gollent we took appart some of the stuff that was going on. GCC claimed that it tried to execlv (I think) "cc1" but it didn't work. So we were looking through the whole path such a call takes. We didn't spot anything obvious. After a bit of more testing it turned out that exactly this test case would only fail when run inside the root source dir of GCC. Going through it systematically I copied over the files from that dir into a testbed and checked if it would still compile. It did. So I went on creating subdirectories analogous to the ones in the source tree. And there it was: as soon as there was a "gcc" directory, things would fail. Easy, the binary is called "gcc" and there is a subdir called "gcc", it must be that Haiku tries something executing "gcc" and thinks that directory is executable, which it is of course because the executable bit on directories means "traverse ok" and not "execute ok". But looking at the sources it was exactly this case that was handled! So the bug simply didn't seem to be in Haiku.

Then you have to work from the other side. I looked up what was actually called on the GCC side. And it really was "cc1" and exec. And it really couldn't find it, because it obviously wasn't in the source dir. After a bit of searching through the sources and trying to make sense of the things I saw I came to the conclusion that the prefix that was computed must simply be wrong. And tracking the prefix creation down I arrived at a pretty familiar block of code. The code looked almost exactly like the code in Haikus exec implementation. That's because it resolved the binary path using the PATH environment variable. But the difference was that exactly the directory case where X_OK is set but it's not a regular file at all wasn't handled. So this was a bug in libiberty which caused it to fail to resolve the path to the own gcc binary, making it unable to resolve the relative path to the "cc1" binary as well. Funnily I was only able to find that by doing the configure from the directory where you shouldn't do it at all. So I patched that, registered at the GCC bug tracker and submitted a bug with a diff. You can see it here, turns out another reported bug was reported that exhibited the same issue, but they didn't track it down to that problem yet.

Having this issue resolved, I was able to rebuild the whole GCC4 and build a fully native one. By that time the GCC folks released GCC 4.3.3, so I made a new diff, dumped my GCC 4.3.2 tree and started over again. Since Haiku hasn't really been optimized yet, we're talking build times of 3-4 hours here. Anyway I got it working straight from that patch again. This time I also wanted to get the current binutils, so I made a diff of the 2.17 binutils we had in the buildtools trunk and applied that (by hand, I like doing that because I can then more clearly see what's going on and if something nearby may need attention as well or if something can actually be left out). Binutils were friendly and built pretty much right away. So that really was a success. A native GCC 4.3.3 plus current binutils 2.19. I packaged it up, uploaded it and added it as an optional package ot Haiku.

The rest of the story was updating binutils and GCC in the Haiku buildtools repository through my totally crappy internet connection, a hundred attempts to fix configuration issues for the cross-compiler setup and finding issues that other platforms exhibited when building those tools. You can find that in the commits and in the bug tracker, so I'll refrain from prolonging this story.

Now we have a native, up to date GCC and the current binutils for Haiku. This should open up the door for a lot of exciting stuff. Ports of software that weren't feasible before because of using GCC2 and optimizations in Haiku that weren't available back then. Have fun!

Using the Haiku USB stack

Blog post by mmlr on Fri, 2007-04-20 08:30

This article contains outdated information, please read with caution.

Mainly in the second half of the last year the Haiku USB stack has matured a great deal. Not only has it stabilized a bit, it has also seen the addition of an EHCI driver to support USB 2.0 devices. A rewritten UHCI driver and a new implementation of the USBKit library are other steps to a complete stack.

The reason to write about that is the following: An increasing number of people apparently get interested in the progress of Haiku USB and they start to ask questions about the completeness and usability of the stack. Also whether and how to use the Haiku USB stack under R5 is an interesting question. Instead of telling the story individually it probably makes more sense to sum everything up in a post for everyone to read. I'll try to show what is currently implemented and working and where missing parts or possible problems could arise.

Here's an overview about everything USB that is available from Haiku:

  • The USB bus manager module(s) - They provide the unified interface to the USB from the driver perspective
  • The UHCI/OHCI/EHCI bus modules - Provide the hardware specific interface to the USB bus manager
  • The USBKit library and its raw driver - Provide an interface to use the USB from userspace
  • USB drivers - They use the USB bus manager or the USBKit to support specific devices

As you can see there is more to USB than just the busses or drivers. The good thing is that most of the parts are quite independent of Haiku and can be used under R5 and up as well. The components are mostly independent of each other too so that it's not an all or nothing thing if you want to profit from Haiku USB. I've split the following discussion into the parts that can be installed separately and list for each one what you can gain or lose by installing it and how to do it.

The USB stack

The stack alone only consist of two components, the bus manager and the bus modules. As mentioned above the bus manager is the module that provides the USB interface to the kernel level drivers. Actually the Haiku USB bus manager provides two modules, the "bus_managers/usb/v2" and the "bus_managers/usb/v3". Internally both use the same code and most of the v2 functions are mapped directly to the v3 functions. The two modules are provided so that drivers that were developed under R5 and use the v2 API can work beside drivers written for the newer v3 USB API of Dano and up. Both APIs are very similar in general. The biggest difference between the two is that the v3 API uses usb_ids to identify handels to internal stack objects instead of giving out direct pointers. This serves stability and eases debugging of stack and driver problems.

The bus modules namely UHCI, OHCI and EHCI can be counted to the USB stack as well. They are the parts that implement the hardware specific interfaces and provide things like the virtual root hub. The bus manager will search for these bus modules on bootup. Each one will initialize and register itself (if it finds supported hardware).

Pros and cons of installing

When you replace the R5 USB stack with the one from Haiku you can gain USB 2.0 support through the EHCI module. On the other hand you will lose support for OHCI as, at the time of this writing, the OHCI host controller driver is not yet implemented. That means if you have an OHCI controller installed and use low or fullspeed USB devices (mice or keyboards most of the time) you will not want to install the Haiku USB stack just yet. You can find out what devices are present in your system by using a command like "listdev | grep USB". This will list all the installed controllers in the format "PCI bus, device #_: Serial Bus Controller (USB) [c|3|x]", where x is the PCI class_api field indicating 0 = UHCI, 10 = OHCI or 20 = EHCI.

Also note that none of the bus modules currently support isochronous transfers. If you have working USB video or audio hardware (webcams, mics), it most likely uses isochronous transfers. Such devices would cease working when you switch to the Haiku USB stack.

Getting the binaries

See below if there are prebuilt packages for your platform. If not, you will need a checked out Haiku tree and the corresponding build tools to produce the binaries. From the base directory you can build the individual components for your platform by a command like "TARGET_PLATFORM=r5 jam usb \<usb\>ehci \<usb\>uhci". You need the backslashes to escape the less and greater than signs and you should replace the "r5" platform by "bone" or "dano" as required. This command should build the modules that can then be found under "generated/objects/<platform>/x86/release/add-ons/kernel/".

Installing the binaries

The first thing you should do before installing the new binaries is to archive the old ones. The original USB stack components can be found at "/boot/beos/system/add-ons/kernel/bus_managers/usb", "/boot/beos/system/add-ons/kernel/busses/usb/uhci" and "/boot/beos/system/add-ons/kernel/busses/usb/ohci". You need to move all of these files out of the add-ons tree and archive them in a zip somewhere.

You can now go to "generated/objects/<platform>/x86/release/add-ons/kernel/bus_managers/usb" and copy the "usb" bus manager module to "/boot/home/config/add-ons/kernel/bus_managers". Also the bus modules "uhci" and "ehci" need to be copied from "generated/objects/<platform>/x86/release/add-ons/kernel/busses/usb" to "/boot/home/config/add-ons/kernel/busses/usb". After that you can reboot and see if anything still works. I've been using this stack for months now without problems (or at least without problems I couldn't fix), but your system might just be unsupported. Be sure to leave a report in the comments or open a bug report if you encounter problems. If everything works you can of course leave a note too. If you are unable to boot after installing the new stack you should disable user add-ons in the bootmenu and then remove the binaries and move the old ones back in.

USB mass storage module

There is the USB mass storage module (or rather USB-SCSI bus module) that exposes mass storage protocol compliant USB devices as normal SCSI disk to the system. They can then be mounted or partitioned as normal drives.

Pros and cons of installing

The USB mass storage driver should bring you mountable USB memory sticks, working card readers and access to MP3 players if they use the USB Mass Storage protocol and are compliant enough. There shouldn't be any downsides when installing this module.

Getting the module

Use "TARGET_PLATFORM=<platform> jam usb_scsi" to generate the usb_scsi bus module. The built module can be found under "generated/objects/<platform>/x86/release/add-ons/kernel/busses/scsi/usb/".

Installing the module

If you have any other USB mass storage module installed currently you should first store it away to reduce the risk of problems. You can then go to "generated/objects/<platform>/x86/release/add-ons/kernel/busses/scsi/usb" and copy the "usb_scsi" module to "/boot/home/config/add-ons/kernel/busses/scsi". After a reboot you can try out your mass storage device and see if it works.

The Haiku USBKit

Haiku includes a rewritten USBKit implementation. It should be fully compatible with the existing implementations, but fixes some bugs and enables getting more information from some devices. If you are currently using the USBKit (i.e. the USBKit.a static library) you can try to replace the implementation you have with the one from Haiku. When you do this you should also install the usb_raw driver from Haiku.

Pros and cons of installing

If you are implementing software that uses the USB from userland you can profit from some fixes in the Haiku USBKit. As a normal user you should not really notice a difference in using a different usb_raw driver and you cannot change the USBKit that is used by software as it is linked in statically.

Getting the binaries

You can use "TARGET_PLATFORM=<platform> jam USBKit.a" to generate the USBKit static library. It will be placed into "generated/objects/<platform>/x86/release/libs/usb/". Use the "headers/libs/usb/USBKit.h" header from the Haiku tree with this library. Most of the functionality the library provides is documented in that header file.

Note that you will also need the usb_raw driver for the USBKit to work. It is encouraged that you use the Haiku usb_raw driver with the Haiku USBKit, but it is not mandatory. The Haiku USBKit should work with the older usb_raw drivers from Be as well. To build the Haiku driver use "TARGET_PLATFORM=<platform> jam usb_raw" which will place the driver into "objects/<platform>/x86/release/add-ons/kernel/drivers/bus/usb/".

Installing the driver

Installing the usb_raw driver is as easy as copying it from "objects/<platform>/x86/release/add-ons/kernel/drivers/bus/usb/" to "/boot/home/config/add-ons/kernel/drivers/bin" and creating a link to it in "/boot/home/config/add-ons/kernel/drivers/dev/bus/usb". You can verify that the driver is installed correctly by "ls /dev/bus/usb" you should then see some numbers and the "raw" entry.

Other USB drivers

There are other USB drivers in the Haiku tree that could just be useful to you. There is the usb_hid driver and things like usb_midi. I don't know how well they will work if they build for R5 at all as I didn't test them. You will have to try and see for yourself here. For other non Haiku USB drivers you should be able to install them as normal. Usually you will have to put them under "/boot/home/config/add-ons/kernel/drivers/bin". They should work with the Haiku USB stack the same as before. If they don't please let me know.

Prebuilt packages

There are packages available with the Haiku USB stack and mass storage module as well as a standalone source package with the Haiku USBKit. These will only work with R5 or BONE installations respectively. The USBKit source archive includes a makefile that should build a USBKit.a that can then be used with the included USBKit.h header. To install one of the binary packages make sure you follow the steps above to archive your existing USB stack and mass storage module. Then unpack the package to "/boot/home" this will put the binaries at the right place. The USBKit sources can be unpacked and used anywhere.

Problems and Bugs

If you encounter problems with the Haiku USB stack please open a bug report at our bug tracker. When making a bug report please try to be as specific as possible and include syslog output, hardware configuration and other information that might be relevant for finding the problem at hand.

Syndicate content