Обновление ядра на генту (Gentoo)

Вот и подошло время обновить ядро(kernel) на моем ноутбуке. Распечатка доступных ядер при помощи модуля kernel утилиты eselect только подтвердил эту гипотезу:

# eselect kernel list
Available kernel symlink targets:
  [1]   linux-2.6.30-gentoo-r4
  [2]   linux-2.6.31-gentoo-r6
  [3]   linux-2.6.32-gentoo-r7
  [4]   linux-2.6.36-gentoo-r5
  [5]   linux-2.6.38-gentoo-r5 *
  [6]   linux-2.6.38-gentoo-r6
  [7]   linux-2.6.38-gentoo-r7
  [8]   linux-2.6.39-gentoo-r3
  [9]   linux-3.0.6-gentoo
  [10]  linux-3.1.6-gentoo
  [11]  linux-3.2.1-gentoo-r2
  [12]  linux-3.2.12-gentoo
  [13]  linux-3.3.8-gentoo
  [14]  linux-3.4.9-gentoo
  [15]  linux-3.5.7-gentoo
  [16]  linux-3.6.11-gentoo

Судя по всему, обновление ядра это одно из занятий для которого у меня редко находился время. Так, что выбрав последнюю версию

# eselect kernel set 11
# ls -l /usr/src/linux
lrwxrwxrwx 1 root root 21 Feb 26 11:25 /usr/src/linux -> linux-3.2.1-gentoo-r2

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

# cd /usr/src/linux
# make menuconfig

Для своего старенького ноутбука модели samsung r70 мной используется следующая конфигурация:

General setup  --->
  <*> Kernel .config support
  [*]   Enable access to .config through /proc/config.gz


Processor type and features  ---> 
  [*] Symmetric multi-processing support

  Processor family (Generic-x86-64)  --->
    (X) Core 2/newer Xeon

  [*]   Intel MCE features


Device Drivers  --->
  <*> Multimedia support  --->
    <*>   Video For Linux 
    [*]   Video capture adapters (NEW)  ---> 
      [*]   V4L USB devices (NEW)  --->
	<*>   USB Video Class (UVC)

  <*> Sound card support  ---> 
    <*>   Advanced Linux Sound Architecture  ---> 
      [*]   PCI sound devices  ---> 
        <M>   Intel/SiS/nVidia/AMD/ALi AC97 Controller 
        <*>   Intel HD Audio  ---> 
          [*]   Support jack plugging notification via input layer

  Graphics support  --->
    -*- Support for frame buffer devices  --->
      [*]   Enable firmware EDID 
      [*]   VESA VGA graphics support
    
    Console display driver support  --->  
      <*> Framebuffer Console support 
      [*]   Map the console to the primary display device

  [*] Network device support  --->
    Wireless LAN  --->
      [*]   Wireless LAN (IEEE 802.11)  ---> 
        <M>   Intel Wireless Wifi 
	  [*]     Enable LED support in iwlagn and iwl3945 drivers 
	  [*]     Enable Spectrum Measurement in iwlagn driver
	  <M>     Intel Wireless WiFi Next Gen AGN (iwlagn)
	    [*]       Intel Wireless WiFi 4965AGN
    <*>   PPP (point-to-point protocol) support
    <*>     PPP support for async serial ports
    <*>     PPP support for sync tty ports
    <*>     PPP Deflate compression
    <*>     PPP BSD-Compress compression

  [*] USB support  --->
    <*>   OHCI HCD support
    <*>   UHCI HCD (most Intel and VIA) support
    <M>   USB Serial Converter support  --->
      [*]   USB Generic Serial Driver
      <M>   USB driver for GSM and CDMA modems
    <M>   USB Modem (CDC ACM) support


File systems  ---> 
  <M> FUSE (Filesystem in Userspace) support 

  Pseudo filesystems  ---> 
    -*- /proc file system support 
    [*] Virtual memory file system support (former shm fs) 

[*] Networking support  ---> 
    <*>   Bluetooth subsystem support  ---> 

После чего можно приступить к компиляции ядра и в случае успеха к интегрированию его модулей:

# make && make modules_install 

Переносим полученное ядро в папку, откуда будет происходить монтирования

# cp arch/x86_64/boot/bzImage /boot/kernel-3.2.1-gentoo-r2

Также необходимо перекомпилировать не входящие в ядро модули, например: графоческий драйвер от ndivia. Для этого мной используется утилита (sys-kernel/module-rebuild). Компиляция модулей инициируется командой:

module-rebuild  rebuild

На конечном этапе остается настроить менеджер загрузки

 # vim /boot/grub/menu.lst 

добавив к списку новое ядро, моя настройки выглядит следующим образом:

title Gentoo Linux 3.2.1-r2
root (hd0,6)
kernel /boot/kernel-3.2.1-gentoo-r2 root=/dev/sda7 video=vesafb:mtrr:3,ywrap vga=865

Осталось только перезапустить систему и проверить все ли получилось

# uname -r
3.2.1-gentoo-r2

настройка встроенного устройства для чтения SD-карт (“кардреадер”)
Оказывается что использование следующей утилиты достаточно что-бы определить устройство:

# lspci
00:00.0 Host bridge: Intel Corporation Mobile PM965/GM965/GL960 Memory Controller Hub (rev 03)
00:01.0 PCI bridge: Intel Corporation Mobile PM965/GM965/GL960 PCI Express Root Port (rev 03)
00:1a.0 USB controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #4 (rev 03)
00:1a.1 USB controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #5 (rev 03)
00:1a.7 USB controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI Controller #2 (rev 03)
00:1b.0 Audio device: Intel Corporation 82801H (ICH8 Family) HD Audio Controller (rev 03)
00:1c.0 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 1 (rev 03)
00:1c.1 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 2 (rev 03)
00:1c.3 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 4 (rev 03)
00:1d.0 USB controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #1 (rev 03)
00:1d.1 USB controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #2 (rev 03)
00:1d.2 USB controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #3 (rev 03)
00:1d.7 USB controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI Controller #1 (rev 03)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev f3)
00:1f.0 ISA bridge: Intel Corporation 82801HM (ICH8M) LPC Interface Controller (rev 03)
00:1f.2 IDE interface: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (rev 03)
00:1f.3 SMBus: Intel Corporation 82801H (ICH8 Family) SMBus Controller (rev 03)
01:00.0 VGA compatible controller: nVidia Corporation G86 [GeForce 8600M GS] (rev a1)
03:00.0 Network controller: Intel Corporation PRO/Wireless 4965 AG or AGN [Kedron] Network Connection (rev 61)
04:00.0 Ethernet controller: Marvell Technology Group Ltd. 88E8055 PCI-E Gigabit Ethernet Controller (rev 13)
05:09.0 CardBus bridge: Ricoh Co Ltd RL5c476 II (rev b4)
05:09.1 SD Host controller: Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (rev 18)
05:09.2 System peripheral: Ricoh Co Ltd R5C592 Memory Stick Bus Host Adapter (rev 09)
05:09.3 System peripheral: Ricoh Co Ltd xD-Picture Card Controller (rev 04)

после чего осталось только активировать ниже перечисленные модули

Device Drivers  --->
  <*> MMC/SD/SDIO card support  --->
    <*>   MMC block device driver (NEW)
    <M>   Secure Digital Host Controller Interface support
    <M>   SDHCI support on PCI bus 
    [*]     Ricoh MMC Controller Disabler  (EXPERIMENTAL)

и устройства начинает работать.

Для sys-fs/udev-197 необходимо включить опцию DEVTMPFS

Device Drivers  --->
  Generic Driver Options  --->
    [*] Maintain a devtmpfs filesystem to mount at /dev     
 

Для sys-fs/udisks-1.0.4-r4 необходимо включить опцию USB_SUSPEND

 Power management and ACPI options  --->
  [*] Run-time PM core functionality 
Device Drivers  ---> 
  [*] USB support  --->
    [*]     USB runtime power management (autosuspend) and wakeup
 
Advertisements

“Hello World” example in Vala using Gtk+3

screenshot of gtk3 based vala example
Today I decided to rewrite a simple code of the “Hello World” example written in python by Micah Carrick almost a year ago. And I decided to do it in Vala! Vala has a modern syntax, compared to C# or java and brings many useful object oriented features. Vala’s compiler named “valac” translates your written code and based on it generates a C output, which it then compiles. I frequently observed how this project emerges, because I was fascinated by this idea from the beginning and soon realized, that I like to write in Vala myself too. Especially as I saw that the quadrapassel’s game code (a tetrix derivate in GNOME) was moved from C++ to Vala. So, here is a code of “hello_world.vala”:

namespace TestingWorld {
	class HelloWorld : Gtk.Application {
		public HelloWorld( ) {
			Object( application_id: "testing.hello.world",
					flags: ApplicationFlags.FLAGS_NONE );
		}
		
		public override void activate( ) {
			var window = new Gtk.Window( );
			window.set_title( "Gtk3 Vala Example" );
			window.set_default_size( 250, -1 );
			window.set_border_width( 24 );
			window.destroy.connect( () => { Gtk.main_quit( ); } );

			var label = new Gtk.Label( "Hello World!\nМиру Мир!" );
			window.add( label );
			window.show_all( );
			this.add_window( window );
		}

		public static void main( string[] args ) {
			var app = new HelloWorld( );
			app.run( );
		}
	}
}

This tiny example can be easily compiled with:

valac hello_world.vala --pkg gtk+-3.0 

Here, the created class “HelloWorld” is inherited from the Gtk.Application, which should replace the libunique functionallity. By providing a “application_id”, all the later launched instances join the same main loop. So, once you destroy it with “Gtk.main_quit”, all running application instances will be terminated. The “Gtk.Application”, additionally, provides many more usefull features, such as communication between running application instances.
If you do not like to write “Gtk.” every time when referring to classes from the GTK+ library, you can insert

 using Gtk;

at the beginning of the file. By doing so, you can omit the need of specifying the work space from where the classes you would like to use comes from. For example, you can then just write for the line number 15 the following:

 var label = new Label( "Hello World!" );

Why can’t I chain up to base constructor?

Deriving a custom class from GObject

This post demonstrates how to create a custom class derived from GObject. In this example it is a class named “Hamster”. Furthermore, it is shown, how to define a private class members, in this case the “name” of the hamster. The way custom properties can be defined is also illustrated.
There is no much explanation yet, so consider it as a work in progress…

source code of the header file mz-hamster.h:

#ifndef __MZ_HAMSTER_H__
#define __MZ_HAMSTER_H__

#include <glib-object.h>

G_BEGIN_DECLS

#define MZ_TYPE_HAMSTER			( mz_hamster_get_type( ) )
#define MZ_HAMSTER( obj )		( G_TYPE_CHECK_INSTANCE_CAST( (obj), MZ_TYPE_HAMSTER, MzHamster ) )
#define MZ_IS_HAMSTER( obj )		( G_TYPE_CHECK_INSTANCE_TYPE( (obj), MZ_TYPE_HAMSTER ) )
#define MZ_HAMSTER_CLASS( klass )	( G_TYPE_CHECK_CLASS_CAST( (klass), MZ_TYPE_HAMSTER, MzHamsterClass ) )
#define MZ_IS_HAMSTER_CLASS( klass )	( G_TYPE_CHECK_CLASS_TYPE( (klass), MZ_TYPE_HAMSTER ) )
#define MZ_HAMSTER_GET_CLASS( obj )	( G_TYPE_INSTANCE_GET_CLASS( (obj), MZ_TYPE_HAMSTER, MzHamsterClass ) )

typedef struct _MzHamster      MzHamster;
typedef struct _MzHamsterClass MzHamsterClass;

struct _MzHamster
{
  GObject parent;
};

struct _MzHamsterClass
{
  GObjectClass parent_class;
};

GType mz_hamster_get_type( void ) G_GNUC_CONST;

MzHamster * mz_hamster_new( const gchar *name );

gchar * mz_hamster_get_name( MzHamster *hamster );
void mz_hamster_set_name( MzHamster *hamster, const gchar *name );

G_END_DECLS

#endif	/* __MZ_HAMSTER_H__ */

source code of mz-hamster.c:

#include <glib/gprintf.h>
#include "mz-hamster.h"

#define MZ_HAMSTER_GET_PRIVATE( obj )	  ( G_TYPE_INSTANCE_GET_PRIVATE( (obj), MZ_TYPE_HAMSTER, MzHamsterPrivate ) )

G_DEFINE_TYPE( MzHamster, mz_hamster, G_TYPE_OBJECT )

typedef struct _MzHamsterPrivate MzHamsterPrivate;

struct _MzHamsterPrivate
{
  gchar *name;
};

enum
{
  PROP_0,

  PROP_NAME
};

static void mz_hamster_finalize( GObject *hamster );

static void
mz_hamster_set_property( GObject *object,
			 guint prop_id,
			 const GValue *value,
			 GParamSpec *pspec );

static void
mz_hamster_get_property( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec );

static void 
mz_hamster_class_init( MzHamsterClass *klass )
{
  GObjectClass *gobject_class = G_OBJECT_CLASS( klass );

  gobject_class->finalize = mz_hamster_finalize;

  g_type_class_add_private( klass, sizeof( MzHamsterPrivate ) );

  gobject_class->get_property = mz_hamster_get_property;
  gobject_class->set_property = mz_hamster_set_property;

  g_object_class_install_property( gobject_class,
				   PROP_NAME,
				   g_param_spec_string( "name",
							"Name",
							"hamster's name",
							NULL,
							G_PARAM_READWRITE ) );
}

static void
mz_hamster_init( MzHamster *hamster )
{
  MzHamsterPrivate *priv = MZ_HAMSTER_GET_PRIVATE( hamster );

  g_printf( "...instance init" );

  priv->name = g_strdup( "unnamed" );
}
  
static void
mz_hamster_finalize( GObject *object )
{
  MzHamster *hamster = MZ_HAMSTER( object );
  MzHamsterPrivate *priv = MZ_HAMSTER_GET_PRIVATE( hamster );
  GObjectClass *parent_class = G_OBJECT_CLASS( mz_hamster_parent_class );

  g_printf( "...instance finalize\n" );

  g_free( priv->name );

  ( *parent_class->finalize )( object );
}

MzHamster *
mz_hamster_new( const gchar *name )
{
  MzHamster *hamster;

  hamster = MZ_HAMSTER( g_object_new( MZ_TYPE_HAMSTER, NULL ) );

  if( name != NULL )
    mz_hamster_set_name( hamster, name );
  
  return hamster;
}

gchar *
mz_hamster_get_name( MzHamster *hamster )
{
  MzHamsterPrivate *priv;
  
  g_return_val_if_fail( MZ_IS_HAMSTER( hamster ), NULL );

  priv = MZ_HAMSTER_GET_PRIVATE( hamster );

  return g_strdup( priv->name );
}

void
mz_hamster_set_name( MzHamster *hamster, const gchar *name )
{
  MzHamsterPrivate *priv;
  
  g_return_if_fail( name );
  g_return_if_fail( MZ_IS_HAMSTER( hamster ) );

  priv = MZ_HAMSTER_GET_PRIVATE( hamster );

  if( priv->name != NULL )
    g_free( priv->name );

  priv->name = g_strdup( name );
}

static void
mz_hamster_set_property( GObject *object,
			 guint prop_id,
			 const GValue *value,
			 GParamSpec *pspec )
{
  MzHamster *hamster = MZ_HAMSTER( object );

  switch( prop_id ) {
    case PROP_NAME:
      mz_hamster_set_name( hamster, g_value_get_string( value ) );
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
  }
}
      
static void
mz_hamster_get_property( GObject *object,
			 guint prop_id,
			 GValue *value,
			 GParamSpec *pspec )
{
  MzHamster *hamster = MZ_HAMSTER( object );

  switch( prop_id ) {
    case PROP_NAME:
      g_value_set_string( value, mz_hamster_get_name( hamster ) );
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
  }
}

main.c file:

#include <glib-object.h>
#include <glib/gprintf.h>

#include "mz-hamster.h"

int main( void )
{
  MzHamster *hamster;
  gchar *name;
  GValue value = { 0, };	/* GValue instance must contain zeros! */

  g_type_init( );

  hamster = mz_hamster_new( NULL );
  
  name = mz_hamster_get_name( hamster );
  g_printf( "name: %s\n", name );
  g_free( name );

  mz_hamster_set_name( hamster, "хoмяк" );
  name = mz_hamster_get_name( hamster );
  g_printf( "new name: %s\n", name );

  g_free( name );
  g_object_unref( G_OBJECT( hamster ) );
  
  g_printf( "bye!\n" );

  g_printf( "...checking properties...\n" );
  hamster = mz_hamster_new ( "karry" );
  
  g_value_init( &value, G_TYPE_STRING );
  g_value_set_string( &value, "papa" );
  g_object_set_property( G_OBJECT( hamster ), "name", &value );
  name = mz_hamster_get_name( hamster );
  g_printf( "new name: %s\n", name ); 
  
  mz_hamster_set_name( hamster, "mama" );
  g_object_get_property( G_OBJECT( hamster ), "name", &value );
  name = g_value_dup_string( &value );
  g_printf( "another hamster named: %s\n", name );
  
  return 0;
}

makefile:

SHELL=/bin/bash

deps=$(shell pkg-config --libs --cflags gobject-2.0 )
flags=-Wall -pedantic

hamster: main.c mzhamster.o
	gcc -o $@ $^ ${deps} ${flags}

%.o: %.c %.h
	gcc -o $@ -c $< ${deps} ${flags}

clean:
	rm -rf *.o hamster

output from the shell:

$ ./hamster 
...instance init
name: unnamed
new name: хoмяк
...instance finalize
bye!
...checking properties...
...instance init
new name: papa
another hamster named: mama

In the object oriented language like Vala this example looks rather trivial (property.vala):

namespace Mz {
	public class Hamster : Object {
		// Definition of a property with a standard get and set methods
		public string name { get; set; }
		
		public Hamster( string name = "unnamed" ) {
			stdout.printf( "...instance init\n" );
			Object( name: name );
		}
		
		// Destructor
		~Hamster( ) {
			stdout.printf( "...instance named %s is finalized\n", this.name );
		}
		
		public static void main( string[] args ) {
			var hamster = new Hamster( );
			
			stdout.printf( "name: %s\n", hamster.name );
			
			hamster.name = "хoмяк";
			stdout.printf( "new name: %s\n", hamster.name );
			
			hamster = new Hamster( "karry" );
			stdout.printf( "bye\n" );
			
			stdout.printf( "...checking properties...\n" );
			Value svalue = "papa";
			hamster.set_property( "name", svalue );
			stdout.printf( "new name: %s\n", hamster.name );
			
			hamster.set( "name", "mama" );
			string name;
			hamster.get( "name", out name );
			stdout.printf( "another hamster named: %s\n", name );
		}
	}
}

This one can be easiliar compiled with:

valac-0.14 property.vala

Vala compiler is also able to generate the corresponding C code by invoiking the command:

 valac-0.14 property.vala --ccode

By doing so the file “property.c” will be created containing a similiar C code, introduced above. There are more detailed examples how properties can be defined in Vala, shown here. Line 28 shows, that Vala has a build-in auto-(un)boxing support for Glib’s Value structure, which saves you from writing the following lines:

// to initialize structures no "new" keyword is needed 
Value svalue = Value( typeof( string ) );
svalue.set_string( "papa" );

Further examples of using GLib.Value structure can be found here.

By comparing the amount of code needed to create a custom class written in C with the code written in a object-oriented language like python, C++ or Vala very often the question arises: “What is the benefit of writing so many complicated at the first look and unnecessary lines of code in C to create a class, if in another language it is almost a trivial task?”

If one knows the background hiding behind this decision to still write in C, it’s very easy to understand this situation. First of all, C is a very tiny programming language without any modern language features. It’s available almost on every device, and if not, it can be rather easily integrated than other heavier languages. Additionally, big part of gnu/linux based operating systems are written in C, including a rich collections of libraries, which can be integrated in the new C based projects. GObject, on the other side, is the one of the possible ways bringing the object-oriented capabilities to the C programming language, which allows the use of the modern design. The model used in GObject should in first place simplify the construction and intregration of binding to another languages, so the libraries on top of it, e.g. Gtk+, can be easily used to create window based applications.