Сегодня у нас статья Егора Баранова о разработке для Sony PlayStation Portable.

Больше полугода назад у меня появилась игровая консоль Sony Playstation Portable (или просто PSP). Надо сказать, что игры на ней отменные, консоль можно взять в любую поездку и приятно скоротать время в дороге. Как разработчику мне всегда было интересно, как же писать приложения для PSP, я видел множество свободнораспространяющихся приложений, таких как PSP WiFile Transfer, Bookr и даже порты OpenSource игр, например OpenTTD, а недавно у меня появилось немного свободного времени, чтобы заняться вопросом разработки для PSP более подробно, поэтому я поискал информацию по данному вопросу и, как оказалось, программировать для PSP не так уж и сложно.

Итак, в данной статье мы рассмотрим настройку среды разработки для PSP на языках программирования Си и Си++ и написание простейшей классической программы Hello world.

Что же мы имеем изначально:

  1. дистрибутив Ubuntu 9.04
  2. доступ в интернет (придется скачивать исходные коды библиотек, необходимых для разработки PSP программ)
  3. свободное время порядка 3 — 4 часов (библиотеки собираются из исходных кодов, поэтому компиляция занимает несколько часов)

Первое что нам потребуется — установить subversion:

sudo aptitude install subversion

Теперь можно получить последние исходные коды psptoolchain (кросскомпилятора для PSP)

svn co svn://svn.ps2dev.org/psp/trunk/psptoolchain

В полученной папке есть readme файл для всех и специально для дистрибутива Ubuntu (замечу, что psptoolchain можно собрать в любом linux дистрибутиве, а так же cygwin-е). В readme файле для дистрибутива Ubuntu написано что для сборки psptoolchain необходимо удовлетворить зависимости с помощью следующей команды:

sudo apt-get install build-essential autoconf automake bison flex \

libncurses5-dev libreadline-dev libusb-dev texinfo libgmp3-dev \

libmpfr-dev subversion gcc-4.2

что мы и сделаем. После этого нам нужно определить несколько переменных окружения. Добавим следующие строки в файл ~/.bashrc:

export PSPDEV=”/usr/local/pspdev”

export PSPSDK=”$PSPDEV/psp/sdk”

export PATH=”$PATH:$PSPDEV/bin:$PSPSDK/bin”

и выполним команду:

source ~/.bashrc

Теперь можно приступить непосредственно к сборке среды разработки:

cd psptoolchain

sudo ./toolchain-sudo.sh

После этого необходимо получить дополнительные библиотеки для разработки (zlib, SDL и т.п.). Для этого сначала получим набор скриптов из SVN с помощью следующей команды:

svn co svn://svn.ps2dev.org/psp/trunk/psplibraries psplibraries

К сожалению в скриптах установки дополнительных библиотек есть ошибка, для того чтобы ее исправить необходимо сделать следующее: открваем файл psplibraries/scripts/003-freetype.sh и заменяем его содержимое на следующий текст:

#!/bin/sh
# freetype.sh by Dan Peori (danpeori@oopo.net)
## Download the latest source code.

if test ! -d "freetype"; then
svn checkout svn://svn.ps2dev.org/psp/trunk/freetype || { exit 1; }
else
svn update freetype || { exit 1; }
fi

## Enter the source directory.
cd freetype || { exit 1; }
cd builds/unix
automake --add-missing
cd ../..

## Bootstrap the source.
sh autogen.sh || { exit 1; }

## Configure the build.
LDFLAGS="-L$(psp-config --pspsdk-path)/lib -lc -lpspuser" ./configure --host psp --prefix=$(psp-config --psp-prefix) || { exit 1; }

## Compile and install.
make clean && make -j2 && make install && make clean || { exit 1; }

После этого установим одну зависимость:

sudo aptitude install libtool

и запускаем компиляцию библиотек:

sudo ./libraries-sudo.sh

После данных махинаций мы имеем кросскомпилятор и набор библиотек для разработки программ для PSP на Си и Си++. Давайте напишем нашу первую программу.

#include <pspkernel.h>
#include <pspdebug.h>

PSP_MODULE_INFO("Hello World", 0, 1, 1);
#define printf pspDebugScreenPrintf

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common) {
    sceKernelExitGame();
    return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp) {
    int cbid;
    cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    sceKernelRegisterExitCallback(cbid);
    sceKernelSleepThreadCB();
    return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
    int thid = 0;
    thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
    if(thid >= 0) {
        sceKernelStartThread(thid, 0, 0);
    }
    return thid;
}

int main() {
    pspDebugScreenInit();
    SetupCallbacks();
    printf("Hello World");
    sceKernelSleepThread();
    return 0;
}

Итак, с помощью макроса PSP_MODULE_INFO мы определяем задаем информацию о нашей программе и ее версии, далее опредяем несколько стандартных callback-ов и соотвественно главную функцию нашей программы main — которая устанавливает заданные нами callback-и и печатает на экране заветную строку «Hello world».

Теперь напишем Makefile для того чтобы собрать наш код.

TARGET = hello
OBJS = main.o
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Hello world
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak

Скомпилируем нашу программу командой make. Полученный файл EBOOT.PBP поместим на консоль в папку psp/game/hello. Вот и все. В следующей статье мы рассмотрим, как контролировать нажатия клавиш.

Оригинал статьи.

Previous ArticleNext Article
Технический директор IT-Dimension, компании-разработчика кросс-платформенного программного обеспечения

This post has 5 Comments

5
  1. Как-то сложно все, хотя и достаточно интересно. А это все принципиально из убунты делается?

  2. Спасибо за подробную и хорошую статью.
    Но вот проблема. Застываю в самом конце. На команде make – кричит “make: psp-config: Команда не найдена
    Makefile:9: /lib/build.mak: No such file or directory
    make: *** Нет правила для сборки цели `/lib/build.mak’. Останов.”

    Посоветуйте как побороть проблему?

  3. а что у вас выдает если сделать

    sudo updatedb
    locate psp-config
    
  4. На это выдает следующее:
    “locate psp-config

    /home/spiritfan/psptoolchain/build/pspsdk/tools/psp-config.c
    /home/spiritfan/psptoolchain/build/pspsdk/tools/.deps/psp-config.Po
    /home/spiritfan/psptoolchain/build/pspsdk/tools/.svn/prop-base/psp-config.c.svn-base
    /home/spiritfan/psptoolchain/build/pspsdk/tools/.svn/text-base/psp-config.c.svn-base
    /usr/local/pspdev/bin/psp-config”

  5. Сделал все сначала.
    Заработало.

    Спасибо еще раз за статью.

    С нетерпением жду продолжения.

Leave a Reply

Your email address will not be published. Required fields are marked *

M.

Maemo 5 Beta SDK Released

И вот, вышла новая версия Maemo SDK. В этом релизе:

  • Поддержка OMAP3.
  • Поддержка HSPA.
  • Поддержка камер высокого разрешения.
  • Аппаратное ускорение вывода графики.

SDK включает упрощенную реализацию рабочего стола и меню приложений. Режим редактирования рабочего стола включен чтобы облегчить управление приложениями и тестирование виджетов.

В комплект включена предварительная версия документации для разработчиков.

maemo5-sdk-beta

С.

Собираем собственный дистрибутив Embedded Linux на базе OpenEmbedded

Администратор сайта OpenEmbedded.ru любезно предоставил интереснейшую статью о том, как собрать свой собственный дистрибутив Embedded Linux на базе OpenEmbedded. Судя по качеству материала, проект OpenEmbedded.ru может быть очень интересен разработчикам, использующим Embedded Linux для построения решений. Статья под катом, читаем!

Практически у всех программистов первой программой была Hello, world! Она говорила – Здравствуй, мир! и завершалась. Первый дистрибутив на базе OpenEmbedded будет делать то же самое. Но для этого придется немного попотеть, потребуется следующее:

  • Компьютер с установленным дистрибутивом Linux Ubuntu.
  • Желание установить и умение читать.
  • Интернет канал, желательно безлимитный.

Если у вас есть все требуемое, запускайте терминал. Для начала запустим установку необходимых программного обеспечения:

sudo apt-get install make gcc g++ ccache sed wget cvs \
subversion git-core git coreutils unzip texi2html texinfo \
libsdl1.2-dev docbook-utils gawk python-pysqlite2 \
diffstat help2man libxml2-utils xmlto \
python-psyco

В случае если у вас достаточно быстрый интернет, то установка займет где-то полчаса. Если же нет, то это отнимет больше времеи.

Как только все программы установятся, cоздаем каталог для опытов и переходим в нее:

exit
mkdir -p ~/stuff/build/conf
cd ~/stuff

Далее установливаем bitbake. Для этого с сайта bitbake скачиваем и распаковываем последний релиз:

wget http://download.berlios.de/bitbake/bitbake-1.8.12.tar.gz
tar -xzvf bitbake-1.8.12.tar.gz
mv bitbake-1.8.12 bitbake

Следующим шагом идет получение репозитория OpenEmbedded. Для его получения запускаем:

git clone git://git.openembedded.net/openembedded

Если вдруг доступен только http (злые админы закрыли интернеты) то пробуем получить его через http:

git clone http://repo.or.cz/r/openembedded.git

Note:

В дальнейшем для обновления репозитария будет достаточно перейти в каталог stuff/openembedded:

cd ~/stuff/openembedded
git pull

Учтите, репозиторий довольно большой, так что качается довольно долго. Когда он скачается, необходимо создать конфигурационный файл сборки. Воспользуемся примером из репозитория:

cd ~/stuff/
cp openembedded/conf/local.conf.sample build/conf/local.conf

Далее откройте файл в редакторе и измените значения следующих переменных:

BBFILES = "${HOME}/stuff/openembedded/packages/*/*.bb"
DL_DIR = "${HOME}/stuff/sources"
DISTRO = "angstrom-2008.1"
MACHINE = "x86"

А в конце файла удалите строку:

REMOVE_THIS_LINE

сохраните файл.
Теперь необходимо настроить окружение. Сначала указываем где у нас находится bitbake

export PATH=${PATH}:${HOME}/stuff/bitbake/bin

затем указываем bitbake где искать репозиторий и файл конфигурации

export BBPATH=${HOME}/stuff/build:${HOME}/stuff/openembedded

И наконец запускаем сборку hello world:

bitbake helloworld-image

Если в результате запуска появилось нечто такое:

NOTE: Handling BitBake files: / (6291/6291) [100 %]
NOTE: Parsing finished. 6027 cached, 0 parsed, 264 skipped, 0 masked.
NOTE: build 200812252310: started

OE Build Configuration:
BB_VERSION        = "1.8.10"
METADATA_BRANCH   = "org.openembedded.dev"
METADATA_REVISION = "5b1ed09b1ab1a60a28a76e4658bc9957cd361b5d"
TARGET_ARCH       = "i486"
TARGET_OS         = "linux"
MACHINE           = "x86"
DISTRO            = "angstrom"
DISTRO_VERSION    = "2008.1-test-20081225"
TARGET_FPU        = ""

NOTE: Resolving any missing task queue dependencies
NOTE: Preparing runqueue
NOTE: Executing runqueue

то можете себя поздравить, bitbake и openembedded установленны правильно. Вам осталось подождать пока bitbake соберет все что необходимо.

Итак, сборка helloworld-image завершена. В результате при помощи OpenEmbedded был собран helloworld и создан образ корневой файловой системы вместе с ним. Осталось только все это запустить, это довольно просто. Для начала устанавливаем Virtual Box:

sudo apt-get install virtualbox

Затем потребуется собрать модуль для virtualbox (возможно, вам не потребуется собирать модуль, так-как в исходных кодах он стал устанавливаться недавно)

sudo apt-get install module-assistant
sudo m-a prepare
sudo m-a a-i virtualbox-ose

и загрузить его

sudo modprobe vboxdrv

Note

Команда sudo m-a a-i virtualbox-ose может сообщить об неудачном завершении. Но на самом деле все что необходимо она выполнила. Если при этом у вас команда sudo modprobe vboxdrv не вывела никаких ошибок при выполнении, то значит все в порядке.

Затем добавляем его в автозагрузку. Для этого открываем /etc/modules и добавляем туда:

vboxdrv

после чего сохраняем. Теперь при каждой загрузке этот модуль будет подгружаться сам. Осталось добавить себя в группу пользователей vboxusers, чтобы можно было работать с Virtualbox:

sudo adduser [your username] vboxusers

Note

Для вступления в силу изменений потребуется завершить сеанс и войти заново.

Теперь пробуем запустить Virtualbox (у меня находится в разделе стандартные). Если вы увидите нечто такое:

OpenEmbedded в VirtualBox

то значит, что virtualbox работаем и можно приступать к созданию виртуальной машины, если нет то необходимо разобраться, что у вас не так.

Для создания новой виртуальной машины нажимаем создать, далее в качестве имени вводим openembedded (на самом деле имя может быть любым, главное чтобы оно не содержало пробелов), в тип ОС указываем Linux 2.6, жмем далее до запроса о виртуальном диске. Тут так же жмем далее, когда выскакивает предупреждение о том, что у нас нет дисков, нажимайте продолжить пока они не потребуются. После этого выведется итог, там жмем готово.
В списках виртуальных машин должна появиться машина openembedded. Выделяем ее и жмем свойства, там выбираем пункт Общие и переключаемся с закладки Основные на закладку Дополнительно. Там меняем порядок загрузки таким образом, чтобы Сеть была включена и была в списке первой. Если что-то не понятно сверьтесь:

openembedded-create-virtualbox-machine

Если вы выполнили все верно, то виртуальная машина настроена. Теперь необходимо добавить загрузчик, собрать ядро, установить и настроить NFS сервер. Начем с загрузчика.

В качестве загрузчика будет использоваться pxelinux из состава syslinux. Устанавливаем его:

sudo apt-get install syslinux

Нужный нам файл pxelinux.0 находится в каталоге /usr/lib/syslinux. Для его установки переходим в каталог ~/.VirtualBox, создаем нем каталог TFTP и копируем туда pxelinux.0:

cd ~/.VirtualBox
mkdir TFTP
cp /usr/lib/syslinux/pxelinux.0 TFTP/openembedded.pxe

Note

Такое странное имя выбрано не спроста. Если вы вспомните называлась виртуальная машина, то заметите что оно совпадает с ее именем. Это необходимо из-за того что VirtualBox обладает встроенными средствами автоконфигурации и загрузки по сети. Для того чтобы он нашел загрузчик, он должен называться имя машины.pxe.

Теперь можно попробовать включить виртуальную машину. Выберите ее в списке и нажмите старт. Если в результате вывелось что-то похожее

OpenEmbedded в VirtualBox

значит VirtualBox нашел загрузчик и передал ему управление. Выключаем вируальную машину и переходим к сборке ядра. Для этого потребуется изменить локальную конфигурацию и один из файлов репозитория. Начнем с файла локальной конфигурации local.conf. Добавляем в него строку следующего вида:

FILESPATH =. "${TOPDIR}/conf/packages/${PN}/${MACHINE}:"

Затем изменяем файл base.bbclass. Он находится в каталоге ~/stuff/openembedded/classes. Открывываем его, ищем строку начинающуюся с:

FILESPATH

удаляем.

Note

Эти действия необходимы для того чтобы конфигурация ядра бралась не из репозитория, а из определенного конфигурацией каталога.

Создаем каталог в котором будет находится файл конфигурации ядра:

mkdir -p ~/stuff/build/conf/packages/linux/x86

Выкачиваем его:

cd ~/stuff/build/conf/packages/linux/x86
wget http://openembedded.ru/wp-content/uploads/2009/01/defconfig

Далее собираем ядро. Для этого переходим в каталог ~/stuff/build и запускаем сборку ядра:

cd ~/stuff/build
export BBPATH="$HOME/stuff/build:$HOME/stuff/openembedded"
bitbake virtual/kernel

Сборка займет где-то полчаса-час в зависимости от мощности вашего компьютера. После ее завершения потребуется скопировать ядро в каталог ~/.VirtualBox/TFT, чтобы его смог найти загрузчик. Далее настроить загрузчик, так чтобы он грузил ядро и настроить NFS сервер, чтобы ядро смогло подключить корневую файловую систему. Начнем с ядра.

Ядро находится в каталоге ~/stuff/build/tmp/deploy/glibc/images/x86 и называется bzImage-x86.bin. Копируем его в ~/.VirtualBox/TFTP:

cd ~/.VirtualBox/TFTP
cp ~/stuff/build/tmp/deploy/glibc/images/x86/bzImage-x86.bin bzImage

Переходим к настройке загрузчика. Создаем каталог pxelinux.cfg (в нем загрузчик ищет файлы конфигурации):

mkdir ~/.VirtualBox/TFTP/pxelinux.cfg
cd ~/.VirtualBox/TFTP/pxelinux.cfg

Далее создаем файл конфигурации default следующего содержания:

prompt 0
default linux
timeout 5

label linux
kernel bzImage
append ip=dhcp root=/dev/nfs nfsroot=192.168.1.100:/var/lib/nfsroot

При этом:

  • 192.168.1.100 это ваш ip адрес (который настроен на вашем компьютере автоматически или в ручную)
  • /var/lib/nfsroot указывает где находится необходимая нам корневая файловая система.

Если вы сейчас попробуете загрузить виртуальную машину, то загрузчик найдет ядро и загрузит его. Ядро запустится, но не найдет корневую файловую систему и перейдет в kernel panic. Чтобы избежать этого необходимо установить и настроить nfs сервер.
Для установки запускаем команду:

sudo apt-get install nfs-kernel-server

затем настраиваем экспорт каталога, где будет находиться корневая файловая система, в /etc/exports. Для этого в файл exports требуется добавить строку следующего вида:

/var/lib/nfsroot        *(ro,insecure,all_squash,no_subtree_check)

В качестве каталога для корневой файловой системы я выбрал /var/lib/nfsroot. Его требуется создать и распаковать туда корневую файловую систему. Сделать это можно следующим образом:

sudo mkdir /var/lib/nfsroot
cd /var/lib/nfsroot
sudo tar -xvf ~/stuff/build/tmp/deploy/glibc/images/x86/helloworld-image-x86.tar

В результате каталог /var/lib/nfsroot будет содержать корневую файловую систему. Проверить все ли в порядке можно при помощи следующей команды:

$ ls -l
итого 4
drwxr-xr-x 2 root root   17 Дек 31 00:50 bin
drwxr-xr-x 2 root root 4096 Дек 31 00:50 dev
drwxr-xr-x 3 root root   42 Дек 31 00:50 etc
drwxr-xr-x 4 root root   26 Дек 31 00:50 usr

Если вы получили аналогичный вывод значит все в порядке.
Запускаем nfs сервер:

sudo /etc/init.d/nfs-kernel-server start

Теперь сновая запускаем виртуальную машину. После того как она включится, должен будет запустится загрузчик, затем он запустит ядро, а ядро подключит по nfs корневую файловую систему и запустит /bin/init который является символической ссылкой на программу helloworld. И в результате вы должны увидеть вот такую картину:

OpenEmbedded в VirtualBox - Hello World

Если вы ее видите, то поздравляю вас. Вы собрали первый дистрибутив на базе OpenEmbedded!
А в следующий раз я расскажу как собрать систему состояющую не только из helloworld.

PS: Оригинальные версии использованных материалов: Здравствуй, Мир! Сборка, Здравствуй, Мир! Запуск.

PPS: defconfig файл можно скачать еще здесь.