Ticket #2185: src_system_kernel_main.cpp.diff

File src_system_kernel_main.cpp.diff, 19.3 KB (added by kaoutsis, 16 years ago)
  • headers/private/kernel/kernel_daemon.h

     
    1414#endif
    1515status_t kernel_daemon_init(void);
    1616
    17 #endif  /* _KRENEL_DAEMON_H */
     17#endif  /* _KERNEL_DAEMON_H */
  • src/system/kernel/Jamfile

     
    2929    kernel_daemon.cpp
    3030    linkhack.c
    3131    lock.cpp
    32     main.c
     32    main.cpp
    3333    module.cpp
    3434    Notifications.cpp
    3535    port.cpp
  • src/system/kernel/main.c

     
    1 /*
    2  * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
    3  * Distributed under the terms of the MIT License.
    4  *
    5  * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
    6  * Distributed under the terms of the NewOS License.
    7  */
    8 
    9 /*! This is main - initializes the kernel and launches the Bootscript */
    10 
    11 
    12 #include <OS.h>
    13 
    14 #include <arch/platform.h>
    15 #include <boot_item.h>
    16 #include <boot_splash.h>
    17 #include <cbuf.h>
    18 #include <commpage.h>
    19 #include <condition_variable.h>
    20 #include <cpu.h>
    21 #include <debug.h>
    22 #include <elf.h>
    23 #include <fs/devfs.h>
    24 #include <int.h>
    25 #include <kdevice_manager.h>
    26 #include <kdriver_settings.h>
    27 #include <kernel_daemon.h>
    28 #include <kmodule.h>
    29 #include <kscheduler.h>
    30 #include <ksyscalls.h>
    31 #include <lock.h>
    32 #include <messaging.h>
    33 #include <Notifications.h>
    34 #include <port.h>
    35 #include <posix/realtime_sem.h>
    36 #include <real_time_clock.h>
    37 #include <sem.h>
    38 #include <smp.h>
    39 #include <system_info.h>
    40 #include <team.h>
    41 #include <timer.h>
    42 #include <user_debugger.h>
    43 #include <vfs.h>
    44 #include <vm.h>
    45 #include <boot/kernel_args.h>
    46 
    47 #include <string.h>
    48 
    49 
    50 //#define TRACE_BOOT
    51 #ifdef TRACE_BOOT
    52 #   define TRACE(x...) dprintf("INIT: " x)
    53 #else
    54 #   define TRACE(x...) ;
    55 #endif
    56 
    57 bool kernel_startup = true;
    58 
    59 static kernel_args sKernelArgs;
    60 static uint32 sCpuRendezvous;
    61 static uint32 sCpuRendezvous2;
    62 
    63 static int32 main2(void *);
    64 int _start(kernel_args *bootKernelArgs, int cpu);   /* keep compiler happy */
    65 
    66 
    67 int
    68 _start(kernel_args *bootKernelArgs, int currentCPU)
    69 {
    70     if (bootKernelArgs->kernel_args_size != sizeof(kernel_args)
    71         || bootKernelArgs->version != CURRENT_KERNEL_ARGS_VERSION) {
    72         // This is something we cannot handle right now - release kernels
    73         // should always be able to handle the kernel_args of earlier
    74         // released kernels.
    75         debug_early_boot_message("Version mismatch between boot loader and "
    76             "kernel!\n");
    77         return -1;
    78     }
    79 
    80     smp_set_num_cpus(bootKernelArgs->num_cpus);
    81 
    82     // wait for all the cpus to get here
    83     smp_cpu_rendezvous(&sCpuRendezvous, currentCPU);
    84 
    85     // the passed in kernel args are in a non-allocated range of memory
    86     if (currentCPU == 0)
    87         memcpy(&sKernelArgs, bootKernelArgs, sizeof(kernel_args));
    88 
    89     smp_cpu_rendezvous(&sCpuRendezvous2, currentCPU);
    90 
    91     // do any pre-booting cpu config
    92     cpu_preboot_init_percpu(&sKernelArgs, currentCPU);
    93     thread_preboot_init_percpu(&sKernelArgs, currentCPU);
    94 
    95     // if we're not a boot cpu, spin here until someone wakes us up
    96     if (smp_trap_non_boot_cpus(currentCPU)) {
    97         thread_id thread;
    98 
    99         // init platform
    100         arch_platform_init(&sKernelArgs);
    101 
    102         // setup debug output
    103         debug_init(&sKernelArgs);
    104         set_dprintf_enabled(true);
    105         dprintf("Welcome to kernel debugger output!\n");
    106         dprintf("Haiku revision: %lu\n", get_haiku_revision());
    107 
    108         // init modules
    109         TRACE("init CPU\n");
    110         cpu_init(&sKernelArgs);
    111         cpu_init_percpu(&sKernelArgs, currentCPU);
    112         TRACE("init interrupts\n");
    113         int_init(&sKernelArgs);
    114 
    115         TRACE("init VM\n");
    116         vm_init(&sKernelArgs);
    117             // Before vm_init_post_sem() is called, we have to make sure that
    118             // the boot loader allocated region is not used anymore
    119 
    120         // now we can use the heap and create areas
    121         arch_platform_init_post_vm(&sKernelArgs);
    122         lock_debug_init();
    123         TRACE("init driver_settings\n");
    124         boot_item_init();
    125         driver_settings_init(&sKernelArgs);
    126         debug_init_post_vm(&sKernelArgs);
    127         int_init_post_vm(&sKernelArgs);
    128         cpu_init_post_vm(&sKernelArgs);
    129         commpage_init();
    130         TRACE("init system info\n");
    131         system_info_init(&sKernelArgs);
    132 
    133         TRACE("init SMP\n");
    134         smp_init(&sKernelArgs);
    135         TRACE("init timer\n");
    136         timer_init(&sKernelArgs);
    137         TRACE("init real time clock\n");
    138         rtc_init(&sKernelArgs);
    139 
    140         TRACE("init semaphores\n");
    141         haiku_sem_init(&sKernelArgs);
    142         condition_variable_init();
    143 
    144         // now we can create and use semaphores
    145         TRACE("init VM semaphores\n");
    146         vm_init_post_sem(&sKernelArgs);
    147         TRACE("init driver_settings\n");
    148         driver_settings_init_post_sem(&sKernelArgs);
    149         TRACE("init generic syscall\n");
    150         generic_syscall_init();
    151         TRACE("init cbuf\n");
    152         cbuf_init();
    153         TRACE("init teams\n");
    154         team_init(&sKernelArgs);
    155         TRACE("init threads\n");
    156         thread_init(&sKernelArgs);
    157         TRACE("init ports\n");
    158         port_init(&sKernelArgs);
    159         TRACE("init kernel daemons\n");
    160         kernel_daemon_init();
    161         arch_platform_init_post_thread(&sKernelArgs);
    162         realtime_sem_init();
    163 
    164         TRACE("init VM threads\n");
    165         vm_init_post_thread(&sKernelArgs);
    166         TRACE("init ELF loader\n");
    167         elf_init(&sKernelArgs);
    168         TRACE("init scheduler\n");
    169         scheduler_init();
    170         TRACE("init notification services\n");
    171         notifications_init();
    172         TRACE("init VFS\n");
    173         vfs_init(&sKernelArgs);
    174 
    175         // bring up the AP cpus in a lock step fashion
    176         TRACE("waking up AP cpus\n");
    177         sCpuRendezvous = sCpuRendezvous2 = 0;
    178         smp_wake_up_non_boot_cpus();
    179         smp_cpu_rendezvous(&sCpuRendezvous, 0); // wait until they're booted
    180 
    181         // exit the kernel startup phase (mutexes, etc work from now on out)
    182         TRACE("exiting kernel startup\n");
    183         kernel_startup = false;
    184 
    185         smp_cpu_rendezvous(&sCpuRendezvous2, 0);
    186             // release the AP cpus to go enter the scheduler
    187 
    188         TRACE("enabling interrupts and starting scheduler on cpu 0\n");
    189         enable_interrupts();
    190         scheduler_start();
    191 
    192         // start a thread to finish initializing the rest of the system
    193         TRACE("starting main2 thread\n");
    194         thread = spawn_kernel_thread(&main2, "main2", B_NORMAL_PRIORITY, NULL);
    195         TRACE("resuming main2 thread...\n");
    196         resume_thread(thread);
    197     } else {
    198         // lets make sure we're in sync with the main cpu
    199         // the boot processor has probably been sending us
    200         // tlb sync messages all along the way, but we've
    201         // been ignoring them
    202         arch_cpu_global_TLB_invalidate();
    203 
    204         // this is run for each non boot processor after they've been set loose
    205         cpu_init_percpu(&sKernelArgs, currentCPU);
    206         smp_per_cpu_init(&sKernelArgs, currentCPU);
    207 
    208         // wait for all other AP cpus to get to this point
    209         smp_cpu_rendezvous(&sCpuRendezvous, currentCPU);
    210         smp_cpu_rendezvous(&sCpuRendezvous2, currentCPU);
    211 
    212         // welcome to the machine
    213         enable_interrupts();
    214         scheduler_start();
    215     }
    216 
    217     TRACE("main: done... begin idle loop on cpu %d\n", currentCPU);
    218     for (;;)
    219         arch_cpu_idle();
    220 
    221     return 0;
    222 }
    223 
    224 static int32
    225 main2(void *unused)
    226 {
    227     (void)(unused);
    228 
    229     TRACE("start of main2: initializing devices\n");
    230 
    231     boot_splash_init(sKernelArgs.boot_splash);
    232 
    233     TRACE("Init modules\n");
    234     boot_splash_set_stage(BOOT_SPLASH_STAGE_1_INIT_MODULES);
    235     module_init(&sKernelArgs);
    236 
    237     // ToDo: the preloaded image debug data is placed in the kernel args, and
    238     //  thus, if they are enabled, the kernel args shouldn't be freed, so
    239     //  that we don't have to copy them.
    240     //  What is yet missing is a mechanism that controls this (via driver settings).
    241     if (0) {
    242         // module_init() is supposed to be the last user of the kernel args
    243         // Note: don't confuse the kernel_args structure (which is never freed)
    244         // with the kernel args ranges it contains (and which are freed here).
    245         vm_free_kernel_args(&sKernelArgs);
    246     }
    247 
    248     // init userland debugging
    249     TRACE("Init Userland debugging\n");
    250     init_user_debug();
    251 
    252     // init the messaging service
    253     TRACE("Init Messaging Service\n");
    254     init_messaging_service();
    255 
    256     /* bootstrap all the filesystems */
    257     TRACE("Bootstrap file systems\n");
    258     boot_splash_set_stage(BOOT_SPLASH_STAGE_2_BOOTSTRAP_FS);
    259     vfs_bootstrap_file_systems();
    260 
    261     TRACE("Init Device Manager\n");
    262     boot_splash_set_stage(BOOT_SPLASH_STAGE_3_INIT_DEVICES);
    263     device_manager_init(&sKernelArgs);
    264 
    265     TRACE("Add preloaded old-style drivers\n");
    266     devfs_add_preloaded_drivers(&sKernelArgs);
    267 
    268     int_init_post_device_manager(&sKernelArgs);
    269 
    270     TRACE("Mount boot file system\n");
    271     boot_splash_set_stage(BOOT_SPLASH_STAGE_4_MOUNT_BOOT_FS);
    272     vfs_mount_boot_file_system(&sKernelArgs);
    273 
    274     // CPU specific modules may now be available
    275     boot_splash_set_stage(BOOT_SPLASH_STAGE_5_INIT_CPU_MODULES);
    276     cpu_init_post_modules(&sKernelArgs);
    277 
    278     TRACE("vm_init_post_modules\n");
    279     boot_splash_set_stage(BOOT_SPLASH_STAGE_6_INIT_VM_MODULES);
    280     vm_init_post_modules(&sKernelArgs);
    281 
    282     TRACE("debug_init_post_modules\n");
    283     debug_init_post_modules(&sKernelArgs);
    284 
    285     TRACE("device_manager_init_post_modules\n");
    286     device_manager_init_post_modules(&sKernelArgs);
    287 
    288     boot_splash_set_stage(BOOT_SPLASH_STAGE_7_RUN_BOOT_SCRIPT);
    289 //  kernel_args_free(sKernelArgs.boot_splash);
    290 // NOTE: We could introduce a syscall to draw more icons indicating
    291 // stages in the boot script itself. Then we should not free the image.
    292 
    293     // start the init process
    294     {
    295         const char *args[] = {"/bin/sh", "/boot/beos/system/boot/Bootscript",
    296             NULL};
    297         int32 argc = 2;
    298         thread_id thread;
    299 
    300         thread = load_image(argc, args, NULL);
    301         if (thread >= B_OK) {
    302             resume_thread(thread);
    303             TRACE("Bootscript started\n");
    304         } else
    305             dprintf("error starting \"%s\" error = %ld \n", args[0], thread);
    306     }
    307 
    308     return 0;
    309 }
    310 
  • src/system/kernel/main.cpp

     
     1/*
     2 * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
     6 * Distributed under the terms of the NewOS License.
     7 */
     8
     9/*! This is main - initializes the kernel and launches the Bootscript */
     10
     11
     12#include <OS.h>
     13
     14#include <arch/platform.h>
     15#include <boot_device.h>
     16#include <boot_item.h>
     17#include <boot_splash.h>
     18#include <cbuf.h>
     19#include <commpage.h>
     20#include <condition_variable.h>
     21#include <cpu.h>
     22#include <debug.h>
     23#include <elf.h>
     24#include <fs/devfs.h>
     25#include <fs/KPath.h>
     26#include <FindDirectory.h>
     27#include <int.h>
     28#include <kdevice_manager.h>
     29#include <kdriver_settings.h>
     30#include <kernel_daemon.h>
     31#include <kmodule.h>
     32#include <kscheduler.h>
     33#include <ksyscalls.h>
     34#include <lock.h>
     35#include <messaging.h>
     36#include <Notifications.h>
     37#include <port.h>
     38#include <posix/realtime_sem.h>
     39#include <real_time_clock.h>
     40#include <sem.h>
     41#include <smp.h>
     42#include <system_info.h>
     43#include <team.h>
     44#include <timer.h>
     45#include <user_debugger.h>
     46#include <vfs.h>
     47#include <vm.h>
     48#include <boot/kernel_args.h>
     49
     50#include <string.h>
     51
     52
     53//#define TRACE_BOOT
     54#ifdef TRACE_BOOT
     55#   define TRACE(x...) dprintf("INIT: " x)
     56#else
     57#   define TRACE(x...) ;
     58#endif
     59
     60bool kernel_startup = true;
     61
     62static kernel_args sKernelArgs;
     63static uint32 sCpuRendezvous;
     64static uint32 sCpuRendezvous2;
     65
     66static int32 main2(void *);
     67
     68#ifdef  __cplusplus
     69extern "C" {
     70#endif
     71
     72extern int _start(kernel_args *bootKernelArgs, int cpu);    /* keep compiler happy */
     73
     74#ifdef __cplusplus
     75} /* extern "C" */
     76
     77#endif
     78
     79int
     80_start(kernel_args *bootKernelArgs, int currentCPU)
     81{
     82    if (bootKernelArgs->kernel_args_size != sizeof(kernel_args)
     83        || bootKernelArgs->version != CURRENT_KERNEL_ARGS_VERSION) {
     84        // This is something we cannot handle right now - release kernels
     85        // should always be able to handle the kernel_args of earlier
     86        // released kernels.
     87        debug_early_boot_message("Version mismatch between boot loader and "
     88            "kernel!\n");
     89        return -1;
     90    }
     91
     92    smp_set_num_cpus(bootKernelArgs->num_cpus);
     93
     94    // wait for all the cpus to get here
     95    smp_cpu_rendezvous(&sCpuRendezvous, currentCPU);
     96
     97    // the passed in kernel args are in a non-allocated range of memory
     98    if (currentCPU == 0)
     99        memcpy(&sKernelArgs, bootKernelArgs, sizeof(kernel_args));
     100
     101    smp_cpu_rendezvous(&sCpuRendezvous2, currentCPU);
     102
     103    // do any pre-booting cpu config
     104    cpu_preboot_init_percpu(&sKernelArgs, currentCPU);
     105    thread_preboot_init_percpu(&sKernelArgs, currentCPU);
     106
     107    // if we're not a boot cpu, spin here until someone wakes us up
     108    if (smp_trap_non_boot_cpus(currentCPU)) {
     109        thread_id thread;
     110
     111        // init platform
     112        arch_platform_init(&sKernelArgs);
     113
     114        // setup debug output
     115        debug_init(&sKernelArgs);
     116        set_dprintf_enabled(true);
     117        dprintf("Welcome to kernel debugger output!\n");
     118        dprintf("Haiku revision: %lu\n", get_haiku_revision());
     119
     120        // init modules
     121        TRACE("init CPU\n");
     122        cpu_init(&sKernelArgs);
     123        cpu_init_percpu(&sKernelArgs, currentCPU);
     124        TRACE("init interrupts\n");
     125        int_init(&sKernelArgs);
     126
     127        TRACE("init VM\n");
     128        vm_init(&sKernelArgs);
     129            // Before vm_init_post_sem() is called, we have to make sure that
     130            // the boot loader allocated region is not used anymore
     131
     132        // now we can use the heap and create areas
     133        arch_platform_init_post_vm(&sKernelArgs);
     134        lock_debug_init();
     135        TRACE("init driver_settings\n");
     136        boot_item_init();
     137        driver_settings_init(&sKernelArgs);
     138        debug_init_post_vm(&sKernelArgs);
     139        int_init_post_vm(&sKernelArgs);
     140        cpu_init_post_vm(&sKernelArgs);
     141        commpage_init();
     142        TRACE("init system info\n");
     143        system_info_init(&sKernelArgs);
     144
     145        TRACE("init SMP\n");
     146        smp_init(&sKernelArgs);
     147        TRACE("init timer\n");
     148        timer_init(&sKernelArgs);
     149        TRACE("init real time clock\n");
     150        rtc_init(&sKernelArgs);
     151
     152        TRACE("init semaphores\n");
     153        haiku_sem_init(&sKernelArgs);
     154        condition_variable_init();
     155
     156        // now we can create and use semaphores
     157        TRACE("init VM semaphores\n");
     158        vm_init_post_sem(&sKernelArgs);
     159        TRACE("init driver_settings\n");
     160        driver_settings_init_post_sem(&sKernelArgs);
     161        TRACE("init generic syscall\n");
     162        generic_syscall_init();
     163        TRACE("init cbuf\n");
     164        cbuf_init();
     165        TRACE("init teams\n");
     166        team_init(&sKernelArgs);
     167        TRACE("init threads\n");
     168        thread_init(&sKernelArgs);
     169        TRACE("init ports\n");
     170        port_init(&sKernelArgs);
     171        TRACE("init kernel daemons\n");
     172        kernel_daemon_init();
     173        arch_platform_init_post_thread(&sKernelArgs);
     174        realtime_sem_init();
     175
     176        TRACE("init VM threads\n");
     177        vm_init_post_thread(&sKernelArgs);
     178        TRACE("init ELF loader\n");
     179        elf_init(&sKernelArgs);
     180        TRACE("init scheduler\n");
     181        scheduler_init();
     182        TRACE("init notification services\n");
     183        notifications_init();
     184        TRACE("init VFS\n");
     185        vfs_init(&sKernelArgs);
     186
     187        // bring up the AP cpus in a lock step fashion
     188        TRACE("waking up AP cpus\n");
     189        sCpuRendezvous = sCpuRendezvous2 = 0;
     190        smp_wake_up_non_boot_cpus();
     191        smp_cpu_rendezvous(&sCpuRendezvous, 0); // wait until they're booted
     192
     193        // exit the kernel startup phase (mutexes, etc work from now on out)
     194        TRACE("exiting kernel startup\n");
     195        kernel_startup = false;
     196
     197        smp_cpu_rendezvous(&sCpuRendezvous2, 0);
     198            // release the AP cpus to go enter the scheduler
     199
     200        TRACE("enabling interrupts and starting scheduler on cpu 0\n");
     201        enable_interrupts();
     202        scheduler_start();
     203
     204        // start a thread to finish initializing the rest of the system
     205        TRACE("starting main2 thread\n");
     206        thread = spawn_kernel_thread(&main2, "main2", B_NORMAL_PRIORITY, NULL);
     207        TRACE("resuming main2 thread...\n");
     208        resume_thread(thread);
     209    } else {
     210        // lets make sure we're in sync with the main cpu
     211        // the boot processor has probably been sending us
     212        // tlb sync messages all along the way, but we've
     213        // been ignoring them
     214        arch_cpu_global_TLB_invalidate();
     215
     216        // this is run for each non boot processor after they've been set loose
     217        cpu_init_percpu(&sKernelArgs, currentCPU);
     218        smp_per_cpu_init(&sKernelArgs, currentCPU);
     219
     220        // wait for all other AP cpus to get to this point
     221        smp_cpu_rendezvous(&sCpuRendezvous, currentCPU);
     222        smp_cpu_rendezvous(&sCpuRendezvous2, currentCPU);
     223
     224        // welcome to the machine
     225        enable_interrupts();
     226        scheduler_start();
     227    }
     228
     229    TRACE("main: done... begin idle loop on cpu %d\n", currentCPU);
     230    for (;;)
     231        arch_cpu_idle();
     232
     233    return 0;
     234}
     235
     236static int32
     237main2(void *unused)
     238{
     239    (void)(unused);
     240
     241    TRACE("start of main2: initializing devices\n");
     242
     243    boot_splash_init(sKernelArgs.boot_splash);
     244
     245    TRACE("Init modules\n");
     246    boot_splash_set_stage(BOOT_SPLASH_STAGE_1_INIT_MODULES);
     247    module_init(&sKernelArgs);
     248
     249    // ToDo: the preloaded image debug data is placed in the kernel args, and
     250    //  thus, if they are enabled, the kernel args shouldn't be freed, so
     251    //  that we don't have to copy them.
     252    //  What is yet missing is a mechanism that controls this (via driver settings).
     253    if (0) {
     254        // module_init() is supposed to be the last user of the kernel args
     255        // Note: don't confuse the kernel_args structure (which is never freed)
     256        // with the kernel args ranges it contains (and which are freed here).
     257        vm_free_kernel_args(&sKernelArgs);
     258    }
     259
     260    // init userland debugging
     261    TRACE("Init Userland debugging\n");
     262    init_user_debug();
     263
     264    // init the messaging service
     265    TRACE("Init Messaging Service\n");
     266    init_messaging_service();
     267
     268    /* bootstrap all the filesystems */
     269    TRACE("Bootstrap file systems\n");
     270    boot_splash_set_stage(BOOT_SPLASH_STAGE_2_BOOTSTRAP_FS);
     271    vfs_bootstrap_file_systems();
     272
     273    TRACE("Init Device Manager\n");
     274    boot_splash_set_stage(BOOT_SPLASH_STAGE_3_INIT_DEVICES);
     275    device_manager_init(&sKernelArgs);
     276
     277    TRACE("Add preloaded old-style drivers\n");
     278    devfs_add_preloaded_drivers(&sKernelArgs);
     279
     280    int_init_post_device_manager(&sKernelArgs);
     281
     282    TRACE("Mount boot file system\n");
     283    boot_splash_set_stage(BOOT_SPLASH_STAGE_4_MOUNT_BOOT_FS);
     284    vfs_mount_boot_file_system(&sKernelArgs);
     285
     286    // CPU specific modules may now be available
     287    boot_splash_set_stage(BOOT_SPLASH_STAGE_5_INIT_CPU_MODULES);
     288    cpu_init_post_modules(&sKernelArgs);
     289
     290    TRACE("vm_init_post_modules\n");
     291    boot_splash_set_stage(BOOT_SPLASH_STAGE_6_INIT_VM_MODULES);
     292    vm_init_post_modules(&sKernelArgs);
     293
     294    TRACE("debug_init_post_modules\n");
     295    debug_init_post_modules(&sKernelArgs);
     296
     297    TRACE("device_manager_init_post_modules\n");
     298    device_manager_init_post_modules(&sKernelArgs);
     299
     300    boot_splash_set_stage(BOOT_SPLASH_STAGE_7_RUN_BOOT_SCRIPT);
     301//  kernel_args_free(sKernelArgs.boot_splash);
     302// NOTE: We could introduce a syscall to draw more icons indicating
     303// stages in the boot script itself. Then we should not free the image.
     304
     305    // start the init process
     306    {
     307        KPath bootScriptPath;
     308        status_t status = find_directory(B_BEOS_SYSTEM_DIRECTORY, gBootDevice,
     309            false, bootScriptPath.LockBuffer(), bootScriptPath.BufferSize());
     310        if (status < B_OK)
     311            dprintf("main2: error when find_directory() %s\n", strerror(status));
     312
     313        bootScriptPath.UnlockBuffer();
     314        bootScriptPath.Append("boot/Bootscript");   
     315       
     316        const char *args[] = {"/bin/sh", bootScriptPath.Path(),
     317            NULL};
     318        int32 argc = 2;
     319        thread_id thread;
     320
     321        thread = load_image(argc, args, NULL);
     322        if (thread >= B_OK) {
     323            resume_thread(thread);
     324            TRACE("Bootscript started\n");
     325        } else
     326            dprintf("error starting \"%s\" error = %ld \n", args[0], thread);
     327    }
     328
     329    return 0;
     330}
     331