source: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 23.4 KB
Line 
1/* ----------------------------------------------------------------------- *
2 *
3 *   Copyright 2009 Erwan Velu - All Rights Reserved
4 *
5 *   Permission is hereby granted, free of charge, to any person
6 *   obtaining a copy of this software and associated documentation
7 *   files (the "Software"), to deal in the Software without
8 *   restriction, including without limitation the rights to use,
9 *   copy, modify, merge, publish, distribute, sublicense, and/or
10 *   sell copies of the Software, and to permit persons to whom
11 *   the Software is furnished to do so, subject to the following
12 *   conditions:
13 *
14 *   The above copyright notice and this permission notice shall
15 *   be included in all copies or substantial portions of the Software.
16 *
17 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 *   OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * -----------------------------------------------------------------------
27*/
28
29#include <stdlib.h>
30#include <string.h>
31#include <stdio.h>
32#include <getkey.h>
33#include "syslinux/config.h"
34#include "../lib/sys/vesa/vesa.h"
35#include "hdt-common.h"
36#include <disk/util.h>
37#include <disk/mbrs.h>
38#include <memory.h>
39
40/* ISOlinux requires a 8.3 format */
41void convert_isolinux_filename(char *filename, struct s_hardware *hardware)
42{
43    /* Exit if we are not running ISOLINUX */
44    if (hardware->sv->filesystem != SYSLINUX_FS_ISOLINUX)
45        return;
46    /* Searching the dot */
47    char *dot = strchr(filename, '.');
48    /* Exiting if no dot exists in that string */
49    if (dot == NULL)
50        return;
51    /* Exiting if the extension is 3 char or less */
52    if (strlen(dot) <= 4)
53        return;
54
55    /* We have an extension bigger than .blah
56     * so we have to shorten it to 3*/
57    dot[4] = '\0';
58}
59
60void detect_parameters(const int argc, const char *argv[],
61                       struct s_hardware *hardware)
62{
63    /* Quiet mode - make the output more quiet */
64    quiet = true;
65
66    /* Silent mode - make not output at all */
67    silent = false;
68
69    /* Vesa mode isn't set until we explictly call it */
70    vesamode = false;
71
72    /* Automode isn't the default*/
73    automode = false;
74
75    /* Menu mode is the default*/
76    menumode = true;
77
78    for (int i = 1; i < argc; i++) {
79        if (!strncmp(argv[i], "quiet", 5)) {
80            quiet = true;
81        } else if (!strncmp(argv[i], "silent", 6)) {
82            silent = true;
83        } else  if (!strncmp(argv[i], "verbose", 7)) {
84            quiet = false;
85        } else if (!strncmp(argv[i], "modules_pcimap=", 15)) {
86            strlcpy(hardware->modules_pcimap_path, argv[i] + 15,
87                    sizeof(hardware->modules_pcimap_path));
88            convert_isolinux_filename(hardware->modules_pcimap_path, hardware);
89        } else if (!strncmp(argv[i], "pciids=", 7)) {
90            strlcpy(hardware->pciids_path, argv[i] + 7,
91                    sizeof(hardware->pciids_path));
92            convert_isolinux_filename(hardware->pciids_path, hardware);
93        } else if (!strncmp(argv[i], "modules_alias=", 14)) {
94            strlcpy(hardware->modules_alias_path, argv[i] + 14,
95                    sizeof(hardware->modules_alias_path));
96            convert_isolinux_filename(hardware->modules_alias_path, hardware);
97        } else if (!strncmp(argv[i], "memtest=", 8)) {
98            strlcpy(hardware->memtest_label, argv[i] + 8,
99                    sizeof(hardware->memtest_label));
100            convert_isolinux_filename(hardware->memtest_label, hardware);
101        } else if (!strncmp(argv[i], "vesa", 4)) {
102            vesamode = true;
103            max_console_lines = MAX_VESA_CLI_LINES;
104            /* If the user defines a background image */
105            if (!strncmp(argv[i], "vesa=", 5)) {
106                strlcpy(hardware->vesa_background, argv[i] + 5,
107                        sizeof(hardware->vesa_background));
108            }
109        } else if (!strncmp(argv[i], "novesa", 6)) {
110            vesamode = false;
111            max_console_lines = MAX_CLI_LINES;
112        } else if (!strncmp(argv[i], "nomenu", 6)) {
113            menumode = false;
114        } else if (!strncmp(argv[i], "dump_filename=", 14)) {
115            strlcpy(hardware->dump_filename, argv[i] + 14,
116                    sizeof(hardware->dump_filename));
117        } else if (!strncmp(argv[i], "dump_path=", 10)) {
118            strlcpy(hardware->dump_path, argv[i] + 10,
119                    sizeof(hardware->dump_path));
120        } else if (!strncmp(argv[i], "tftp_ip=", 8)) {
121            strlcpy(hardware->tftp_ip, argv[i] + 8,
122                    sizeof(hardware->tftp_ip));
123        } else if (!strncmp(argv[i], "postexec=", 9)) {
124            /* The postexec= parameter is separated in several argv[]
125             * as it can contains spaces.
126             * We use the AUTO_DELIMITER char to define the limits
127             * of this parameter.
128             * i.e postexec='linux memtest.bin'
129             */
130
131            char *argument = (char*)argv[i]+10;
132            /* Extracting the first parameter */
133            strcpy(hardware->postexec, argument);
134
135            /* While we can't find the other AUTO_DELIMITER, let's process the argv[] */
136            while ((strchr(argument, AUTO_DELIMITER) == NULL) && (i+1<argc)) {
137                i++;
138                argument = (char *)argv[i];
139                strcat(hardware->postexec, " ");
140                strcat(hardware->postexec, argument);
141            }
142       
143             hardware->postexec[strlen(hardware->postexec) - 1] = 0;
144        } else if (!strncmp(argv[i], "auto=", 5)) {
145            /* The auto= parameter is separated in several argv[]
146             * as it can contains spaces.
147             * We use the AUTO_DELIMITER char to define the limits
148             * of this parameter.
149             * i.e auto='show dmi; show pci'
150             */
151
152            automode=true;
153            char *argument = (char*)argv[i]+6;
154            /* Extracting the first parameter */
155            strcpy(hardware->auto_label, argument);
156
157            /* While we can't find the other AUTO_DELIMITER, let's process the argv[] */
158            while ((strchr(argument, AUTO_DELIMITER) == NULL) && (i+1<argc)) {
159                i++;
160                argument = (char *)argv[i];
161                strcat(hardware->auto_label, " ");
162                strcat(hardware->auto_label, argument);
163            }
164
165             hardware->auto_label[strlen(hardware->auto_label) - 1] = 0;
166        }
167    }
168}
169
170void detect_syslinux(struct s_hardware *hardware)
171{
172    hardware->sv = syslinux_version();
173    switch (hardware->sv->filesystem) {
174    case SYSLINUX_FS_SYSLINUX:
175        strlcpy(hardware->syslinux_fs, "SYSlinux", 9);
176        break;
177    case SYSLINUX_FS_PXELINUX:
178        strlcpy(hardware->syslinux_fs, "PXElinux", 9);
179        break;
180    case SYSLINUX_FS_ISOLINUX:
181        strlcpy(hardware->syslinux_fs, "ISOlinux", 9);
182        break;
183    case SYSLINUX_FS_EXTLINUX:
184        strlcpy(hardware->syslinux_fs, "EXTlinux", 9);
185        break;
186    case SYSLINUX_FS_UNKNOWN:
187    default:
188        strlcpy(hardware->syslinux_fs, "Unknown Bootloader",
189                sizeof hardware->syslinux_fs);
190        break;
191    }
192}
193
194void init_hardware(struct s_hardware *hardware)
195{
196    hardware->pci_ids_return_code = 0;
197    hardware->modules_pcimap_return_code = 0;
198    hardware->modules_alias_return_code = 0;
199    hardware->cpu_detection = false;
200    hardware->pci_detection = false;
201    hardware->disk_detection = false;
202    hardware->disks_count = 0;
203    hardware->dmi_detection = false;
204    hardware->pxe_detection = false;
205    hardware->vesa_detection = false;
206    hardware->vpd_detection = false;
207    hardware->memory_detection = false;
208    hardware->acpi_detection = false;
209    hardware->nb_pci_devices = 0;
210    hardware->is_dmi_valid = false;
211    hardware->is_pxe_valid = false;
212    hardware->is_vpd_valid = false;
213    hardware->is_acpi_valid = false;
214    hardware->pci_domain = NULL;
215    hardware->detected_memory_size = 0;
216    hardware->physical_cpu_count =1; /* we have at least one cpu */
217
218    /* Cleaning structures */
219    memset(hardware->disk_info, 0, sizeof(hardware->disk_info));
220    memset(hardware->mbr_ids, 0, sizeof(hardware->mbr_ids));
221    memset(&hardware->dmi, 0, sizeof(s_dmi));
222    memset(&hardware->cpu, 0, sizeof(s_cpu));
223    memset(&hardware->pxe, 0, sizeof(struct s_pxe));
224    memset(&hardware->vesa, 0, sizeof(struct s_vesa));
225    memset(&hardware->vpd, 0, sizeof(s_vpd));
226    memset(&hardware->acpi, 0, sizeof(s_acpi));
227    memset(hardware->syslinux_fs, 0, sizeof hardware->syslinux_fs);
228    memset(hardware->pciids_path, 0, sizeof hardware->pciids_path);
229    memset(hardware->modules_pcimap_path, 0,
230           sizeof hardware->modules_pcimap_path);
231    memset(hardware->modules_alias_path, 0,
232           sizeof hardware->modules_alias_path);
233    memset(hardware->memtest_label, 0, sizeof hardware->memtest_label);
234    memset(hardware->auto_label, 0, sizeof hardware->auto_label);
235    memset(hardware->dump_path, 0, sizeof hardware->dump_path);
236    memset(hardware->dump_filename, 0, sizeof hardware->dump_filename);
237    memset(hardware->vesa_background, 0, sizeof hardware->vesa_background);
238    memset(hardware->tftp_ip, 0, sizeof hardware->tftp_ip);
239    memset(hardware->postexec, 0, sizeof hardware->postexec);
240    strcat(hardware->dump_path, "hdt");
241    strcat(hardware->dump_filename, "%{m}+%{p}+%{v}");
242    strcat(hardware->pciids_path, "pci.ids");
243    strcat(hardware->modules_pcimap_path, "modules.pcimap");
244    strcat(hardware->modules_alias_path, "modules.alias");
245    strcat(hardware->memtest_label, "memtest");
246    strlcpy(hardware->vesa_background, CLI_DEFAULT_BACKGROUND,
247            sizeof(hardware->vesa_background));
248}
249
250/*
251 * Detecting if a DMI table exist
252 * if yes, let's parse it
253 */
254int detect_dmi(struct s_hardware *hardware)
255{
256    if (hardware->dmi_detection == true)
257        return -1;
258    hardware->dmi_detection = true;
259    if (dmi_iterate(&hardware->dmi) == -ENODMITABLE) {
260        hardware->is_dmi_valid = false;
261        return -ENODMITABLE;
262    }
263
264    parse_dmitable(&hardware->dmi);
265    hardware->is_dmi_valid = true;
266    return 0;
267}
268
269/*
270 * Detecting ACPI
271 * if yes, let's parse it
272 */
273int detect_acpi(struct s_hardware *hardware)
274{
275    int retval;
276    if (hardware->acpi_detection == true)
277        return -1;
278    hardware->acpi_detection = true;
279    if ((retval=parse_acpi(&hardware->acpi)) != ACPI_FOUND) {
280        hardware->is_acpi_valid = false;
281        return retval;
282    }
283
284    hardware->is_acpi_valid = true;
285    return retval;
286}
287
288/**
289 * vpd_detection - populate the VPD structure
290 *
291 * VPD is a structure available on IBM machines.
292 * It is documented at:
293 *    http://www.pc.ibm.com/qtechinfo/MIGR-45120.html
294 * (XXX the page seems to be gone)
295 **/
296int detect_vpd(struct s_hardware *hardware)
297{
298    if (hardware->vpd_detection)
299        return -1;
300    else
301        hardware->vpd_detection = true;
302
303    if (vpd_decode(&hardware->vpd) == -ENOVPDTABLE) {
304        hardware->is_vpd_valid = false;
305        return -ENOVPDTABLE;
306    } else {
307        hardware->is_vpd_valid = true;
308        return 0;
309    }
310}
311
312/* Detection vesa stuff*/
313int detect_vesa(struct s_hardware *hardware)
314{
315    static com32sys_t rm;
316    struct vesa_general_info *gi;
317    struct vesa_mode_info *mi;
318    uint16_t mode, *mode_ptr;
319    char *oem_ptr;
320    int rv = -1;
321
322    if (hardware->vesa_detection == true)
323        return -1;
324
325    hardware->vesa_detection = true;
326    hardware->is_vesa_valid = false;
327
328    gi = lmalloc(sizeof(*gi));
329    if (!gi)
330        return -1;
331
332    mi = lmalloc(sizeof(*mi));
333    if (!mi)
334        goto out;
335
336    gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */
337    memset(&rm, 0, sizeof rm);
338    rm.eax.w[0] = 0x4F00;       /* Get SVGA general information */
339    rm.edi.w[0] = OFFS(gi);
340    rm.es = SEG(gi);
341    __intcall(0x10, &rm, &rm);
342
343    if (rm.eax.w[0] != 0x004F) {
344        goto out;
345    };
346
347    mode_ptr = GET_PTR(gi->video_mode_ptr);
348    oem_ptr = GET_PTR(gi->oem_vendor_name_ptr);
349    strlcpy(hardware->vesa.vendor, oem_ptr, sizeof(hardware->vesa.vendor));
350    oem_ptr = GET_PTR(gi->oem_product_name_ptr);
351    strlcpy(hardware->vesa.product, oem_ptr, sizeof(hardware->vesa.product));
352    oem_ptr = GET_PTR(gi->oem_product_rev_ptr);
353    strlcpy(hardware->vesa.product_revision, oem_ptr,
354            sizeof(hardware->vesa.product_revision));
355
356    hardware->vesa.major_version = (gi->version >> 8) & 0xff;
357    hardware->vesa.minor_version = gi->version & 0xff;
358    hardware->vesa.total_memory = gi->total_memory;
359    hardware->vesa.software_rev = gi->oem_software_rev;
360
361    hardware->vesa.vmi_count = 0;
362
363    while ((mode = *mode_ptr++) != 0xFFFF) {
364
365        memset(&rm, 0, sizeof rm);
366        rm.eax.w[0] = 0x4F01;   /* Get SVGA mode information */
367        rm.ecx.w[0] = mode;
368        rm.edi.w[0] = OFFS(mi);
369        rm.es = SEG(mi);
370        __intcall(0x10, &rm, &rm);
371
372        /* Must be a supported mode */
373        if (rm.eax.w[0] != 0x004f)
374            continue;
375
376        /* Saving detected values */
377        memcpy(&hardware->vesa.vmi[hardware->vesa.vmi_count].mi, mi,
378               sizeof(struct vesa_mode_info));
379        hardware->vesa.vmi[hardware->vesa.vmi_count].mode = mode;
380
381        hardware->vesa.vmi_count++;
382    }
383    hardware->is_vesa_valid = true;
384
385    rv = 0;
386out:
387    lfree(mi);
388    lfree(gi);
389    return rv;
390}
391
392/* Try to detect disks from port 0x80 to 0xff */
393void detect_disks(struct s_hardware *hardware)
394{
395    int i = -1;
396    int err;
397
398    if (hardware->disk_detection)
399        return;
400
401    hardware->disk_detection = true;
402    for (int drive = 0x80; drive < 0xff; drive++) {
403        i++;
404        hardware->disk_info[i].disk = drive;
405        err = get_drive_parameters(&hardware->disk_info[i]);
406
407        /*
408         * Do not print output when drive does not exist or
409         * doesn't support int13 (cdrom, ...)
410         */
411        if (err == -1 || !hardware->disk_info[i].cbios)
412            continue;
413
414        /* Detect MBR */
415        hardware->mbr_ids[i] = get_mbr_id(&hardware->disk_info[i]);
416
417        hardware->disks_count++;
418    }
419}
420
421int detect_pxe(struct s_hardware *hardware)
422{
423    void *dhcpdata;
424
425    size_t dhcplen;
426    t_PXENV_UNDI_GET_NIC_TYPE gnt;
427
428    if (hardware->pxe_detection == true)
429        return -1;
430    hardware->pxe_detection = true;
431    hardware->is_pxe_valid = false;
432    memset(&gnt, 0, sizeof(t_PXENV_UNDI_GET_NIC_TYPE));
433    memset(&hardware->pxe, 0, sizeof(struct s_pxe));
434
435    /* This code can only work if pxelinux is loaded */
436    if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
437        return -1;
438    }
439// printf("PXE: PXElinux detected\n");
440    if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
441        pxe_bootp_t *dhcp = &hardware->pxe.dhcpdata;
442        memcpy(&hardware->pxe.dhcpdata, dhcpdata,
443               sizeof(hardware->pxe.dhcpdata));
444        snprintf(hardware->pxe.mac_addr, sizeof(hardware->pxe.mac_addr),
445                 "%02x:%02x:%02x:%02x:%02x:%02x", dhcp->CAddr[0],
446                 dhcp->CAddr[1], dhcp->CAddr[2], dhcp->CAddr[3],
447                 dhcp->CAddr[4], dhcp->CAddr[5]);
448
449        /* Saving our IP address in a easy format */
450        hardware->pxe.ip_addr[0] = hardware->pxe.dhcpdata.yip & 0xff;
451        hardware->pxe.ip_addr[1] = hardware->pxe.dhcpdata.yip >> 8 & 0xff;
452        hardware->pxe.ip_addr[2] = hardware->pxe.dhcpdata.yip >> 16 & 0xff;
453        hardware->pxe.ip_addr[3] = hardware->pxe.dhcpdata.yip >> 24 & 0xff;
454
455        if (!pxe_get_nic_type(&gnt)) {
456            switch (gnt.NicType) {
457            case PCI_NIC:
458                hardware->is_pxe_valid = true;
459                hardware->pxe.vendor_id = gnt.info.pci.Vendor_ID;
460                hardware->pxe.product_id = gnt.info.pci.Dev_ID;
461                hardware->pxe.subvendor_id = gnt.info.pci.SubVendor_ID;
462                hardware->pxe.subproduct_id =
463                    gnt.info.pci.SubDevice_ID,
464                    hardware->pxe.rev = gnt.info.pci.Rev;
465                hardware->pxe.pci_bus = (gnt.info.pci.BusDevFunc >> 8) & 0xff;
466                hardware->pxe.pci_dev = (gnt.info.pci.BusDevFunc >> 3) & 0x7;
467                hardware->pxe.pci_func = gnt.info.pci.BusDevFunc & 0x03;
468                hardware->pxe.base_class = gnt.info.pci.Base_Class;
469                hardware->pxe.sub_class = gnt.info.pci.Sub_Class;
470                hardware->pxe.prog_intf = gnt.info.pci.Prog_Intf;
471                hardware->pxe.nictype = gnt.NicType;
472                break;
473            case CardBus_NIC:
474                hardware->is_pxe_valid = true;
475                hardware->pxe.vendor_id = gnt.info.cardbus.Vendor_ID;
476                hardware->pxe.product_id = gnt.info.cardbus.Dev_ID;
477                hardware->pxe.subvendor_id = gnt.info.cardbus.SubVendor_ID;
478                hardware->pxe.subproduct_id =
479                    gnt.info.cardbus.SubDevice_ID,
480                    hardware->pxe.rev = gnt.info.cardbus.Rev;
481                hardware->pxe.pci_bus =
482                    (gnt.info.cardbus.BusDevFunc >> 8) & 0xff;
483                hardware->pxe.pci_dev =
484                    (gnt.info.cardbus.BusDevFunc >> 3) & 0x7;
485                hardware->pxe.pci_func = gnt.info.cardbus.BusDevFunc & 0x03;
486                hardware->pxe.base_class = gnt.info.cardbus.Base_Class;
487                hardware->pxe.sub_class = gnt.info.cardbus.Sub_Class;
488                hardware->pxe.prog_intf = gnt.info.cardbus.Prog_Intf;
489                hardware->pxe.nictype = gnt.NicType;
490                break;
491            case PnP_NIC:
492            default:
493                return -1;
494                break;
495            }
496
497            /* The firt pass try to find the exact pci device */
498            hardware->pxe.pci_device = NULL;
499            hardware->pxe.pci_device_pos = 0;
500            struct pci_device *pci_device;
501            int pci_number = 0;
502            for_each_pci_func(pci_device, hardware->pci_domain) {
503                pci_number++;
504                if ((__pci_bus == hardware->pxe.pci_bus) &&
505                    (__pci_slot == hardware->pxe.pci_dev) &&
506                    (__pci_func == hardware->pxe.pci_func) &&
507                    (pci_device->vendor == hardware->pxe.vendor_id)
508                    && (pci_device->product == hardware->pxe.product_id)) {
509                    hardware->pxe.pci_device = pci_device;
510                    hardware->pxe.pci_device_pos = pci_number;
511                    return 0;
512                }
513            }
514
515            /* If we reach that part, it means the pci device pointed by
516             * the pxe rom wasn't found in our list.
517             * Let's try to find the device only by its pci ids.
518             * The pci device we'll match is maybe not exactly the good one
519             * as we can have the same pci id several times.
520             * At least, the pci id, the vendor/product will be right.
521             * That's clearly a workaround for some weird cases.
522             * This should happend very unlikely */
523            hardware->pxe.pci_device = NULL;
524            hardware->pxe.pci_device_pos = 0;
525            pci_number = 0;
526            for_each_pci_func(pci_device, hardware->pci_domain) {
527                pci_number++;
528                if ((pci_device->vendor == hardware->pxe.vendor_id)
529                    && (pci_device->product == hardware->pxe.product_id)) {
530                    hardware->pxe.pci_device = pci_device;
531                    hardware->pxe.pci_device_pos = pci_number;
532                    return 0;
533                }
534            }
535
536        }
537    }
538    return 0;
539}
540
541void detect_memory(struct s_hardware *hardware) {
542     if (hardware->memory_detection == false) {
543             hardware->memory_detection = true;
544     hardware->detected_memory_size = detect_memsize();
545     }
546}
547
548void detect_pci(struct s_hardware *hardware)
549{
550    if (hardware->pci_detection == true)
551        return;
552    hardware->pci_detection = true;
553
554    hardware->nb_pci_devices = 0;
555
556    /* Scanning to detect pci buses and devices */
557    hardware->pci_domain = pci_scan();
558
559    if (!hardware->pci_domain)
560        return;
561
562    /* Gathering addtional information */
563    gather_additional_pci_config(hardware->pci_domain);
564
565    struct pci_device *pci_device;
566    for_each_pci_func(pci_device, hardware->pci_domain) {
567        hardware->nb_pci_devices++;
568    }
569
570    if (!quiet) {
571        more_printf("PCI: %d devices detected\n", hardware->nb_pci_devices);
572        more_printf("PCI: Resolving names\n");
573    }
574    /* Assigning product & vendor name for each device */
575    hardware->pci_ids_return_code =
576        get_name_from_pci_ids(hardware->pci_domain, hardware->pciids_path);
577
578    if (!quiet)
579        more_printf("PCI: Resolving class names\n");
580    /* Assigning class name for each device */
581    hardware->pci_ids_return_code =
582        get_class_name_from_pci_ids(hardware->pci_domain,
583                                    hardware->pciids_path);
584
585    if (!quiet)
586        more_printf("PCI: Resolving module names\n");
587    /* Detecting which kernel module should match each device using modules.pcimap */
588    hardware->modules_pcimap_return_code =
589        get_module_name_from_pcimap(hardware->pci_domain,
590                                    hardware->modules_pcimap_path);
591
592    /* Detecting which kernel module should match each device using modules.alias */
593    hardware->modules_alias_return_code =
594        get_module_name_from_alias(hardware->pci_domain,
595                                   hardware->modules_alias_path);
596
597}
598
599void cpu_detect(struct s_hardware *hardware)
600{
601    if (hardware->cpu_detection == true)
602        return;
603    detect_cpu(&hardware->cpu);
604    /* Old processors doesn't manage the identify commands
605     * Let's use the dmi value in that case */
606    if (strlen(remove_spaces(hardware->cpu.model)) == 0)
607        strlcpy(hardware->cpu.model, hardware->dmi.processor.version,
608                sizeof(hardware->cpu.model));
609
610    /* Some CPUs like to put many spaces in the model name
611     * That makes some weird display in console/menu
612     * Let's remove that mulitple spaces */
613    strlcpy(hardware->cpu.model,del_multi_spaces(hardware->cpu.model),sizeof(hardware->cpu.model));
614
615    if ((hardware->is_acpi_valid) && (hardware->acpi.madt.valid)) {
616        hardware->physical_cpu_count=hardware->acpi.madt.processor_local_apic_count / hardware->cpu.num_cores;
617    }
618    hardware->cpu_detection = true;
619}
620
621/*
622 * Find the last instance of a particular command line argument
623 * (which should include the final =; do not use for boolean arguments)
624 */
625const char *find_argument(const char **argv, const char *argument)
626{
627    int la = strlen(argument);
628    const char **arg;
629    const char *ptr = NULL;
630
631    for (arg = argv; *arg; arg++) {
632        if (!memcmp(*arg, argument, la))
633            ptr = *arg + la;
634    }
635
636    return ptr;
637}
638
639void clear_screen(void)
640{
641    move_cursor_to_next_line();
642    disable_utf8();
643    set_g1_special_char();
644    set_us_g0_charset();
645    display_cursor(false);
646    clear_entire_screen();
647    gotoxy(0,0);
648    reset_more_printf();
649}
650
651/* remove begining spaces */
652char *skip_spaces(char *p)
653{
654    while (*p && *p <= ' ') {
655        p++;
656    }
657
658    return p;
659}
660
661/* remove trailing & begining spaces */
662char *remove_spaces(char *p)
663{
664    char *save = p;
665    p += strlen(p) - 1;
666    while (*p && *p <= ' ') {
667        *p = '\0';
668        p--;
669    }
670    p = save;
671    while (*p && *p <= ' ') {
672        p++;
673    }
674
675    return p;
676}
677
678/* remove trailing LF */
679char *remove_trailing_lf(char *p)
680{
681    char *save = p;
682    p += strlen(p) - 1;
683    while (*p && *p == 10) {
684        *p = '\0';
685        p--;
686    }
687    p = save;
688
689    return p;
690}
691
692/* delete multiple spaces, one is enough */
693char *del_multi_spaces(char *p)
694{
695    /* Saving the original pointer */
696    char *save = p;
697
698    /* Let's parse the complete string
699     * As we search for a double spacing
700     * we have to be sure then string is
701     * long enough to be processed */
702    while (*p && *(p + 1)) {
703
704        /* If we have two consecutive spaces */
705        if ((*p == ' ') && (*(p + 1) == ' ')) {
706
707            /* Let's copy to the current position
708             * the content from the second space*/
709            strlcpy(p, p + 1, strlen(p + 1));
710
711            /* Don't increment the pointer as we
712             * changed the content of the current position*/
713            continue;
714        }
715
716        /* Nothing as been found, let's see on the next char */
717        p++;
718    }
719    /* Returning the original pointer */
720    return save;
721}
722
723/* Reset the more_printf counter */
724void reset_more_printf(void)
725{
726    display_line_nb = 0;
727}
728
729int draw_background(const char *what)
730{
731    if (!what)
732        return vesacon_default_background();
733    else
734        return vesacon_load_background(what);
735}
736
737void init_console(struct s_hardware *hardware)
738{
739    if (vesamode) {
740        openconsole(&dev_rawcon_r, &dev_vesaserial_w);
741        draw_background(hardware->vesa_background);
742    } else
743        console_ansi_raw();
744}
745
746void detect_hardware(struct s_hardware *hardware)
747{
748    if (!quiet)
749        more_printf("ACPI: Detecting\n");
750    detect_acpi(hardware);
751
752    if (!quiet)
753        more_printf("MEMORY: Detecting\n");
754    detect_memory(hardware);
755
756    if (!quiet)
757        more_printf("DMI: Detecting Table\n");
758    if (detect_dmi(hardware) == -ENODMITABLE) {
759        more_printf("DMI: ERROR ! Table not found ! \n");
760        more_printf("DMI: Many hardware components will not be detected ! \n");
761    } else {
762        if (!quiet)
763            more_printf("DMI: Table found ! (version %u.%u)\n",
764                        hardware->dmi.dmitable.major_version,
765                        hardware->dmi.dmitable.minor_version);
766    }
767
768    if (!quiet)
769        more_printf("CPU: Detecting\n");
770    cpu_detect(hardware);
771
772    if (!quiet)
773        more_printf("DISKS: Detecting\n");
774    detect_disks(hardware);
775
776    if (!quiet)
777        more_printf("VPD: Detecting\n");
778    detect_vpd(hardware);
779
780    detect_pci(hardware);
781    if (!quiet)
782        more_printf("PCI: %d Devices Found\n", hardware->nb_pci_devices);
783 
784   if (!quiet)
785        more_printf("PXE: Detecting\n");
786    detect_pxe(hardware);
787
788    if (!quiet)
789        more_printf("VESA: Detecting\n");
790    detect_vesa(hardware);
791}
792
Note: See TracBrowser for help on using the repository browser.