Friday, June 26, 2015
Oz 0.14.0 Release
All,
I'm pleased to announce release 0.14.0 of Oz. Oz is a program for doing automated installation of guest operating systems with limited input from the user. Release 0.14.0 is a bugfix and feature release for Oz. Some of the highlights between Oz 0.13.0 and 0.14.0 are:
Fix a bug in checksum checking (this should work again)
Add a global lock around pool refresh; should get rid of a user-visible failure
Support for Debian 8
Support for Ubuntu 15.04
Support for Fedora 22
Support for installing aarch64 guests
Support for installing POWER guests
Support for install arm 32-bit guests
A tarball and zipfile of this release is available on the Github releases page: https://github.com/clalancette/oz/releases . Packages for Rawhide, Fedora-21, Fedora-22, EPEL-7, and EPEL-6 have been built in Koji and will eventually make their way to stable. Instructions on how to get and use Oz are available at http://github.com/clalancette/oz/wiki .
If you have questions or comments about Oz, please feel free to contact me at clalancette at gmail.com, or open up an issue on the github page: http://github.com/clalancette/oz/issues .
Thanks to everyone who contributed to this release through bug reports, patches, and suggestions for improvement.
Saturday, March 7, 2015
Oz 0.13.0 release
I'm pleased to announce release 0.13.0 of Oz. Oz is a program
for doing automated installation of guest operating systems with
limited input from the user. Release 0.13.0 is a bugfix and feature
release for Oz. Some of the highlights between Oz 0.12.0 and 0.13.0
are:
- For Fedora, if the user specifies a version, but that isn't supported yet, try the last supported version (in this case), as that will often work.
- Fix a regression where we forgot to force the qcow2 image type
- Allow installs that use more than one installation device
- Add support for RHEL 6.5
- Rename OEL-6 to OL-6
- Add support for Ubuntu 14.04
- Add Windows 8.1 support
- Add CentOS-7 support
- Add the ability to specify kernel parameters in the TDL
- Make sure to remove dhcp leases from guests after the install
- Fix support for FreeBSD
- Add in support for TDL "precommands"; these are commands that are run *before* package installation
- Fix up file locking
- Add support for RHEL 5.11
- Remove Ubuntu ssh keys at the end of installation
- Add support for Ubuntu 14.10
- Add support for XInclude, for merging various TDLs together
- Add Fedora 21 support
- Add support for ppc64 and ppc64le
Wednesday, January 15, 2014
Developing STM32 microcontroller code on Linux (Part 7 of 8, building and running a simple STM32 program)
The first post of this series covered the steps to build and run code for the STM32. The second post covered how to build a cross-compiler for the STM32. The third post covered how to build a debugger for the STM32. The fourth post covered building and configuring OpenOCD for your development environment. The fifth post covered building the device library, libopencm3. The sixth post covered linker scripts and command-line options necessary for building and linking programs to run on the STM32. This post will cover building and running a program on the STM32.
In the previous posts we dealt with all of the set up necessary to build programs for the STM32. It is finally time to take advantage of all of those tools and build and run something. Recall that from previous posts, we already have an OpenOCD configuration file setup, a linker script setup, and a Makefile setup. All that really remains is for us to write the code, build it, and flash it to our device. The code below is very STM32F3DISCOVERY specific; that is, it very much requires that the GPIO for the LED be on GPIO bank E, pin 12 on the board. If you have one of the other STM32 DISCOVERY boards, you'll need to look at the schematics and find one of the GPIOs that are hooked to an LED.
We are going to take an extremely simple example from libopencm3. This example does nothing more than blink one of the LEDs on the board on and off continuously. While this is simple, it will validate that everything that we've done before is actually correct.
Here is the code:
In the previous posts we dealt with all of the set up necessary to build programs for the STM32. It is finally time to take advantage of all of those tools and build and run something. Recall that from previous posts, we already have an OpenOCD configuration file setup, a linker script setup, and a Makefile setup. All that really remains is for us to write the code, build it, and flash it to our device. The code below is very STM32F3DISCOVERY specific; that is, it very much requires that the GPIO for the LED be on GPIO bank E, pin 12 on the board. If you have one of the other STM32 DISCOVERY boards, you'll need to look at the schematics and find one of the GPIOs that are hooked to an LED.
We are going to take an extremely simple example from libopencm3. This example does nothing more than blink one of the LEDs on the board on and off continuously. While this is simple, it will validate that everything that we've done before is actually correct.
Here is the code:
$ cd ~/stm32-project
$ cat <<EOF > tut.c
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
static void gpio_setup(void)
{
/* Enable GPIOE clock. */
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_IOPEEN);
/* Set GPIO12 (in GPIO port E) to 'output push-pull'. */
gpio_mode_setup(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,
GPIO12);
}
int main(void)
{
int i;
gpio_setup();
/* Blink the LED (PC8) on the board. */
while (1) {
/* Using API function gpio_toggle(): */
gpio_toggle(GPIOE, GPIO12); /* LED on/off */
for (i = 0; i < 2000000; i++) /* Wait a bit. */
__asm__("nop");
}
return 0;
}
EOF
You should now be able to type "make", and the thing should build. Typing "make flash" should run OpenOCD, install the program to the board, and start blinking an LED. Remember that our Makefile required sudo access to actually run openocd. If you don't have sudo access, you can either add sudo access (by adding your user to the wheel group), or just su to root and run the openocd command by hand.
Labels:
C,
cross compile,
linux,
microcontroller,
open source,
stm32
Monday, January 13, 2014
Developing STM32 microcontroller code on Linux (Part 6 of 8, building and linking STM32 programs)
The first post of this series covered the steps to build and run code for the STM32. The second post covered how to build a cross-compiler for the STM32. The third post covered how to build a debugger for the STM32. The fourth post covered building and configuring OpenOCD for your development environment. The fifth post covered building the device library, libopencm3. This post will cover linker scripts and command-line options necessary for building and linking programs to run on the STM32.
Once we have all of the previous steps done, we are achingly close to being able to build and run code on our target STM32 processor. However, there is one more set of low-level details that we have to understand before we can get there. Those details revolve around how our C code gets turned into machine code, and how that code is laid out in memory.
As you may know, compiling code to run on a target is roughly a two-step process:
To do this, we use our cross-compiler. As with any version of gcc, there are many flags that can be passed to our cross-compiler, and they can have many effects on the code that is output. What I'm going to present here is a set of flags that I've found works pretty well. This isn't necessarily optimal in any dimension, but will at least serve as a starting point for our code. I'll also point out that this is where we start to get into the differences between the various STM32F* processors. For instance, the STM32F4 processor has an FPU, while the STM32F3 does not. This will affect the flags that we will pass to the compiler.
For the STM32F3, Cortex-M3 processor that I am using, here are the compiler flags:
Let's go through each of them. The -W* flags tell the compiler to generate compile-time warnings for several classes of common errors. I find that enabling these warnings and getting rid of them usually makes the code much better. The -g flag tells the compiler to include debugging symbols in the binary; this makes the code easier to debug, at the expense of some code space. The -fno-common flag tells gcc to place uninitialized global variables into the data section of the binary, which improves performance a bit. The -mcpu=cortex-m3 flag tells the compiler that we have a Cortex-M3, and thus to generate code optimized for the Cortex-M3. The -mthumb flag tells gcc to generate ARM thumb code, which is smaller and more compact than full ARM code. The -mfloat-abi=hard flag tells gcc that we want to use a hard float ABI; this doesn't make a huge difference on a processor without an FPU, but is a good habit to get into. Finally, the -MD flag tells gcc to generate dependency files while compiling, which is useful for Makefiles.
We'll first start by talking about the flags that we need to pass to the linker to make this work. Here are the set of flags we are going to start with:
Again, let's go through each of them. The --static flag tells the linker to link a static, not a dynamically linked, binary. This flag probably isn't strictly necessary in this case, but we add it anyway. The -lc flag tells the linker to link this binary against the C library, which is newlib in our case. That gives us access to various convenient functions, such as printf(), scanf(), etc. The -lnosys flag tells the linker to link this binary against the "nosys" library. Several of the convenience functions in the C library require underlying implementations of certain functions to operate, such as _write() for printf(). Since we don't have a POSIX operating system that can provide these for us, the nosys library provides empty stub functions for these. If we want, we can later on define our own versions of these stub functions that will get used instead. The -T tut.ld flag tells the linker to use tut.ld as the linker script; we'll talk more about linker scripts below. The -nostartfiles flag tells the linker not to use standard system startup files. Since we don't have an OS here, we can't rely on the standard OS utilities to start our program up. The -Wl,--gc-sections flag tells the linker to garbage collect unused sections. That is, any sections that are not referenced are removed from the resulting binary, which can shrink the binary. The -mcpu=cortex-m3, -mthumb, and -mfloat-abi=hard flags have the same meaning as for the compile flags. The -lm flag tells the linker to link this binary against the math library. It isn't strictly required for our little programs, but most programs want it sooner or later. Finally, the -Wl,-Map=tut.map tells the linker to generate a map file and stick it into tut.map. The map file is helpful for debugging, but is informational only.
With all that said, libopencm3 actually makes this easy on you. They have default linker scripts for each of the chips that are supported. All you really need to do is to fill in a small linker script with the RAM and FLASH size of your chip, include the default libopencm3 one, and away you go.
So we are going to put all of the above together and write a Makefile and a linker script into the project directory we created in the last tutorial. Neither of these are necessarily the best examples of what to do, but they will get the job done. First the Makefile:
Now the linker script:
We now have all of the parts in place. The next post will write, compile, and run a simple program on the board.
Once we have all of the previous steps done, we are achingly close to being able to build and run code on our target STM32 processor. However, there is one more set of low-level details that we have to understand before we can get there. Those details revolve around how our C code gets turned into machine code, and how that code is laid out in memory.
As you may know, compiling code to run on a target is roughly a two-step process:
- Turn C/C++ code into machine code the target processor understands. The output of this step are what are known as object files.
- Take the object files and link them together to form a coherent binary. The output of this step is generally an ELF file.
Compile step
During compilation, the compiler parses the C/C++ code and turns it into an object file. A little more concretely, what we want to have our cross-compiler do is to take our C code, turn it into ARM instructions that can run on the STM32, and then output that into object files.To do this, we use our cross-compiler. As with any version of gcc, there are many flags that can be passed to our cross-compiler, and they can have many effects on the code that is output. What I'm going to present here is a set of flags that I've found works pretty well. This isn't necessarily optimal in any dimension, but will at least serve as a starting point for our code. I'll also point out that this is where we start to get into the differences between the various STM32F* processors. For instance, the STM32F4 processor has an FPU, while the STM32F3 does not. This will affect the flags that we will pass to the compiler.
For the STM32F3, Cortex-M3 processor that I am using, here are the compiler flags:
-Wall -Wextra -Wimplicit-function-declaration -Wredundant-decls -Wstrict-prototypes -Wundef -Wshadow -g -fno-common -mcpu=cortex-m3 -mthumb -mfloat-abi=hard -MD
Let's go through each of them. The -W* flags tell the compiler to generate compile-time warnings for several classes of common errors. I find that enabling these warnings and getting rid of them usually makes the code much better. The -g flag tells the compiler to include debugging symbols in the binary; this makes the code easier to debug, at the expense of some code space. The -fno-common flag tells gcc to place uninitialized global variables into the data section of the binary, which improves performance a bit. The -mcpu=cortex-m3 flag tells the compiler that we have a Cortex-M3, and thus to generate code optimized for the Cortex-M3. The -mthumb flag tells gcc to generate ARM thumb code, which is smaller and more compact than full ARM code. The -mfloat-abi=hard flag tells gcc that we want to use a hard float ABI; this doesn't make a huge difference on a processor without an FPU, but is a good habit to get into. Finally, the -MD flag tells gcc to generate dependency files while compiling, which is useful for Makefiles.
Linking step
Once all of the individual files have been compiled, they are put together into the final binary by the linker. This is more complicated when targeting an embedded platform vs. a regular program. In particular, we have to tell the linker not only which files to link together, but also how to lay the resulting binary out on flash and in memory.We'll first start by talking about the flags that we need to pass to the linker to make this work. Here are the set of flags we are going to start with:
--static -lc -lnosys -T tut.ld -nostartfiles -Wl,--gc-sections -mcpu=cortex-m3 -mthumb -mfloat-abi=hard -lm -Wl,-Map=tut.map
Again, let's go through each of them. The --static flag tells the linker to link a static, not a dynamically linked, binary. This flag probably isn't strictly necessary in this case, but we add it anyway. The -lc flag tells the linker to link this binary against the C library, which is newlib in our case. That gives us access to various convenient functions, such as printf(), scanf(), etc. The -lnosys flag tells the linker to link this binary against the "nosys" library. Several of the convenience functions in the C library require underlying implementations of certain functions to operate, such as _write() for printf(). Since we don't have a POSIX operating system that can provide these for us, the nosys library provides empty stub functions for these. If we want, we can later on define our own versions of these stub functions that will get used instead. The -T tut.ld flag tells the linker to use tut.ld as the linker script; we'll talk more about linker scripts below. The -nostartfiles flag tells the linker not to use standard system startup files. Since we don't have an OS here, we can't rely on the standard OS utilities to start our program up. The -Wl,--gc-sections flag tells the linker to garbage collect unused sections. That is, any sections that are not referenced are removed from the resulting binary, which can shrink the binary. The -mcpu=cortex-m3, -mthumb, and -mfloat-abi=hard flags have the same meaning as for the compile flags. The -lm flag tells the linker to link this binary against the math library. It isn't strictly required for our little programs, but most programs want it sooner or later. Finally, the -Wl,-Map=tut.map tells the linker to generate a map file and stick it into tut.map. The map file is helpful for debugging, but is informational only.
Linker script
As mentioned before, the linker script tells the linker how to lay out the resulting binary in memory. This script is highly chip specific. The details have to do with where the processor jumps to on reset, and where it expects certain things to be. Note that most chips are actually configurable (based on some jumper settings), so where it jumps to on reset can change. Luckily, for most off-the-shelf STM32 designs, including the DISCOVERY boards, it is always configured to expect the code to start out in flash. Therefore, the linker script tells the linker to lay out the code in flash, but to put the data and bss in RAM.With all that said, libopencm3 actually makes this easy on you. They have default linker scripts for each of the chips that are supported. All you really need to do is to fill in a small linker script with the RAM and FLASH size of your chip, include the default libopencm3 one, and away you go.
So we are going to put all of the above together and write a Makefile and a linker script into the project directory we created in the last tutorial. Neither of these are necessarily the best examples of what to do, but they will get the job done. First the Makefile:
$ cd ~/stm32-project
$ cat <<EOF > Makefile
CC=arm-none-eabi-gcc
LD=\$(CC)
OBJCOPY=arm-none-eabi-objcopy
OPENOCD=~/opt/cross/bin/openocd
CFLAGS=-Wall -Wextra -Wimplicit-function-declaration -Wredundant-decls -Wstrict-prototypes -Wundef -Wshadow -g -fno-common -mcpu=cortex-m3 -mthumb -mfloat-abi=hard -MD -DSTM32F3
LDFLAGS=--static -lc -lnosys -T tut.ld -nostartfiles -Wl,--gc-sections -mcpu=cortex-m3 -mthumb -mfloat-abi=hard -lm -Wl,-Map=tut.map
OBJS=tut.o
all: tut.bin
tut.bin: tut.elf
$( echo -e "\t" )\$(OBJCOPY) -Obinary tut.elf tut.bin
tut.elf: \$(OBJS)
$( echo -e "\t" )\$(CC) -o tut.elf \$(OBJS) ~/opt/cross/arm-none-eabi/lib/libopencm3_stm32f3.a --static -lc -lnosys -T tut.ld -nostartfiles -Wl,--gc-sections -mcpu=cortex-m3 -mthumb -mfloat-abi=hard -lm -Wl,-Map=tut.map
flash: tut.bin
$( echo -e "\t" )sudo \$(OPENOCD) -f stm32-openocd.cfg -c "init" -c "reset init" -c "flash write_image erase tut.bin 0x08000000" -c "reset run" -c "shutdown"
clean:
$( echo -e "\t")rm -f *.elf *.bin *.list *.map *.o *.d *~
EOF
You should notice a couple of things in the Makefile. First, we use all of the compiler and linker flags that we talked about earlier. Second, our objects ($OBJS) are tut.c, which we'll create in the next post. And third, we have a flash target that will build the project and flash it onto the target processor. This requires the OpenOCD configuration file that we created a couple of posts ago.Now the linker script:
$ cat <<EOF > tut.ld
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 40K
}
/* Include the common ld script. */
INCLUDE libopencm3_stm32f3.ld
EOF
You'll notice that there isn't a lot here. We just have to define the RAM location and size, and the ROM (Flash) location and size, and the default libopencm3 linker script will take care of the rest.We now have all of the parts in place. The next post will write, compile, and run a simple program on the board.
Labels:
C,
cross compile,
ld,
linker scripts,
linux,
microcontroller,
open source,
stm32
Friday, January 10, 2014
Developing STM32 microcontroller code on Linux (Part 5 of 8, building libopencm3)
The first post of this series covered the steps to build and run code for the STM32. The second post covered how to build a cross-compiler for the STM32. The third post covered how to build a debugger for the STM32. The fourth post covered building and configuring OpenOCD for your development environment. This post will cover building the device library, libopencm3.
As mentioned in the introductory post, it makes our life a lot easier if we use a device library. This is a library that abstracts the low-level details of the hardware registers away from us, and gives us a nice consistent API to use. While ST provides one these directly, it is not open-source (or more specifically, it's open-source status is murky). Luckily there is libopencm3, an open-source re-implementation that is also a better library in my opinion. As usual, I'm going to compile a certain version of libopencm3; newer or later versions may or may not work better for you.
As before, we start out by exporting some environment variables:
Now that we have our environment set up, we can get the code. Note that unlike most of the other tools covered in this tutorial, libopencm3 does not do releases. They expect (more specifically, require) that you clone the latest version and use that. That's what we are going to do here. As of this writing, the latest libopencm3 git hash tag is a909b5ca9e18f802e3caef19e63d38861662c128. Since the libopencm3 developers don't guarantee API stability, all of the steps below will assume the API as of that hash tag. If you decide to use a newer version of libopencm3, you may have to update the example code I give you to conform to the new API. With that out of the way, let's get it:
As mentioned in the introductory post, it makes our life a lot easier if we use a device library. This is a library that abstracts the low-level details of the hardware registers away from us, and gives us a nice consistent API to use. While ST provides one these directly, it is not open-source (or more specifically, it's open-source status is murky). Luckily there is libopencm3, an open-source re-implementation that is also a better library in my opinion. As usual, I'm going to compile a certain version of libopencm3; newer or later versions may or may not work better for you.
As before, we start out by exporting some environment variables:
$ export TOPDIR=~/cross-src
$ export TARGET=arm-none-eabi
$ export PREFIX=~/opt/cross
$ export BUILDPROCS=$( getconf _NPROCESSORS_ONLN )
$ export PATH=$PREFIX/bin:$PATH
The TOPDIR environment variable is the directory in which the sources are stored. The TARGET environment variable is the architecture that we want our compiler to emit code for. For ARM chips without an operating system (like the STM32), we want arm-none-eabi. The PREFIX environment variable is the location we want our cross-compile tools to end up in; feel free to change this to something more suitable. The BUILDPROCS environment variable is the number of processors that we can use; we will use all of them while building to substantially speed up the build process. Finally, we need to add the location of the cross-compile binaries to our PATH so that later building stages can find it.
Now that we have our environment set up, we can get the code. Note that unlike most of the other tools covered in this tutorial, libopencm3 does not do releases. They expect (more specifically, require) that you clone the latest version and use that. That's what we are going to do here. As of this writing, the latest libopencm3 git hash tag is a909b5ca9e18f802e3caef19e63d38861662c128. Since the libopencm3 developers don't guarantee API stability, all of the steps below will assume the API as of that hash tag. If you decide to use a newer version of libopencm3, you may have to update the example code I give you to conform to the new API. With that out of the way, let's get it:
$ sudo yum install git
$ cd $TOPDIR
$ git clone git://github.com/libopencm3/libopencm3.git
$ cd libopencm3
$ git checkout -b clalancette-tutorial \
a909b5ca9e18f802e3caef19e63d38861662c128
What we've done here is to clone the repository, then checkout a new branch with the head at hash a909b5ca9e18f802e3caef19e63d38861662c128. This ensures that even if the library moves forward in the future, we will always use that hash tag for the purposes of this tutorial. Next we build the library:
$ unset PREFIX
$ make DETECT_TOOLCHAIN=1
$ make DETECT_TOOLCHAIN=1 install
$ export PREFIX=~/opt/cross
Here we need to unset PREFIX because libopencm3 uses PREFIX for the toolchain name prefix (arm-none-eabi), not the path prefix. Once we've done that, we can tell libopencm3 to detect the toolchain, and then use it to build libopencm3. Finally we use the install target to install the headers and the static libraries (.a files) to our toolchain. Assuming this is successful, everything necessary should be in ~/opt/cross/arm-none-eabi/, with the libraries in lib/libopencm3* and the header files in include/libopencm3. Note that there is one .a file per chip that is supported by libopencm3; we'll return to this later when we start building code for our chip.
Labels:
C,
cross compile,
libopencm3,
linux,
microcontroller,
open source,
stm32
Thursday, January 9, 2014
Developing STM32 microcontroller code on Linux (Part 4 of 8, building openocd)
The first post of this series covered the steps to build and run code for the STM32. The second post covered how to build a cross-compiler for the STM32. The third post covered how to build a debugger for the STM32. This post is going to cover building OpenOCD for your development environment.
As mentioned in the introductory post, we need OpenOCD so we can take binaries that we build and upload them onto the STM32. OpenOCD is a highly configurable tool and understands a number of different protocols. For our purposes, we really only need it to understand STLinkV2, which is what the STM32 uses. Also note that unlike previous posts, this post does not need or build a cross-compiled tool. That's because OpenOCD itself runs on our development machine, so we just need to do a normal compile. As before, I'm going to compile a certain version of OpenOCD (0.7.0). Newer or older versions may work, but your mileage may vary.
As before, we start out by exporting some environment variables:
Now we are ready to start. Let's fetch openocd:
Assuming everything went properly, we should now have a openocd binary in ~/opt/cross/bin. There will also be a bunch of configuration files installed to ~/opt/cross/share/openocd. These are important as these are pre-canned configuration files provided by OpenOCD. While it is possible to create your own from scratch, the syntax is baroque and it is a lot more work than you would think. Luckily OpenOCD already comes with scripts for STLinkV2 and STM32, so we'll just use those.
In order to have a working configuration, we are going to start creating our "project" directory. This is where the code that eventually runs on the STM32 is going to be placed. I'm going to call my directory ~/stm32-project; feel free to change it for your project. So we do:
That's it for OpenOCD. Everything should be built, configured, and ready to go.
As mentioned in the introductory post, we need OpenOCD so we can take binaries that we build and upload them onto the STM32. OpenOCD is a highly configurable tool and understands a number of different protocols. For our purposes, we really only need it to understand STLinkV2, which is what the STM32 uses. Also note that unlike previous posts, this post does not need or build a cross-compiled tool. That's because OpenOCD itself runs on our development machine, so we just need to do a normal compile. As before, I'm going to compile a certain version of OpenOCD (0.7.0). Newer or older versions may work, but your mileage may vary.
As before, we start out by exporting some environment variables:
$ export TOPDIR=~/cross-src
$ export TARGET=arm-none-eabi
$ export PREFIX=~/opt/cross
$ export BUILDPROCS=$( getconf _NPROCESSORS_ONLN )
$ export PATH=$PREFIX/bin:$PATH
The TOPDIR environment variable is the directory in which the sources are stored. The TARGET environment variable is the architecture that we want our compiler to emit code for. For ARM chips without an operating system (like the STM32), we want arm-none-eabi. The PREFIX environment variable is the location we want our cross-compile tools to end up in; feel free to change this to something more suitable. The BUILDPROCS environment variable is the number of processors that we can use; we will use all of them while building to substantially speed up the build process. Finally, we need to add the location of the cross-compile binaries to our PATH so that later building stages can find it.
Now we are ready to start. Let's fetch openocd:
$ cd $TOPDIR
$ wget http://downloads.sourceforge.net/project/openocd/\
openocd/0.7.0/openocd-0.7.0.tar.gz
To start the compile, we first need to install a dependency:
$ sudo yum install libusbx-devel
Now let's unpack and build openocd:
$ tar -xvf openocd-0.7.0.tar.gz
$ cd openocd-0.7.0
$ ./configure --enable-stlink --prefix=$PREFIX
$ make
$ make install
Here we are unpacking, configuring, building, and installing OpenOCD. The configure flags require a bit of explanation. The --enable-stlink flag means to enable support for STLink and STLinkV2, which is what we need for this board. The --prefix flag tells the build system to install OpenOCD to our ~/opt/cross location. This isn't strictly correct; this isn't a cross compile tool. However, it is convenient to have everything in one place, so we install it there.
Assuming everything went properly, we should now have a openocd binary in ~/opt/cross/bin. There will also be a bunch of configuration files installed to ~/opt/cross/share/openocd. These are important as these are pre-canned configuration files provided by OpenOCD. While it is possible to create your own from scratch, the syntax is baroque and it is a lot more work than you would think. Luckily OpenOCD already comes with scripts for STLinkV2 and STM32, so we'll just use those.
In order to have a working configuration, we are going to start creating our "project" directory. This is where the code that eventually runs on the STM32 is going to be placed. I'm going to call my directory ~/stm32-project; feel free to change it for your project. So we do:
$ mkdir ~/stm32-project
$ cd ~/stm32-project
$ cat <<EOF > stm32-openocd.cfg
source [find interface/stlink-v2.cfg]
source [find target/stm32f3x_stlink.cfg]
reset_config srst_only srst_nogate
EOF
Here we create the project directory, cd into it, and then create the configuration file for OpenOCD. The configuration file deserves a bit of explanation. First, we tell it to "find" the stlink-v2.cfg configuration file. Where it looks depends on the PREFIX we configured, so in our case it is going to look through ~/opt/cross/share/openocd for that file (where it should find it). Next we tell OpenOCD to "find" the stm32f3x_stlink.cfg file. Again, that file is located in ~/opt/cross/share/openocd, and it again should find it. Note that if you have a different STM32 chip, you should substitute f3x with whatever version of the chip you have. Finally there is a line about reset_config srst_only, and srst_nogate. I honestly don't know what those are for, though they seem to be necessary.
That's it for OpenOCD. Everything should be built, configured, and ready to go.
Labels:
C,
cross compile,
linux,
microcontroller,
open source,
openocd,
stm32
Wednesday, January 8, 2014
Release of ruby-libvirt 0.5.2
This is a release notification for ruby-libvirt 0.5.2. ruby-libvirt is a ruby wrapper around the libvirt API. The changelog between 0.5.1 and 0.5.2 is:
Tarball: http://libvirt.org/ruby/download/ruby-libvirt-0.5.2.tgz
Gem: http://libvirt.org/ruby/download/ruby-libvirt-0.5.2.gem
It is also available from rubygems.org; to get the latest version, run:
As usual, if you run into questions, problems, or bugs, please feel free to mail me (clalancette@gmail com) and the libvirt mailing list.
Thanks to Guido Günther for the patch to fix this problem.
- Fix to make sure we don't free more entries than retrieved (potential crash)
Tarball: http://libvirt.org/ruby/download/ruby-libvirt-0.5.2.tgz
Gem: http://libvirt.org/ruby/download/ruby-libvirt-0.5.2.gem
It is also available from rubygems.org; to get the latest version, run:
$ gem install ruby-libvirt
As usual, if you run into questions, problems, or bugs, please feel free to mail me (clalancette@gmail com) and the libvirt mailing list.
Thanks to Guido Günther for the patch to fix this problem.
Developing STM32 microcontroller code on Linux (Part 3 of 8, building gdb)
The first post of this series covered the steps to build and run code for the STM32. The second post covered how to build a cross-compiler for the STM32. This post is going to cover how to build a debugger for the STM32.
Building a debugger isn't strictly necessary for developing on the STM32. However it can make certain debugging tasks easier, and it is relatively simple to do, so we'll do it here. As with the tools in the last post, the version of gdb used (7.6) worked for me. Your mileage may vary. If you fail to cross-compile gdb, then try a slightly newer or older version and try again on your development setup. If you can't build gdb, you can safely skip this step, though you may run into some problems later.
To build gdb, we'll assume you installed the tools to the path from the last post. If you changed path, you'll have to edit the PREFIX path below.
As before, we start out by exporting some environment variables:
Next we'll download, unpack, and build gdb:
Building a debugger isn't strictly necessary for developing on the STM32. However it can make certain debugging tasks easier, and it is relatively simple to do, so we'll do it here. As with the tools in the last post, the version of gdb used (7.6) worked for me. Your mileage may vary. If you fail to cross-compile gdb, then try a slightly newer or older version and try again on your development setup. If you can't build gdb, you can safely skip this step, though you may run into some problems later.
To build gdb, we'll assume you installed the tools to the path from the last post. If you changed path, you'll have to edit the PREFIX path below.
As before, we start out by exporting some environment variables:
$ export TOPDIR=~/cross-src
$ export TARGET=arm-none-eabi
$ export PREFIX=~/opt/cross
$ export BUILDPROCS=$( getconf _NPROCESSORS_ONLN )
$ export PATH=$PREFIX/bin:$PATH
The TOPDIR environment variable is the directory in which the sources are stored. The TARGET environment variable is the architecture that we want our compiler to emit code for. For ARM chips without an operating system (like the STM32), we want arm-none-eabi. The PREFIX environment variable is the location we want our cross-compile tools to end up in; feel free to change this to something more suitable. The BUILDPROCS environment variable is the number of processors that we can use; we will use all of them while building to substantially speed up the build process. Finally, we need to add the location of the cross-compile binaries to our PATH so that later building stages can find it.
Next we'll download, unpack, and build gdb:
$ cd $TOPDIR
$ wget ftp://ftp.gnu.org/gnu/gdb/gdb-7.6.tar.gz
$ tar -xvf gdb-7.6.tar.gz
$ mkdir build-gdb
$ cd build-gdb
$ ../gdb-7.6/configure --target=$TARGET --prefix=$PREFIX \
--enable-interwork
$ make -j$BUILDPROCS
$ make install
We download gdb, unpack it, then configure and build it. The flags to configure deserve some explanation. The --target flag tells gdb what target you want the tools to build for; that is, what kind of code will be emitted by the code. In our case, we want ARM with no operating system. The --prefix flag tells gdb that we want our debugger to be installed to $PREFIX. The --enable-interwork flag allows binutils to emit a combination of ARM and THUMB code; if you don't know what that is, don't worry about it for now. Assuming this step went fine on your development machine, there should be a binary in ~/opt/cross/bin (or whatever your top-level output directory is) called arm-none-eabi-gdb.
Labels:
C,
cross compile,
gdb,
linux,
microcontroller,
open source,
stm32
Tuesday, January 7, 2014
Developing STM32 microcontroller code on Linux (Part 2 of 8, building the cross-compiler)
The first post of this series covered the steps to build and run code for the STM32. This post is going to cover how to build a cross-compiler for the STM32.
The steps to build a cross-compiler are somewhat covered here and here. In theory, building a cross-compiler is a pretty straightforward process:
Now onto the steps needed to build the cross compiling environment. We first need to make sure certain tools are installed. We'll install the development tools through yum:
Now we can start building. We first need to build binutils:
With binutils built, we can now move on to gcc:
With the initial compiler built, we can now build newlib:
With newlib built, we can now go back and finish the build of gcc (the last step!):
Update Jan 8, 2014: Updated the formatting so it is more readable.
The steps to build a cross-compiler are somewhat covered here and here. In theory, building a cross-compiler is a pretty straightforward process:
- Cross compile binutils, to get things like as (assembler), ld (linker), nm (list object symbols), etc.
- Cross compile gcc, which gives you a C and C++ compiler.
- Cross compile newlib, which gives you a minimal libc-like environment to program in.
Now onto the steps needed to build the cross compiling environment. We first need to make sure certain tools are installed. We'll install the development tools through yum:
$ sudo yum install gcc make tar wget bzip2 gmp-devel \
mpfr-devel libmpc-devel gcc-c++ texinfo ncurses-devel
Next we fetch the relevant versions of the packages:
$ mkdir ~/cross-src
$ cd ~/cross-src
$ wget ftp://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.gz
$ wget ftp://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.bz2
$ wget ftp://sources.redhat.com/pub/newlib/newlib-2.0.0.tar.gz
Next we set some environment variables. This isn't strictly necessary, but will help us reduce errors in the following steps:
$ export TOPDIR=~/cross-src
$ export TARGET=arm-none-eabi
$ export PREFIX=~/opt/cross
$ export BUILDPROCS=$( getconf _NPROCESSORS_ONLN )
$ export PATH=$PREFIX/bin:$PATH
The TOPDIR environment variable is the directory in which the sources are stored. The TARGET environment variable is the architecture that we want our compiler to emit code for. For ARM chips without an operating system (like the STM32), we want arm-none-eabi. The PREFIX environment variable is the location we want our cross-compile tools to end up in; feel free to change this to something more suitable. The BUILDPROCS environment variable is the number of processors that we can use; we will use all of them while building to substantially speed up the build process. Finally, we need to add the location of the cross-compile binaries to our PATH so that later building stages can find it.
Now we can start building. We first need to build binutils:
$ cd $TOPDIR
$ tar -xvf binutils-2.24.tar.gz
$ mkdir build-binutils
$ cd build-binutils
$ ../binutils-2.24/configure --target=$TARGET --prefix=$PREFIX \
--enable-interwork --disable-nls
$ make -j$BUILDPROCS
$ make install
Basically we are unpacking binutils, doing an out-of-tree build (recommended), and then installing it. The flags to configure deserve some explanation. The --target flag tells binutils what target you want the tools to build for; that is, what kind of code will be emitted by the code. In our case, we want ARM with no operating system. The --prefix flag tells binutils that we want our tools to be installed to $PREFIX. The --enable-interwork flag allows binutils to emit a combination of ARM and THUMB code; if you don't know what that is, don't worry about it for now. Finally, the --disable-nls flag tells binutils not to build translation files, which speeds up the build. Assuming this step went fine on your development machine, there should be a set of tools in ~/opt/cross/bin (or whatever your top-level output directory is) called arm-none-eabi-*. If this didn't work, then you might want to try a newer or older version of binutils; you can't proceed any further without this working.
With binutils built, we can now move on to gcc:
$ cd $TOPDIR
$ tar -xvf newlib-2.0.0.tar.gz
$ tar -xvf gcc-4.8.2.tar.bz2
$ mkdir build-gcc
$ cd build-gcc
$ ../gcc-4.8.2/configure --target=$TARGET --prefix=$PREFIX \
--enable-interwork --disable-nls --enable-languages="c,c++" \
--without-headers --with-newlib \
--with-headers=$TOPDIR/newlib-2.0.0/newlib/libc/include
$ make -j$BUILDPROCS all-gcc
$ make install-gcc
Here we are unpacking gcc and newlib (which is required for building gcc), doing an out-of-tree build of the initial part of gcc, and then installing it. The flags to configure deserve some explanation. The --target flag tells gcc what target you want the tools to emit code for. The --prefix flag tells gcc that we want our tools to be installed to $PREFIX. The --enable-interwork flag allows gcc to emit a combination of ARM and THUMB code. The --disable-nls flag tells gcc not to build translation files, which speeds up the build. The --enable-languages flag tells gcc which compilers we want it to build; in our case, both the C and C++ compilers. The --without-headers --with-newlib and --with-headers flags tells gcc that it not to use internal headers, but rather to use newlib and the headers from newlib. Assuming this step finished successfully, there should be a file called ~/opt/cross/bin/arm-none-eabi-gcc, which is the initial compiler. Again, if it didn't work, then you might want to try a newer or older version of gcc; you can't proceed any further without this.
With the initial compiler built, we can now build newlib:
$ cd $TOPDIR
$ mkdir build-newlib
$ cd build-newlib
$ ../newlib-2.0.0/configure --target=$TARGET --prefix=$PREFIX \
--enable-interwork
$ make -j$BUILDPROCS
$ make install
Since we've already unpacked newlib, we skip that step. Here we are doing an out-of-tree build of newlib, using the compiler that we built in the last step. The configure flags have the same meaning as previously.
With newlib built, we can now go back and finish the build of gcc (the last step!):
$ cd $TOPDIR/build-gcc
$ make -j$BUILDPROCS
$ make install
This finishes the gcc build, and installs it to $PREFIX.
That's it! You should now have a $PREFIX directory full of tools and headers useful for building code to run on the STM32.
Update Jan 8, 2014: Updated the formatting so it is more readable.
Labels:
binutils,
C,
cross compile,
gcc,
linux,
microcontroller,
newlib,
open source,
stm32
Monday, January 6, 2014
Developing STM32 microcontroller code on Linux (Part 1 of 8, introduction)
Recently I've been playing with the STM32, which is a small microcontroller made by ST. These seem to be pretty great microcontroller chips; they are relatively fast (depending on what model you get), have a decent amount of flash (up to 1MB), and have a decent amount of memory (up to 192KB). It is also easy to get development boards for them; there is a line of boards called the STM32DISCOVERY boards that are really cheap and easy to get. It is possible to work on these chips entirely with open source tools, which is important to me.
This series of posts will go through all of the steps necessary to develop on these boards. Note that all of this is covered elsewhere on the web, but a lot of the information is either outdated or scattered. I'll build all of the pieces from the ground up to get a working set of tools and binaries that you can use to develop your own STM32 applications.
To start with, I'm going to describe my hardware setup. I have a laptop running Fedora 19 x86_64. This is my main development machine, and this is going to be the host for everything I do with the STM32. For an STM32 board, I have an STM32F3DISCOVERY board, as shown here. However, note that for most of the posts, the exact board that you have isn't that important. As long as it is one of the STM32F*DISCOVERY boards, the steps below will mostly apply. The differences will become more important when we start to actually write code that deals with the GPIOs (as the GPIOs differ per board), but for the development environment they are really all quite similar.
This series of posts will do the steps in the following order:
This series of posts will go through all of the steps necessary to develop on these boards. Note that all of this is covered elsewhere on the web, but a lot of the information is either outdated or scattered. I'll build all of the pieces from the ground up to get a working set of tools and binaries that you can use to develop your own STM32 applications.
To start with, I'm going to describe my hardware setup. I have a laptop running Fedora 19 x86_64. This is my main development machine, and this is going to be the host for everything I do with the STM32. For an STM32 board, I have an STM32F3DISCOVERY board, as shown here. However, note that for most of the posts, the exact board that you have isn't that important. As long as it is one of the STM32F*DISCOVERY boards, the steps below will mostly apply. The differences will become more important when we start to actually write code that deals with the GPIOs (as the GPIOs differ per board), but for the development environment they are really all quite similar.
This series of posts will do the steps in the following order:
- In order to do anything, we need a cross compiler. This is a set of tools that runs on our development environment (Fedora 19 x86_64), but emit instructions for our target hardware (STM32 ARM). Besides the C/C++ compiler, this also includes things like the assembler and linker. Part of the cross-compile toolchain also includes a minimal libc-like environment to program in, which gives you access to <stdio.h> and other familiar header files and functions. We will build a cross compile environment from binutils, gcc, and newlib.
- Once we have a cross-compiler, we need some way to debug the programs we write. The simplest thing to do here is to build gdb, the GNU debugger. Unfortunately we can't just use the system gdb, as that generally only understands how to debug and disassemble code on your development machine architecture. So we'll build our own version of gdb that understands ARM.
- With the debugger finished, we need some way to take the compiled version of our code and put it onto the target device. The STM32 devices use something called STLinkV2, which is a multi-purpose communication protocol (generally over USB). In order to upload our code to the device, we need a piece of software the speaks this protocol. Luckily there is OpenOCD, the Swiss Army Knife of communication protocols. We'll need to build a version of this that runs on our development machine, but knows how to speak STLinkV2. In this step we'll also build a configuration file that can communicate over STLinkV2.
- With the communications taken care of, we need a device library. This is basically an abstraction layer that allows us to talk directly to the hardware on the target device. For the purposes of these posts we are going to use libopencm3. This step will build libopencm3 for the target device.
- Once we have libopencm3 built, we have to know how to link programs so that they run on the STM32. This step will discuss linker scripts and command-line directives necessary to build programs that run on the STM32.
- Here we build our first simple program, upload it to the STM32, and watch it run! Finally!
- For bonus, I discuss running a simple Real-Time Operating System on the STM32, FreeRTOS. Using this will allow you to define several tasks and have the RTOS switch between them, much like tasks on a full-fledged OS. This opens up new possibilities and new problems, some of which will be discussed.
Labels:
binutils,
C,
cross compile,
freertos,
gcc,
gdb,
libopencm3,
linux,
microcontroller,
newlib,
open source,
openocd,
stm32
Friday, January 3, 2014
Oz 0.12.0 release
I'm pleased to announce release 0.12.0 of Oz. Oz is a program for doing automated installation of guest operating systems with limited input from the user. Release 0.12.0 is a bugfix and feature release for Oz. Some of the highlights between Oz 0.11.0 and 0.12.0 are:
- Fixes to concurrent oz-install invocations
- Python 3 compatibility in the test suites
- Support for Ubuntu 12.04.3
- Support for Mageia
- Allow a MAC address to be passed in (instead of auto-generated)
- Support for RHEL5.10
- Support for Ubuntu 13.10
- Use lxml instead of libxml2 for XML document processing (it has much better error messages)
- Remove the unused "tunnels" functionality
- Support FreeBSD 10.0
- Remove deprecated functions from the Guest class
- Speed up guest customization on guests that support NetworkManager
- Follow subprocess commands as they are executed (makes debugging easier)
- Ensure that any paths from the user are absolute, otherwise things don't work properly
- Add support for OpenSUSE 13.1
- Add support for Fedora 20
- Add support for RHEL-7
Sunday, December 15, 2013
Release of ruby-libvirt 0.5.1
I'm pleased to announce the release of ruby-libvirt 0.5.1. ruby-libvirt is a ruby wrapper around the libvirt API.
The changelog between 0.5.0 and 0.5.1 is:
- Fixes to compile against older libvirt
- Fixes to compile against ruby 1.8
Monday, December 9, 2013
Release of ruby-libvirt 0.5.0
I'm pleased to announce the release of ruby-libvirt 0.5.0. ruby-libvirt is a ruby wrapper around the libvirt API. Version 0.5.0 brings new APIs, more documentation, and bugfixes:
- Updated Network class, implementing almost all libvirt APIs
- Updated Domain class, implementing almost all libvirt APIs
- Updated Connection class, implementing almost all libvirt APIs
- Updated DomainSnapshot class, implementing almost all libvirt APIs
- Updated NodeDevice class, implementing almost all libvirt APIs
- Updated Storage class, implementing almost all libvirt APIs
- Add constants for almost all libvirt defines
- Improved performance in the library by using alloca
Saturday, November 9, 2013
Writing Ruby Extensions in C - Part 13, Wrapping C data structures
This is the thirteenth in my series of posts about writing ruby extensions in C. The first post talked about the basic structure of a project, including how to set up building. The second post talked about generating documentation. The third post talked about initializing the module and setting up classes. The fourth post talked about types and return values. The fifth post focused on creating and handling exceptions. The sixth post talked about ruby catch and throw blocks. The seventh post talk about dealing with numbers. The eighth post talked about strings. The ninth post focused on arrays. The tenth post looked at hashes. The eleventh post explored blocks and callbacks. The twelfth post looked at allocating and freeing memory. This post will focus on wrapping C data structures in ruby objects.
An example will demonstrate the use of these functions:
On lines 32 and 33, we define the Example module and give it a module function called "open". Lines 34 and 35 define a Conn class under the Example module, and gives the Conn class a "get_a" method. Lines 14 through 21 are where we implement the Example::open function. There, we allocate memory for our C structure, then use Data_Wrap_Struct() to wrap that C structure in a ruby object of type Example::Conn. Note that we also pass mystruct_free() as the free callback; when the object gets reaped by the garbage collector, this function on lines 9 through 12 will be called to free up any memory. Now when the user calls "get_a" on the Example::Conn ruby object, the function on lines 23 through 27 will be called. There we use Data_Get_Struct() to fetch the structure back out of the object, and then return a ruby number for the integer stored inside. Update: added links to all of the previous articles. Update Jan 27, 2014: Updated the example to fix the use of ALLOC(). Thanks to Thomas Thomassen in the comments.
Wrapping C data structures
When developing a ruby extension in C, it may be necessary to save an allocated C structure inside a Ruby object. For instance, in the ruby-libvirt bindings, a virConnectPtr (which points to a libvirt connection object) is saved inside of Libvirt::Connect ruby object, and that pointer is fetched from the object any time an instance method is called. Note that the pointer to the C structure is stored inside the Ruby object in a way that the ruby code can't get to; only C extensions will have access to this pointer. There are only 3 APIs that are used to manipulate these pointers:- Data_Wrap_Struct(VALUE klass, void (*mark)(), void (*free)(), void *ptr) - Wrap the C data structure in ptr into a class of type klass. The free argument is a function pointer to a function that will be called when the object is being garbage collected. If the C structure references other ruby objects, then the mark function pointer must also be provided and must properly mark the other objects with rb_gc_mark(). This function returns a VALUE which is an object of type klass.
- Data_Make_Struct(VALUE klass, c-type, void (*mark)(), void (*free)(), c-type *ptr) - Similar to Data_Wrap_Struct(), but first allocates and then wraps the C structure in an object. The klass, mark, free, and ptr arguments have the same meaning as Data_Wrap_Struct(). The c-type argument is the actual name of the type that needs to be allocated (sizeof(type) will be used to allocate).
- Data_Get_Struct(VALUE obj, c-type, c-type *ptr) - Get the C data structure of c-type out of the object obj, and put the result in ptr. Note that this pointer assignment works because this is a macro.
An example will demonstrate the use of these functions:
1) static VALUE m_example;
2) static VALUE c_conn;
3)
4) struct mystruct {
5) int a;
6) int b;
7) };
8)
9) static void mystruct_free(void *s)
10) {
11) xfree(s);
12) }
13)
14) static VALUE example_open(VALUE m)
15) {
16) struct mystruct *conn;
17) conn = ALLOC(struct mystruct);
18) conn->a = 25;
19) conn->b = 99;
20) return Data_Wrap_Struct(c_conn, NULL, mystruct_free, conn);
21) }
22)
23) static VALUE conn_get_a(VALUE c)
24) {
25) struct mystruct *conn;
26) Data_Get_Struct(c, struct mystruct, conn);
27) return INT2NUM(conn->a);
28) }
29)
30) void Init_example(void)
31) {
32) m_example = rb_define_module("Example");
33) rb_define_module_function(m_example, "open", example_open, 0);
34) c_conn = rb_define_class_under(m_example, "Conn", rb_cObject);
35) rb_define_method(c_conn, "get_a", conn_get_a, 0);
36) }
On lines 32 and 33, we define the Example module and give it a module function called "open". Lines 34 and 35 define a Conn class under the Example module, and gives the Conn class a "get_a" method. Lines 14 through 21 are where we implement the Example::open function. There, we allocate memory for our C structure, then use Data_Wrap_Struct() to wrap that C structure in a ruby object of type Example::Conn. Note that we also pass mystruct_free() as the free callback; when the object gets reaped by the garbage collector, this function on lines 9 through 12 will be called to free up any memory. Now when the user calls "get_a" on the Example::Conn ruby object, the function on lines 23 through 27 will be called. There we use Data_Get_Struct() to fetch the structure back out of the object, and then return a ruby number for the integer stored inside. Update: added links to all of the previous articles. Update Jan 27, 2014: Updated the example to fix the use of ALLOC(). Thanks to Thomas Thomassen in the comments.
Sunday, July 28, 2013
Oz 0.11.0 release
I'm pleased to announce release 0.11.0 of Oz. Oz is a program for doing automated installation of guest operating systems with limited input from the user. Release 0.11.0 is a bugfix and feature release for Oz. Some of the highlights between Oz 0.10.0 and 0.11.0 are:
If you have questions or comments about Oz, please feel free to contact me at clalancette at gmail.com, or open up an issue on the github page: http://github.com/clalancette/oz/issues.
This was one of the most active Oz releases ever, because of the feedback and patches from the community. Thanks to everyone who contributed to this release through bug reports, patches, and suggestions for improvement.
- Add support for installing Ubuntu 13.04
- Add the ability to get user-specific ICICLE information
- Add the ability to generate ICICLE safely, by using a disk snapshot
- Add the ability to include extra files and directories on the installation ISO
- Add the ability to install to alternate file types, like qcow2, etc.
- Add support for installing Ubuntu 5.04/5.10
- Add support for installing Fedora 19
- Add support for installing Debian 7
- Add support for Windows 2012 and 8
- Add support for getting files over http for the commands/files section of the TDL
- Add support for setting a custom MAC address to guests during installation
- Add support for user specified disk and NIC model
- Add support for OpenSUSE 12.3
- Add support for URL based installs for Ubuntu
If you have questions or comments about Oz, please feel free to contact me at clalancette at gmail.com, or open up an issue on the github page: http://github.com/clalancette/oz/issues.
This was one of the most active Oz releases ever, because of the feedback and patches from the community. Thanks to everyone who contributed to this release through bug reports, patches, and suggestions for improvement.
Saturday, March 9, 2013
Oz 0.10.0 release
I'm pleased to announce release 0.10.0 of Oz. Oz is a program for doing automated installation of guest operating systems with limited input from the user. Release 0.10.0 is a bugfix and feature release for Oz. Some of the highlights between Oz 0.9.0 and 0.10.0 are:
- Support for installing OpenSUSE 12.1 and 12.2
- Support for python3
- Support for Ubuntu 12.04.1, 12.04.2, and 12.10
- Fix up
ordering so that commands are run in the order they are specified in the XML - Updates and fixes to the documentation
- Increase the shutdown timeout to support slower qemu guests
- Add a default screenshot directory as /var/lib/oz/screenshots
- Support for RHEL 5.9
- Support for Fedora 18
- Switch over to pycurl for header information; this allows http authentication to work
- Switch to using the libvirt built-in screenshot mechanism. This removes the gvnc dependency and makes screenshots more reliable, but requires libvirt 0.9.7 or newer
- Delete auto-generated ssh keys after customization
Saturday, August 18, 2012
Oz 0.9.0 release
I'm pleased to announce release 0.9.0 of Oz. Oz is a program for doing automated installation of guest operating systems with limited input from the user. Release 0.9.0 is a (long overdue) bugfix and feature release for Oz. Some of the highlights between Oz 0.8.0 and 0.9.0 are:
If you have any questions or comments about Oz, please feel free to contact aeolus-devel@lists.fedorahosted.org or me (clalancette@gmail.com) directly.
Thanks to everyone who contributed to this release through bug reports, patches, and suggestions for improvement.
- Easier to create Debian/Ubuntu packages
- Ability to specify the disk size in the TDL
- Ability to specify the number of CPUs and amount of memory used for the installation VM
- Cleanup and bugfixes to oz-cleanup-cache
- Ability to install Fedora-17 disk images
- Ability to install guests as a non-root user. This has several caveats; please see the documentation on http://github.com/clalancette/oz for more information
- Ability to install RHEL-6.3 disk images
- Ability to install ScientificLinuxCERN disk images
- Ability to install Mandrake 8.2 disk images
- Ability to install OpenSUSE 10.3 disk images
- Ability to install Ubuntu 12.04 disk images
If you have any questions or comments about Oz, please feel free to contact aeolus-devel@lists.fedorahosted.org or me (clalancette@gmail.com) directly.
Thanks to everyone who contributed to this release through bug reports, patches, and suggestions for improvement.
Tuesday, January 24, 2012
Oz 0.8.0 released
(this is a little delayed; sorry about that)
I'm pleased to announce release 0.8.0 of Oz. Oz is a program for doing automated installation of guest operating systems with limited input from the user.
Release 0.8.0 is a (long overdue) bugfix and feature release for Oz. Some of the highlights between Oz 0.7.0 and 0.8.0 are:
A tarball of this release is available, as well as packages for Fedora-15. Instructions on how to get and use Oz are available at http://aeolusproject.org/oz.html
If you have any questions or comments about Oz, please feel free to contact aeolus-devel@lists.fedorahosted.org or me (clalancette@gmail.com) directly.
Thanks to everyone who contributed to this release through bug reports, patches, and suggestions for improvement.
I'm pleased to announce release 0.8.0 of Oz. Oz is a program for doing automated installation of guest operating systems with limited input from the user.
Release 0.8.0 is a (long overdue) bugfix and feature release for Oz. Some of the highlights between Oz 0.7.0 and 0.8.0 are:
- Optional virtualenv make target
- Conversion of unittests to py.test
- Replace mkisofs with genisoimage
- Debian package
- Ability to change the root password for Debian installs
- Add unittests for ozutil
- Add some unittests for the Guest object
- SSH tunnel (with SSL vhost) support for local repositories (mostly useful for imagefactory)
- Add a new manpage for oz-examples
- Make the output filename configurable with a command-line option to oz-install
- Monitor both network and disk activity when looking for guest activity
- Support for installing Ubuntu 11.10
- Support for SSL certificates for repositories
- Support for an optional version in the TDL
- Support for installling Mandrake 9.1, 9.2, 10.0, 10.1, 10.2
- Support for installing Mandriva 2006.0, 2007.0, 2008.0
- Support for Ubuntu customization
- Support for installing RHEL 6.2
A tarball of this release is available, as well as packages for Fedora-15. Instructions on how to get and use Oz are available at http://aeolusproject.org/oz.html
If you have any questions or comments about Oz, please feel free to contact aeolus-devel@lists.fedorahosted.org or me (clalancette@gmail.com) directly.
Thanks to everyone who contributed to this release through bug reports, patches, and suggestions for improvement.
Tuesday, October 4, 2011
Git bash prompts and tab completion
Someone recently asked me about my nifty bash command-prompt with git branch names. If I'm not in a git directory, then the bash prompt looks normal:
However, as soon as I cd into any directory that is a git repository, my prompt changes:
If I'm in the middle of a rebase, my prompt looks like:
There are many other prompts, but that just gives you a taste of what you get. All of this goodness is due to the git-completion file that is shipped along with the git sources. The canonical place for git-completion.sh is actually the upstream git sources; you can see it here: http://repo.or.cz/w/git.git/blob/HEAD:/contrib/completion/git-completion.bash. Basically, you download that file, put it somewhere in your home directory (mine is at ~/.git-completion.sh), source it from your .bashrc, and then modify your PS1 to call the appropriate function. The end of my .bashrc looks like:
The additional benefit that you get from sourcing .git-completion.sh is that you get branch auto-completion, which is also a very useful feature.
[clalance@localhost ~]$
However, as soon as I cd into any directory that is a git repository, my prompt changes:
[clalance@localhost oz (master)]$
If I'm in the middle of a rebase, my prompt looks like:
[clalance@localhost oz (master|REBASE-i)]$
There are many other prompts, but that just gives you a taste of what you get. All of this goodness is due to the git-completion file that is shipped along with the git sources. The canonical place for git-completion.sh is actually the upstream git sources; you can see it here: http://repo.or.cz/w/git.git/blob/HEAD:/contrib/completion/git-completion.bash. Basically, you download that file, put it somewhere in your home directory (mine is at ~/.git-completion.sh), source it from your .bashrc, and then modify your PS1 to call the appropriate function. The end of my .bashrc looks like:
source ~/.git-completion.sh
export PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
The additional benefit that you get from sourcing .git-completion.sh is that you get branch auto-completion, which is also a very useful feature.
Friday, September 23, 2011
RPM dependency trees
Recently I wondered what the dependency tree for Aeolus looked like in Fedora. I knew we had a whole host of dependencies, but I thought it would be instructive to see it visually.
This has been mentioned in other blog posts in the past, but the basic procedure to do this on Fedora is:
The rpmorphan provides the rpmdep binary. The rpmdep binary is a perl script that runs through the RPM dependency information, outputting one digraph node per-line. Then we use dot (part of the graphviz package) to take that digraph information and generate an image out of it. In the above example I made it generate an SVG, but you can have it output PNG, JPEG, PDF, etc. The full list of what dot can do is here: http://www.graphviz.org/doc/info/output.html
This has been mentioned in other blog posts in the past, but the basic procedure to do this on Fedora is:
# yum install rpmorphan graphviz
$ rpmdep -dot aeolus.dot aeolus-all
$ dot -Tsvg aeolus.dot -o aeolus.svg
The rpmorphan provides the rpmdep binary. The rpmdep binary is a perl script that runs through the RPM dependency information, outputting one digraph node per-line. Then we use dot (part of the graphviz package) to take that digraph information and generate an image out of it. In the above example I made it generate an SVG, but you can have it output PNG, JPEG, PDF, etc. The full list of what dot can do is here: http://www.graphviz.org/doc/info/output.html
Subscribe to:
Posts (Atom)