Category Archives: Raspberry Pi

Home / Raspberry Pi
3 Posts

This article documents how I installed MediaWiki on my Raspberry Pi 3 to use as a personal wiki. MediaWiki is the wiki software package that is used by Wikipedia.

This is part of my ongoing series about creating the Ultimate Raspberry Pi 3 Home Server. I'm using a Raspberry Pi 3 Model B with Raspbian Jesse. I won't talk about the basics of setting up a Pi and its OS because there are tons of other articles on the internet for that. Just use google.

It should be noted that by installing MediaWiki, you will be installing a full-fledged LAMP server on your pi.

Installation Instructions

First, make sure the packages on the Pi are up-to-date:

  • sudo apt-get update
  • sudo apt-get upgrade
  • sudo apt-get install mediawiki - Install MediaWiki
  • In the middle of the MediaWiki installation, you will be asked to set a new password for MySQL
  • After the installation finishes, we need to edit the apache.conf file. Open the file using your favorite text editor (I will use nano):

    sudo nano /etc/mediawiki/apache.conf

    Uncomment the line "#Alias /mediawiki /var/lib/mediawiki" by removing the "#" at the start. This is what the entirety of my apache.conf looks like after the change:

  • sudo apt-get install php-apc imagemagick - Install php-apc for object caching and Imagemagick for thumbnailing
  • sudo apache2ctl restart - Restart the apache server
  • Now we'll need to configure apache to host the Mediawiki site:

    sudo nano /etc/apache2/ apache2.conf

    At the end of the file, enter the following line:

    Include /etc/mediawiki/apache.conf

    Next, enter the following two commands:

    Now we need to set up the wiki. We can do this by opening a browser and connecting to the pi's web server: [Raspberry Pi's IP Address]/mediawiki/. For example, I entered the following in my browser address bar to connect to the wiki through the Apache server:

    Your IP address is probably different. Search google if you need to learn how to find your Pi's IP address.

    Once you enter the address you should the bolded words "Mediawiki" along with its logo. Below, you should see a link that says something like "Set up the wiki". Click that link. Follow the instructions to set up MediaWiki. They are very straightforward for the most part. Here are some guidelines for the setup steps that might be more confusing

    Connect to database

    Database type: Leave as MySQL
    Database host: Leave as localhost
    Database name: Change it to whatever. I usually leave it as "my_wiki"
    Database table prefix: Leave it blank
    Database username: Leave as root
    Database password: Set this to the password you entered at the beginning of the installation process when you were asked for a MySQL password

    Database Settings

    Leave the checkbox labeled "Use the same account as for installation" checked
    Storage engine: Leave as InnoDB
    Database Character Set: Leave as Binary


    Name of wiki: Name your wiki whatever you want
    Project Namespace: Leave as default (Same as the wiki name)
    Administrator Account: Setup a username, password, and email for your wiki admin account.

    There is an option at the bottom asking if you want to be asked more questions. I personally skip this past and select "I'm bored already, just install the wiki".

    On the final 'Install' page, click Continue. This will begin the installation, which can take a while. After it's complete, you should see a window that says "Congratulations". That's it! You're done.

    This article discusses programming a GPIO Driver on a Raspberry Pi 2 using C. If you haven't already, check out the introductory post. You will also need the Broadcom BCM2835 datasheet. The Raspberry Pi 2 uses a BCM2836 chip, but at the time of writing this post the datasheet for the BCM2836 has not been released. However, the BCM2835 and BCM2836 have the same underlying architecture. For the scope of this article, the only difference between the two is that the addresses of the registers are different.

    The full source code for the GPIO Driver can be found near the bottom of this post, or by clicking here

    Accessing the Pi's memory

    As I mentioned in the introductory post, we need to write to the Pi's registers. So the first thing we need to do is access the memory of the BCM2836 chip. To do this, we first need to know the physical address at which the peripheral registers start (AKA the base peripheral address) for the Pi 2. This address is different than it is for the Pi 1, so looking through the BCM2835 (the chip in Pi 1) datasheet won't be much help. Luckily, the helpful Pi community on the internet told me that it could be found at 0x3F000000. We'll define this using a macro in the code.

    Note that this value 0x3F000000 is just the address at which all of the peripheral registers start. There are many different peripherals, and so we need to find the one specifically for GPIO. If you don't care about how to find this value, I'll just let you know its 0x3F200000 and you can skip the next paragraph.

    The GPIO registers are located at some offset of the base peripheral address. To find this offset, we consult the BCM2835 datasheet. First, we must find the virtual base peripheral address. This is because the datasheet lists information using virtual addresses rather than physical ones. Page 6 of the datasheet tells us that the virtual base peripheral address is 0x7E000000. Page 90 of the datasheet then tells us that the virtual address of the GPIO peripheral is 0x7E200000. This means that the offset from the peripheral base address to the GPIO peripheral address is 0x00200000. This offset is the same for both the physical and the virtual addresses. We'll define the address for the GPIO peripheral base with a macro as well:

    Finally, to access the BCM2836's memory, we must access /dev/mem. /dev/mem is a pseudo-driver which provides access to the system's physical memory. Then, we can map /dev/mem into the virtual address space of our program using the mmap() command.

    Assuming that mmap() is successful, the gpio variable is now a pointer to the RPi 2's GPIO peripheral registers.

    Working with GPIO Registers

    Information about the RPi 2's GPIO peripheral can be found starting at page 89 of the datasheet. On page 90, the datasheet has a layout of all of the GPIO registers (Section 6.1 - Register View). Note that there is a typo on this layout. The first register, GPFSEL0, is listed twice. We'll define some macros to make the code easy to read and provide easy access to these registers. (Remember that the gpio variable points to the start of the GPIO registers)

    Setting the function of a GPIO pin

    Before we can use a GPIO pin, we must set its functionality in the GPIO Function Select (GPFSEL) Registers. Information about these can be found on pages 91-94 of the datasheet. The GPFSEL registers are used to define the operation of a GPIO pin. There are six GPFSEL registers in total, named GPFSEL0 through GPFSEL5. The layout of the first one GPFSEL0 is shown below. All of the GPFSEL registers have pretty much the same layout.

    Layout and functionality of the GPIO GPFSEL registers from the BCM2835 datasheet.

    Layout and functionality of the GPFSEL registers from the BCM2835 datasheet.

    Each GPIO pin has three corresponding bits in one of the GPSEL registers. Writing a value to these bits will configure that GPIO pin to function in a certain way, as specified in the datasheet (000 for input, 001 for output, etc). Let's define some macros for these different functionalities:

    Then, we can write a function that sets the operation mode of a GPIO pin, as shown below. Here, pin is the GPIO pin number and function should be one of the macros defined above that defines the pin's operation mode.

    How exactly does this work? First, we need to find the three bits that will configure the GPIO pin. Note that the registers are 32-bit. This means that each one of the GPFSEL registers contains the function select bits for 10 GPIO pins (each GPFSEL register has 2 bits left over that are not used for anything). The bits go in order, so GPFSEL0 has the bits for GPIO pins 0 through 9, GPFSEL1 has the bits for GPIO pins 10 through 19, and so on. So, if we simply divide the pin number by 10, we get the GPFSEL register number that we need to write to. This is what the code offset = pin / 10 is doing.

    Then, we can access the correct GPFSEL register using the macro we defined before: GPFSEL[offset] (Remember that we defined GPFSEL to be a pointer to the GPFSEL0 register using a macro)

    shift = (pin % 10) * 3 gives the offset of the three selection bits inside the GPFSEL register.

    Then, the selection bits for the GPIO Pin are cleared and afterwards set accordingly using bit manipulation.

    Reading and Writing to a GPIO pin

    Reading and writing to a GPIO pin is probably the simplest part of the code. Setting a GPIO Pin high is done through the GPIO Pin output Set (GPSET) registers. Clearing a GPIO Pin (AKA setting it low) is done through the GPIO Pin Output Clear (GPCLR) registers. The info on these registers can be found on page 95-96 of the datasheet. Essentially, each GPIO pin has a corresponding bit in one of these registers. Writing a 1 to that bit will set or clear the GPIO pin.

    Similarly, the GPIO Pin Level (GPLEV) registers can be read to see the actual value of a pin. Page 96 on the datasheet has the info for these registers.

    Full Source Code


    A lot of the work being done on the Raspberry Pi involves high-level programming using languages such as Python. However, the Raspberry Pi is also well-equipped for lower-level "embedded-style" programming (like programming a microcontroller). In this article I'll be going through how to create drivers that implement GPIO and I2C functionality on a Raspberry Pi. These drivers will be written in C, a lower-level programming language. The description and source code of these drivers are on their own pages. The links to these can be found at the bottom of this article.

    Why would you want to program the Raspberry Pi like a microcontroller? To learn, mainly. After all, the Pi was originally developed for educational purposes. Another advantage is that programs written in C are capable of running much faster than programs written in high-level languages such as Python. There are many articles online which compare the speed of different languages on a Raspberry Pi. Here is one example that shows how much faster the C language can be.

    To follow the code, you should be familiar with C, have a decent understanding of pointers/pointer arithmetic, and understand how bit manipulation works.


    Low-level programming of microcontrollers is different because it involves writing to registers. A register is a memory location that is frequently used by the CPU. The size of a register can vary and is usually measured in the number of bits (e.g 16-bit register). Writing certain values to these registers allows us to program the CPU.

    But how do we know what we need to write to the registers? The datasheets will tell us. The Raspberry Pi Model A, B, B+, and Zero use the Broadcom BCM2835 chip. The Raspberry Pi 2 uses the Broadcom BCM2836 chip. At the time of writing this, the datasheet for the BCM2836 has not been released. However, the underlying architectures of the BCM2835 and BCM2836 are the same. For the scope of this article, the only difference between the two is that the addresses of the registers are different.

    Implementing the Drivers!

    The implementation and source code of the drivers are in separate articles. The links can be found below.

    GPIO Driver
    I2C Driver