code:
% Libreboot installation workshop at FSF LibrePlanet 2018 conference
% Leah Rowe
% 21 March 2018

LibrePlanet is the annual conference held by the Free Software Foundation in
Boston, MA, USA. This year, it's being held at MIT university on March 24th
and 25th. More details about it are here:
<https://libreplanet.org/2018/>

The FSF isn't officially hosting a Libreboot workshop at LibrePlanet
this year. At the 2015 and 2016 LibrePlanet conference, there were workshops
there run by myself and Patrick McDermott, a former member of the Libreboot
project. The FSF has confirmed that they don't have a dedicated room for it
this year, due to increasing number of conference goers.

Therefore, an unofficial workshop is being set up. I've already issued a news
post about this on the libreplanet-discuss mailing list:
<https://lists.gnu.org/archive/html/libreplanet-discuss/2018-03/msg00037.html>

With John Sullivan's blessing:
<https://lists.gnu.org/archive/html/libreplanet-discuss/2018-03/msg00039.html>

If you, the reader, are attending LibrePlanet this year, and you would like to
get a Libreboot system flashed for you, then take it with you to LibrePlanet.
There will be knowledgeable people there who can flash Libreboot for you.

Find one of the people on the list below (list will be updated if more people
volunteer to flash). If it's Kurt, they'll flash for you at the Technoethical
booth. If it's someone else, they can take you into the speakers' lounge (it does
not matter if they're not a speaker). John Sullivan of FSF has approved this.
There are tables, chairs and power sockets in that room.
There are also tables and chairs outside the speakers' lounge, in the common
area at the conference, but I highly recommend using the speakers' lounge.
That's where I took people, on LibrePlanet 2015 and 2016 :)
It's really comfy in there.

John Sullivan of FSF has also confirmed that that there is a dedicated
*alcohol-free social and hacking time* at the FSF office on Saturday 24th
March, between 1900-2130 (7-9:30 PM). You could also flash someone's laptop for
them there, in the conference room at the FSF, or on a table outside. Or the
sysadmin room, if that's OK with them.

I've been asking around. The following people have confirmed so far that they
will be providing Libreboot flashing services at the conference:

- Kurt from Technoethical, an FSF-endorsed Libreboot hardware seller. They will
  also have their own samples. They'll be at the Technoethical booth there.
  IRC nick sensiblemn\_ or sensiblemn on #libreboot IRC
- zyliwax from #libreboot IRC - has confirmed that they will be there
- Patrick McDermott (pehjota) of Libiquity. Patrick is also present at
  LibrePlanet, and has brought flashing equipment. What Patrick said on the
  libreplanet-discuss mailing list: look for the person that is wearing a
  grey Libiquity polo shirt. They posted this picture on the mailing list,
  so you know how to find this person:
  <http://www.libiquity.com/media/images/patrick-mcdermott.jpg>
  - of note: Patrick is bringing CH341A-based programmer, and can flash D8/D16
- You could also find an FSF sysadmin and ask them to flash Libreboot for you.

I would be grateful if anyone else would also be willing to provide flashing.
I myself am not attending the conference physically, unfortunately.

See mailing list post for more info. If you would like to help Kurt and
zyliwax out, please either reply to that mailing list post on
libreplanet-discuss or email me directly:
[leah@libreboot.org](mailto:leah@libreboot.org) and I'll add your name in
the above list.

Basically, all you need for flashing someone's laptop at the conference is:

- Portable SPI flasher (USB powered. SSH into it via your laptop, use the SPI
  flasher's own 3v3, etc). Make sure to use the workaround-mx patch on
  flashrom, so that you can use `--workaround-mx` on Macronix chips, if flashing
  an X200, otherwise flashing will be unreliable (see mailing list post linked
  above) - portability is important, in case you sit down with someone in
  a place without power sockets.
  See guides on libreboot.org for setting up SPI flashers, but ignore the notes
  about external PSUs and instead just wire up the flasher's own 3v3 connection.
  The workaround-mx patch is here:
  <https://notabug.org/consts/libreboot/raw/2caaac00972d9ea56b0fcd7c95897e90283b05b8/projects/flashrom/patches/0005-Workaround-MX25-reliable-operation.patch>
  apply this on flashrom src and build with that. To use it, just pass the
  `--workaround-mx` option in flashrom.
- Screwdrivers (phillips head 0 *and* 00 - sometimes labelled PH0 or PH00,
  respectively)
- Thermal paste and thermal cleaning material, for T400 flashing
  - arctic mx-4 paste recommended. For cleaning material, use anti-static cloth
  and isopropyl alcohol - as pure as possible! ideally close to 100%! 70%
  rubbing alcohol is common in USA, and not suitable for electronics
- Anti-ESD wrist/ankle strap, to protect against damage from electrostatic
  discharge when working with circuit boards.

Optionally:

- Bring DIP8 25xx SPI chips with Libreboot, for ASUS KCMA-D8 or KGPE-D16, for the
  conference goer to put in their D8/D16 when they get home. Also PLCC32 LPC
  1MB (or bigger, with padding at the beginning) chips for ASUS KFSN4-DRE
- Soldering equipment (knife tip, hot air, etc) for X200T flashing. NOTE: FSF has
  soldering equipment in their office, you could ask them to lend it to you
  if you're flashing a laptop there at the FSF office. NOTE2: Kurt from
  Technoethical is also bringing soldering equipment.


code:
% Libreboot installation workshop at FSF LibrePlanet 2019 conference
% Leah Rowe
% 19 March 2018

LibrePlanet is the annual conference held by the Free Software Foundation in
Boston, MA, USA. This year, it's being held at MIT university on March 23th
and 24th. More details about it are here:
<https://libreplanet.org/2019/>

The FSF isn't officially hosting a Libreboot workshop at LibrePlanet
this year. At the 2015 and 2016 LibrePlanet conference, there were workshops
there run by myself and Patrick McDermott, a former member of the Libreboot
project.

This year, like [last year](libreplanet2018-workshop.md), the intention is to
provide Libreboot flashing for conference goers on an unofficial basis. If
you have SPI flashing hardware and would like to help out, then email Leah Rowe
on [leah@libreboot.org](mailto:leah@libreboot.org) and your name will be added
here. If you can provide a photo to be shared on this page, that will further
assist attendees in finding you at the conference.

If you, the reader, are attending LibrePlanet this year, and you would like to
get a Libreboot system flashed for you, then take it with you to LibrePlanet.
There will be knowledgeable people there who can flash Libreboot for you.

I, Leah Rowe, would be grateful to anyone who can answer my call. I'm looking
for people who can provide a Libreboot installation service at the FSF conference
during the weekend.

Recommended areas to go for flashing peoples laptops/desktops at the conference:

- Speakers lounge (behind the reception desk). There is normally space in there
  and nobody actually checks whether you are a speaker. If you volunteer to
  help with stuff it should be fine.

- Tables outside the conference rooms (NOTE: no power sockets. Bring extension
  cables and duct tape, so you can tape the power cables to the ground to
  prevent trip hazards).

- FSF office (before the conference, e.g. on Thursday, March 21st or Friday,
  March 22nd. Or Monday, March 25th at the FSF office. The FSF has an open door
  policy, so any person can show up to their office on 51 Franklin Street, 5th
  Floor, Boston MA 02110. Either use the conference room if it's free, or use
  the lobby area at the back of the office. The sysadmin office will probably be
  good too, if the sysadmins let you in there

- Any room that is used for lightning talks (do it in the back, and be quiet
  so as to not disturb any talks that are in progress).

I would be grateful if anyone else would also be willing to provide flashing.
I myself am not attending the conference physically, unfortunately.

Basically, all you need for flashing someone's laptop at the conference is:

- Portable SPI flasher (USB powered. SSH into it via your laptop, use the SPI
  flasher's own 3v3, etc). Make sure to use the workaround-mx patch on
  flashrom, so that you can use `--workaround-mx` on Macronix chips, if flashing
  an X200, otherwise flashing will be unreliable (see mailing list post linked
  above) - portability is important, in case you sit down with someone in
  a place without power sockets.
  See guides on libreboot.org for setting up SPI flashers, but ignore the notes
  about external PSUs and instead just wire up the flasher's own 3v3 connection.
  The workaround-mx patch is here:
  <https://notabug.org/consts/libreboot/raw/2caaac00972d9ea56b0fcd7c95897e90283b05b8/projects/flashrom/patches/0005-Workaround-MX25-reliable-operation.patch>
  apply this on flashrom src and build with that. To use it, just pass the
  `--workaround-mx` option in flashrom.
- Screwdrivers (phillips head 0 *and* 00 - sometimes labelled PH0 or PH00,
  respectively)
- Thermal paste and thermal cleaning material, for T400 flashing
  - arctic mx-4 paste recommended. For cleaning material, use anti-static cloth
  and isopropyl alcohol - as pure as possible! ideally close to 100%! 70%
  rubbing alcohol is common in USA, and not suitable for electronics
- Anti-ESD wrist/ankle strap, to protect against damage from electrostatic
  discharge when working with circuit boards.

Optionally:

- Bring DIP8 25xx SPI chips with Libreboot, for ASUS KCMA-D8 or KGPE-D16, for the
  conference goer to put in their D8/D16 when they get home. Also PLCC32 LPC
  1MB (or bigger, with padding at the beginning) chips for ASUS KFSN4-DRE
- Soldering equipment (knife tip, hot air, etc) for X200T flashing. NOTE: FSF has
  soldering equipment in their office, you could ask them to lend it to you
  if you're flashing a laptop there at the FSF office.

license: mit


code:
% New development mailing list for Libreboot
% Leah Rowe
% 10 Jun 2017

Our sysadmin, Alyssa Rosenzweig, has set up a mailing list on libreboot.org
infrastructure, for development discussions.

The mailing list address is
[development@libreboot.org](mailto:development@libreboot.org)

Information about the mailing list and how to subscribe are
on the [lists page](../lists/). Archives of discussion threads
are in the [pipermail development directory](../pipermail/development/).

This replaces the mailing lists that we had before. The mailing list software
in use is [GNU Mailman](https://www.gnu.org/software/mailman/), which is also
used by many other free software projects and is very popular. If you already
use mailing lists in other projects, then the way to use Libreboot's new
mailing list is exactly the same.

This mailing list is for development discussion *only*. User support is still
handled via #libreboot on Freenode IRC, as always.

This new mailing list will also be used for beta testing of upcoming stable
releases, from now on. Work is currently underway on a new Libreboot release.


code:
% Community feedback needed on whether Libreboot should re-join the GNU project
%
% 22 Apr 2017

Community feedback is needed on whether Libreboot should re-join the GNU
project, having previously been a member. The discussion place for this topic
is on [this thread in the Libreboot subreddit at reddit.com/r/libreboot/](https://www.reddit.com/r/libreboot/comments/66tdds/proposal_for_libreboot_rejoin_gnu_community/). With sufficient community support, Libreboot will
apply to re-join to become a member of the GNU project. Full reasoning and
history behind this proposal is detailed in the thread.


code:
% Testers needed for a new upcoming Libreboot release
% Leah Rowe
% 21 Dec 2017

We need testers, especially hardware testers, for a new upcoming release of
Libreboot.

Andrew Robbins, one of the developers, has done extensive work on the build
system in Libreboot and now we are rebasing all boards in Libreboot onto the
latest version of coreboot. Upstream coreboot has many bugfixes, which the
version that Libreboot uses (an older revision) does not have.

We are currently assembling a team of testers. If you wish to participate,
then reply on this thread in our bug tracker:

<https://notabug.org/libreboot/libreboot/issues/373>

Any help would be appreciated. In general, testing is also needed (e.g.
build testing, documentation testing/improvements, etc).


code:
% TALOS II Secure Workstation, from Raptor Engineering
% Leah Rowe
% 15 August 2017

Recently, [Raptor Engineering](https://www.raptorcs.com/TALOSII/) has launched
a new series of workstation and server computers. These are high-end systems,
using the libre IBM POWER9 architecture, and the boot firmware is entirely
Free Software like Libreboot.

This is the *first* OEM producing *high-end* systems, from the factory assembly
line, with completely libre boot firmware. The boot firmware, operating system
and everything else is entirely Free Software. While not technically libreboot,
the boot firmware on TALOS II is Free Software, so it was decided that the
TALOS II would be promoted here on libreboot.org.

If you are in the market for a high-end, secure workstation or server with
100% free boot firmware (like Libreboot) and operating system, produced by
an OEM *hardware manufacturer* that cares about freedom, look no further than
the TALOS II from Raptor Engineering!

Their website for pre-orders is here:
<https://www.raptorcs.com/TALOSII/>

An entry for the TALOS II has also been added to the
[suppliers page](../suppliers.md) on libreboot.org.

Raptor Engineering is the same company that ported the ASUS KFSN4-DRE,
KPGE-D16 and KCMA-D8 motherboards to Libreboot. In addition, they added support
for Hybrid Graphics on the ThinkPad T400 which Libreboot supports, enabling
those laptops to be used in freedom (with the AMD GPU disabled, in favour of
the Intel GPU which Libreboot has free video initialization for).

In response to the TALOS II launch I, Leah Rowe, have removed the Libreboot D16
(TALOS II's main competitor) from minifree.org, and removed the Minifree D16
entries from the [suppliers page](../suppliers.md) on libreboot.org.
I encourage Vikings and Technoethical, also present on that suppliers page, to
do the same and discontinue their D16 products. The TALOS II is very important
for the future of free, libre computing and indeed the free software community
as a whole; if TALOS II fails, we will be stuck for a very long time without
any viable high-end workstations that are libre. High-end hardware is necessary
for modern software development.


code:
% Open Letter to the Free Software Community
%
% 2 Apr 2017

To the free software community:

Over the past six months, the Libreboot project has been in a state of discord.
After an issue with a transgender employee at the FSF escalated, Libreboot
publicly left GNU with little consultation from the community. Relations with
so many people were strained. Friendships broken, lines of code never written:
the chaos needs to come to an end.

A series of organisational issues with Libreboot enabled this fallout to occur.
We have since corrected them:

Previously, the libreboot repository and the website could only be modified by
the project leader, Leah Rowe. This setup created a single point of failure,
with little leeway for dissenting contributors. Since then, I have joined the
project as the sysadmin. Along with another contributor, Sebastian "Swift Geek"
Grzywna, direct access to the code and servers is shared. Though the project
cannot yet be completely decentralised, this change is a win for transparency.

Previously, most of libreboot.org, including public statements such as those
regarding GNU, were issued by Leah herself. The rest of the team and the
community were not consulted. As Damien Zammit, a former contributor noted, the
word "we" on old Libreboot notices meant "Leah". But alas, there is no room for
the "royal we" in democracy.

Finally, on a personal note, Leah was at the time struggling with gender
dysphoria and substance abuse. Since then, she has been managing these issues.
She agrees that her behaviour was rash and is determined to find a unifying
solution.

With all of this in mind, were the allegations against the Free Software
Foundation true? Perhaps. Perhaps not. At this point, it doesn't matter.
Indeed, it is unlikely that Libreboot will ever rejoin GNU, but feuding in an
already fragmented community helps nobody. The world of free software is
shrinking and under attack. Though the FSF may make mistakes from time to time,
so do we. We do not need another divide.

Similarly, we would like to work closely with librecore, another project
working to deblob coreboot, whose team includes Damien Zammit. Once librecore
matures, libreboot plans to switch to librecore in lieu of our current
deblobbed fork. That is, there will be less duplication of effort; instead of
competing with librecore, libreboot will complement it.

As a technical update, we are currently working on a Libreboot port to
the X220. Leah and Swift are investigating ways to disable the ME on
Sandybridge hardware, which potentially means more modern Intel hardware may be
supported. Additionally, Paul Kocialkowski has been working on supporting
several new Chromebooks with ARM chips; these ports will also be available in
an upcoming release.

No more "royal we". No more notorious surprises. No more late night
"typofixes".

Transparency and collaboration are the way forward.

~Alyssa Rosenzweig

### A message from Leah, to further complement Alyssa's submission:

I acknowledge that what I did was wrong. Although I felt justified at the time,
I ended up hurting a lot of people, most of whom were uninvolved with any of
the relevant events. At the time of taking Libreboot out of GNU, I was going
through intense personal difficulty in my life, and I was highly unstable.
Presented with a similiar situation, I likely won't respond the way I did
before. I've changed a lot, and I promise this type of thing won't happen
again.

What I'd like the most, is to simply focus on Libreboot as I've always done,
and to forget about what happened in the past and move on.

I sincerely hope that the FSF, GNU project and others who I have hurt, can do
the same. My only goal at present is to continue improving Libreboot, and to do
everything in my power to make libre hardware a reality for everyone, as is the
goal of the Libreboot project.

I will remain in my place as a developer in this project, but everything that I
do from now on will be the result of open collaboration with others in the
project. I very nearly single handedly destroyed this project, and caused a lot
of damage to the entire community, damage which I now wish to repair. I love
Libreboot, Free Software and the community, and my only wish is to see it
thrive.

I wish well any and all outreach organisations that do work with the FSF; e.g.
Outreachy, who are working to do what they can to improve conditions for women,
LGBT people and other minorities in the sphere of computing and engineering
fields, related to Free Software.

I hope that any damage I caused to the community is not permanent.

I'm deeply sorry for the damage and upset that I caused. I will not repeat the
same mistakes twice. To a very specific person, who cannot be named in the
interest of their privacy, but for whom context will allow that person
to know this is for them: I'm especially sorry for the damage that I did to
you during those months, and I sincerely hope that you get what you are
currently seeking. I fully support you in your endeavour, and if I could help
you, I would. You still mean a great deal to me.

I'm especially sorry to John Sullivan and Ruben Rodriguez of the FSF, both of
whom I publicly slandered on the Libreboot website. They did not deserve any of
that. I was being highly abusive towards you both.

I would also like to express my sincerest apology to those GNU maintainers
whose emails I published on the Libreboot website, when all of that chaos was
underway.

I'm sorry to all the other Libreboot maintainers at the time, some of whom felt
like they had no choice but to quit the project because of my actions. Doubly
so for Damien Zammit and Timothy Pearson, both of whom I let down in various
ways afterwards aswell.

I would like to sincerely apologize to Timothy Pearson of Raptor Engineering
in particular, for the damage that I caused with Libreboot's exit from GNU,
while you were running your TALOS workstation campaign. Although I do not know
whether the campaign would have succeeded without all that chaos, my own
actions certainly did not help.

Finally, I would like to once again apologize to the community as a whole, for
the damage that I caused. I hope that I can prove to you all that I do wish to
make amends for the damage, and to improve, and to re-build bridges with the
community, and to once again work with the community in bringing Libreboot and
Free Software forward, into the future.

~Leah Rowe


code:
#!/usr/bin/env bash
#
# Copyright (C) 2017 Alyssa Rosenzweig <alyssa@rosenzweig.io>
# Copyright (C) 2017 Leah Rowe <info@minifree.org>
# Copyright (C) 2017 Michael Reed <michael@michaelreed.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

[ "x${DEBUG+set}" = 'xset' ] && set -v
set -e

FILE=${1%.md}
TMPFILE=$(mktemp -t libreboot_www.XXXXXXXXXX)

cat "$1" > "$TMPFILE"

OPTS="-T Libreboot"

if [[ $FILE == "index" || $FILE == "./index" ]]; then
        OPTS="--css /headercenter.css"
else
        if [[ $FILE == *suppliers ]]
        then
            RETURN=""
        else
            if [[ $FILE == *index ]]
            then
                DEST="../"
            else
                DEST="./"
            fi

            RETURN="Edit this page -- Back to previous index"
            OPTS="-T Libreboot"
        fi
fi

if [[ $FILE = *suppliers ]]; then
        printf '\n%s\n' "Edit this page -- Back to previous page" >> "$TMPFILE"
fi

if [[ $FILE != "./docs/fdl-1.3" && $FILE != "docs/fdl-1.3" &&
      $FILE != "./conduct"      && $FILE != "conduct" ]]; then
    cat footer.md >> "$TMPFILE"
fi

# change out .md -> .html
sed -i -e 's/\.md\(#[a-zA-Z0-9_-]*\)\?\([])]*\)/.html\1\2/g' "$TMPFILE"

# work around issue #2872
TOC=$(grep -q "^x-toc-enable: true$" "$TMPFILE" && printf '%s\n' "--toc --toc-depth=2") || TOC=""

# work around heterogenous pandoc versions
SMART=$(pandoc -v | grep -q '2\.0' || printf '%s\n' "--smart") || SMART=""

# chuck through pandoc
#
# $OPTS must not be quoted, otherwise pandoc interprets '--css /headercenter.css'
# as one argument, when it is actually two.
pandoc $TOC $SMART "$TMPFILE" -s --css /global.css $OPTS \
        --template template.html --metadata return="$RETURN" > "$FILE.html"

# generate section title anchors as [link]
sed -i -e 's_^<h\([123]\) id="\(.*\)">\(.*\)</h\1>_
<h\1 id="\2">\3</h\1>[link]
_' "$FILE.html"

# clean up temporary file
rm -f "$TMPFILE"


code:
---
title: Suppliers selling Libreboot pre-installed
...

Libiquity
---------

Patrick McDermott, Libiquity's founder, is a former Libreboot
developer. **Ships to USA only**

-   [Taurinus X200 laptop](https://shop.libiquity.com/product/taurinus-x200) (FSF RYF certified)
-   [Libreboot chassis](https://shop.libiquity.com/product/libreboot-stickers-shaped-matte-vinyl-2x2.25-3-pack) and [Libreboot Inside stickers](https://shop.libiquity.com/product/libreboot-inside-case-badges-3-pack)

Home page:
<https://shop.libiquity.com/>

Ministry of Freedom (Minifree)
------------------------------

Leah Rowe, Minifree's founder, is also Libreboot's founder and is an active
Libreboot developer. Minifree is the first company to achieve FSF RYF
endorsement on a computer system, and invests money directly into Libreboot.

**Minifree ships worldwide, to all countries.**

Routers:

-   [Libre WNDR3800 Router](https://minifree.org/product/minifree-wndr3800-libre-router/) (FSF RYF pending)

Laptops:

-   [Libreboot X200 laptop](https://minifree.org/product/libreboot-x200/) (FSF RYF certified)
-   [Libreboot T400 laptop](https://minifree.org/product/libreboot-t400/) (FSF RYF certified)
-   [Libreboot X200 Tablet laptop](https://minifree.org/product/libreboot-x200-tablet/) (FSF RYF certified)

Services:

-   [Hardware and software based security enhancements for Libreboot laptops](https://minifree.org/product/security-mods/)
-   [Libreboot installation service](https://minifree.org/product/libreboot-installation-service/)
-   [Libreboot chip flashing service for ASUS KGPE-D16 and KCMA-D8](https://minifree.org/product/d8-d16-chipflash/)

Merchandise:

-   [Libreboot T400 battery](https://minifree.org/product/libreboot-t400-battery/)
-   [Libreboot X200 battery](https://minifree.org/product/libreboot-x200-battery/)
-   [Libreboot X200 Tablet battery](https://minifree.org/product/libreboot-x200-tablet-battery/)
-   [Libreboot X200/X200T docking station](https://minifree.org/product/docking-station-for-libreboot-x200/)
-   [Libreboot stickers](https://minifree.org/product/libreboot-stickers/)

Home page:
<https://minifree.org/>

Phreedom 2600
------------------

Phreedom 2600 sells the BeagleBone Black (which can be used for flashing Libreboot)
and the Thinkpad X200. All computers come with Parabola GNU/Linux preinstalled.
All products meets the criteria for [Respects Your Freedom](https://fsf.org/ryf).

Home page:
<https://shop.phreedom2600.net/>

Raptor Engineering
------------------

Raptor is the world's first libre OEM, producing systems with libre boot
firmware and operating system preinstalled, *from the factory*.

Website for pre-orders:
<https://www.raptorcs.com/TALOSII/>

They have 2 systems available:

- [TALOS II Lite](https://secure.raptorcs.com/content/TL1BC1/purchase.html)
  (this is the cheaper version)
- [TALOS II](https://secure.raptorcs.com/content/TL2WK2/intro.html)

NOTE: this isn't technically Libreboot, but the boot firmware is entirely free.

This is the same company that ported the ASUS KFSN4-DRE, KGPE-D16 and KCMA-D8
mainboards to Libreboot. Raptor has also helped improve other ports in Libreboot,
for instance they added support for *switchable graphics* on the ThinkPad T400
which Libreboot supports.

Home page:
<https://www.raptorcs.com/>

Technoethical
-------------

Technoethical (formerly Tehnoetic) is a team of free software activists and
developers that are selling hardware pre-installed with libreboot as a way to
fund the activity within their nonprofit foundation.

**Ships worldwide, to all countries.**

Services:

-   [Libreboot installation service](https://tehnoetic.com/tet-lis)

Laptops:

-   [Technoethical T500 laptop](https://tehnoetic.com/tet-t500)
-   [Technoethical T400 laptop](https://tehnoetic.com/tet-t400)
-   [Technoethical T400S laptop](https://tehnoetic.com/tet-t400s)
-   [Technoethical X200 Tablet laptop](https://tehnoetic.com/tet-x200t)
-   [Technoethical X200 laptop](https://tehnoetic.com/tet-x200)

Home page:
<https://tehnoetic.com/>

Vikings
-------

Vikings is the first company to offer hosting on hardware pre-installed with
libreboot and they are also selling the hardware itself to fund the building
of their libreboot-powered datacenter.

**Ships worldwide, to all countries.**

Servers:

-   [Vikings D16 1U server](https://store.vikings.net/libre-friendly-hardware/the-server-1u)

Mainboards:

-   [Vikings D16 mainboard](https://store.vikings.net/libre-friendly-hardware/d16-ryf-certfied) (FSF RYF certified)

Desktops:

-   [Vikings D16 workstation](https://store.vikings.net/libre-friendly-hardware/vikings-d16-workstation)

Laptops:

-   [Vikings X200 laptop](https://store.vikings.net/libre-friendly-hardware/x200-ryf-certfied) (FSF RYF certified)

Home page:
<https://vikings.net/>

Other suppliers
===============

Sellers on eBay
---------------

On the eBay website, in various countries, you can search for libreboot and
you may find some individual sellers providing Libreboot-preinstalled hardware.

We cannot verify the quality of these suppliers, but they do exist.

Some of them also provide choice of GNU+Linux distribution, or they may provide
services where you can ship your Libreboot-compatible device to them and they
would install Libreboot for you.

This can be useful for some people, but due to the nature of eBay, we cannot
link to them since eBay listings are regularly deleted due to expiration (some
sellers may choose to have longer listings, or renew expired listings).

There may also be other websites similar to eBay (e.g. mercado livre, available
for several South American countries) that might have Libreboot hardware on
them.

**If you are considering purchasing from a supplier on eBay, make sure to read
their feedback comments for other products that they sell, and check their
seller rating. Don't get duped by a bad seller!**

Workshops/hackerspaces
----------------------

You may have a GNU+Linux User Group, free software workshop or hackerspace near
you that can help you with installing Libreboot, for instance.


code:
<!DOCTYPE html>

  <meta charset="utf-8">
  <meta name="generator" content="pandoc">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
$for(author-meta)$
  <meta name="author" content="$author-meta$">
$endfor$
$if(date-meta)$
  <meta name="dcterms.date" content="$date-meta$">
$endif$
$if(keywords)$
  <meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$">
$endif$
  <title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
$if(quotes)$

$endif$
$if(highlighting-css)$

$endif$
$for(css)$
  <link rel="stylesheet" href="$css$">
$endfor$
$if(math)$
  $math$
$endif$
$for(header-includes)$
  $header-includes$
$endfor$
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/feed.xml"/>

$for(include-before)$
$include-before$
$endfor$
$if(title)$

$title$

$if(subtitle)$

$subtitle$

$endif$
$for(author)$

$author$

$endfor$
$if(date)$

$date$

$endif$

$endif$
$if(return)$
$return$
$endif$
$if(toc)$

$toc$

$endif$
$body$
$for(include-after)$
$include-after$
$endfor$


code:
.directory
.fuse*
*.pisi
*.pyc
*.svn
*~
.dir*
*.kate-swp

repo_name: ayhanyalcinsoy/main

path: .gitignore


code:
Herhangi bir paketin *-devel paketinin ba??ml?l???n?n tam olarak yaz?lmas?, pakete ba??ml? di?er paketlerinde d?zg?n bir ?ekilde derlenmesi sa?layacakt?r. Bu sebeple yap?lan, derlenen paketlerin, derlendikten sonra;

checkelf -s -x *.pisi

??kt?s?n?n haricinde bir yolu daha var ki buda, derlenme dizinine gidip (/var/pisi/*) buradaki install dizinimizde /usr/lib/pkgconfig/*.pc i?erisindeki *.pc dosyas?n?n i?eri?ini okumakt?r.

Bu dosyan?n i?erisinde;

Requires.private:
Requires:

yani ba??ml? ve ?zel ba??ml? olarak kar??s?nda ba??ml? paketler yazmaktad?r. burada yazanlar? pisi sf ile sistemde tart?p ne oldu?unu bulabiliriz.

?rnek;

libaccounts-glib  paketinin :  install dizini /var/pisi/libaccounts-glib-1.21-1/install

pkgconfig dizini : /var/pisi/libaccounts-glib-1.21-1/install/usr/lib/pkgconfig/libaccounts-glib.pc

libaccounts-glib.pc dosyas?n?n i?eri?i;

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
applicationfilesdir=${prefix}/share/accounts/applications
servicefilesdir=${prefix}/share/accounts/services
servicetypefilesdir=${prefix}/share/accounts/service_types
providerfilesdir=${prefix}/share/accounts/providers

Name: libaccounts-glib
Description: A low-level library for managing accounts settings.
Requires: glib-2.0 gobject-2.0 gio-unix-2.0
Require.private: libxml-2.0 sqlite3
Version: 1.21
Libs: -L${libdir} -laccounts-glib
Cflags: -I${includedir}

konsolu a??p;

pisi sf glib-2.0 (?ok fazla sonu? ??kacakt?r ama i?lerinden bu glib-2.0 bulmak zor de?il ismiyle ayn? paket olacak)

glib2-devel paketi oldu?unu ??reneceksiniz.

-devel ba??ml?l?klar?n? bu ?ekilde bulabiliriz.


code:
#!/usr/bin/python
#
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008, TUBITAK/UEKAE
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.
#

import sys
import multiprocessing

import urllib2
import bz2
import lzma

import piksemel

import pisi
import pisi.dependency as dependency
from pisi.graph import CycleException

class SourceDB:
    def __init__(self, index):

        self.__source_nodes = {}
        self.__pkgstosrc = {}

        doc = piksemel.parseString(index)
        self.__source_nodes, self.__pkgstosrc = self.__generate_sources(doc)

    def __generate_sources(self, doc):
        sources = {}
        pkgstosrc = {}

        for spec in doc.tags("SpecFile"):
            src_name = spec.getTag("Source").getTagData("Name")
            sources[src_name] = spec.toString()
            for package in spec.tags("Package"):
                pkgstosrc[package.getTagData("Name")] = src_name

        return sources, pkgstosrc

    def has_spec(self, name):
        return self.__source_nodes.has_key(name)

    def get_spec(self, name):
        src = self.__source_nodes[name]
        spec = pisi.specfile.SpecFile()
        spec.parse(src)
        return spec

    def list_specs(self):
        return self.__source_nodes.keys()

    def pkgtosrc(self, name):
        return self.__pkgstosrc[name]

def find_circle(sourcedb, A):

    G_f = pisi.graph.Digraph()

    def get_spec(name):
        if sourcedb.has_spec(name):
            return sourcedb.get_spec(name)
        else:
            raise Exception('Cannot find source package: %s' % name)

    def get_src(name):
        return get_spec(name).source

    def add_src(src):
        if not str(src.name) in G_f.vertices():
            G_f.add_vertex(str(src.name), (src.version, src.release))

    def pkgtosrc(pkg):
        try:
            tmp = sourcedb.pkgtosrc(pkg)
        except KeyError, e:
            # this is a bad hack but after we hit a problem we need to continue
            tmp = "e3"
            print "---> borks in ", e

        return tmp

    B = A

    install_list = set()

    while len(B) > 0:
        Bp = set()
        for x in B:
            sf = get_spec(x)
            src = sf.source
            add_src(src)

            # add dependencies

            def process_dep(dep):
                srcdep = pkgtosrc(dep.package)
                if not srcdep in G_f.vertices():
                    Bp.add(srcdep)
                    add_src(get_src(srcdep))
                if not src.name == srcdep: # firefox - firefox-devel thing
                    G_f.add_edge(src.name, srcdep)

            for builddep in src.buildDependencies:
                process_dep(builddep)

            for pkg in sf.packages:
                for rtdep in pkg.packageDependencies:
                    process_dep(rtdep)
        B = Bp

        try:
            order_build = G_f.topological_sort()
            order_build.reverse()
        except CycleException, cycle:
            return str(cycle)

    return ""

def getIndex(uri):
    try:
        if "://" in uri:
            rawdata = urllib2.urlopen(uri).read()
        else:
            rawdata = open(uri, "r").read()
    except IOError:
        print "could not fetch %s" % uri
        return None

    if uri.endswith("bz2"):
        data = bz2.decompress(rawdata)
    elif uri.endswith("xz") or uri.endswith("lzma"):
        data = lzma.decompress(rawdata)
    else:
        data = rawdata

    return data

def processPackage(pkg, sourcesLength, counter):
    global sourcedb

    sys.stdout.write("\r(%04d/%d) Calculating build dep of %s                       " % (counter, sourcesLength, pkg))
    sys.stdout.flush()

    return find_circle(sourcedb, [pkg])

def updateStatus(circleResult):
    global cycles
    cycles.add(circleResult)

if __name__ == "__main__":

    if len(sys.argv) < 2:
        print "Usage: circlefinder.py <source repo pisi-index.xml file>"
        sys.exit(1)

    rawIndex = getIndex(sys.argv[1])
    sourcedb = SourceDB(rawIndex)
    sources = sourcedb.list_specs()

    sourcesLength = len(sources)
    counter = 0

    global cycles
    cycles = set()

    pool = multiprocessing.Pool()

    for pkg in sources:
        counter += 1
        pool.apply_async(processPackage, (pkg, sourcesLength, counter), callback=updateStatus)

    pool.close()
    pool.join()

    if len(cycles):
        print
        for cycle in cycles:
            print cycle
    else:
        print "No circular dep found"

path: circledep-finder


code:
#!/usr/bin/python
# -*- coding: utf-8 -*-

import shutil
import sys
import re
import os

from optparse import OptionParser

def read_file(path):
    with open(path) as f:
        return f.read().strip()

def write_file(path, content):
    open(path, "w").write(content)
    open(path, "a").write("\n")

class Components():
    COMPONENT_XML = """<PISI>
    <Name>%s</Name>
</PISI>
"""
    EMPTY_COMPONENT = """        <Component>
            <Name>%s</Name>
            <LocalName xml:lang="en">FIXME</LocalName>
            FIXME
            <Description xml:lang="en">FIXME</Description>
            <Group>FIXME</Group>
            <Maintainer>
                <Name>PisiLinux Community</Name>
                <Email>admins@pisilinux.org</Email>
            </Maintainer>
        </Component>"""
    CBGN = """<PISI>
    <Components>"""
    CEND = """
    </Components>
</PISI>"""
    LOCALNAME = '            <LocalName xml:lang="%s">%s</LocalName>\n'
    SUMMARY = '            %s\n'
    DESCRIPTION = '            <Description xml:lang="%s">%s</Description>\n'
    COMPONENT = """
        <Component>
            <Name>%s</Name>
%s%s%s            <Group>%s</Group>
            <Maintainer>
                <Name>%s</Name>
                <Email>%s</Email>
            </Maintainer>
        </Component>"""

    def __init__(self, path):
        self.path = path
        self.components = []
        self.components_xml = "%s/components.xml" % self.path
        self.name_ptrn = re.compile("\s*<Name>(.+?)<\/Name>\s*")
        self.lnamech_ptrn = re.compile("\s*<LocalName.*?>(.+?)<\/LocalName>\s*")
        self.lname_ptrn = re.compile("\s*<LocalName\s+xml:lang\s?=\s?[\'\"](\w\w.*?)[\'\"]\s?>(.+?)<\/LocalName>\s*")
        self.summarych_ptrn = re.compile("\s*(.+?)<\/Summary>\s*")
        self.summary_ptrn = re.compile("\s*(.+?)<\/Summary>\s*")
        self.descch_ptrn = re.compile("\s*<Description.*?>(.+?)<\/Description>\s*")
        self.desc_ptrn = re.compile("\s*<Description\s+xml:lang\s?=\s?[\'\"](\w\w.*?)[\'\"]\s?>(.+?)<\/Description>\s*")
        self.group_ptrn = re.compile("\s*<Group>(.+?)<\/Group>\s*")
        self.email_ptrn = re.compile("\s*<Email>(.+?)<\/Email>\s*")
        self.cbgn_ptrn = re.compile("\s*<Component>\s*")
        self.cend_ptrn = re.compile("\s*<\/Component>\s*")
        self.mbgn_ptrn = re.compile("\s*<Maintainer>\s*")
        self.mend_ptrn = re.compile("\s*<\/Maintainer>\s*")
        self.csend_ptrn = re.compile("\s*<\/Components>\s*")

    def read_components(self):
        csfile = read_file(self.components_xml)
        cread = False
        mread = False
        component = {}
        for line in csfile.split("\n"):
            if re.search(self.cbgn_ptrn, line):
                cread = True
                component["err"] = []
                component["unknown"] = []
                component["clname"] = []
                component["csummary"] = []
                component["cdesc"] = []
                continue
            elif re.search(self.cend_ptrn, line):
                cread = False
                self.components.append(component)
                component = {}
                continue
            if cread:
                if re.search(self.mbgn_ptrn, line):
                    mread = True
                    continue
                elif re.search(self.mend_ptrn, line):
                    mread = False
                    continue
                elif re.search(self.name_ptrn, line):
                    if mread: component["mname"] = re.sub(self.name_ptrn, r"\1", line)
                    else: component["cname"] = re.sub(self.name_ptrn, r"\1", line)
                elif re.search(self.lnamech_ptrn, line):
                    if re.search(self.lname_ptrn, line):
                        component["clname"].append(re.sub(self.lname_ptrn, r"\1:\2", line))
                    else:
                        component["err"].append("LocalName")
                elif re.search(self.summarych_ptrn, line):
                    if re.search(self.summary_ptrn, line):
                        component["csummary"].append(re.sub(self.summary_ptrn, r"\1:\2", line))
                    else:
                        component["err"].append("Summary")
                elif re.search(self.descch_ptrn, line):
                    if re.search(self.desc_ptrn, line):
                        component["cdesc"].append(re.sub(self.desc_ptrn, r"\1:\2", line))
                    else:
                        component["err"].append("Description")
                elif re.search(self.group_ptrn, line):
                    component["cgroup"] = re.sub(self.group_ptrn, r"\1", line)
                elif re.search(self.email_ptrn, line):
                    component["memail"] = re.sub(self.email_ptrn, r"\1", line)
                else: component["unknown"].append(line)

    def sort_components(self):
        self.components = sorted(self.components, key=lambda k: k['cname'])

    def backup_components(self):
        files = os.walk(self.path).next()[2]
        last = 0
        for f in files:
            if f.startswith("components.xml.") and int(f[-3:]) > last: last = int(f[-3:])
        last = str(last + 1)
        while len(last) < 3: last = "0" + last
        shutil.copyfile(self.components_xml, ".".join((self.components_xml, last)))

    def write_components(self):
        self.sort_components()
        cs = ''
        for c in self.components:
            ln = ""
            for i in c["clname"]:
                ln += self.LOCALNAME % tuple(i.split(":"))
            s = ""
            for i in c["csummary"]:
                s += self.SUMMARY % tuple(i.split(":"))
            d = ""
            for i in c["cdesc"]:
                d += self.DESCRIPTION % tuple(i.split(":"))
            cs += self.COMPONENT % (c["cname"], ln, s, d, c["cgroup"], c["mname"], c["memail"])
        self.backup_components()
        open(self.components_xml, "w").write(self.CBGN)
        open(self.components_xml, "a").write(cs)
        open(self.components_xml, "a").write(self.CEND)
        open(self.components_xml, "a").write("\n")

    def edit(self):
        l = []
        mcommands = {"q": "quit",
                    "l": "list components",
                    "c": "choose component",
                    "h": "help"}
        ecommands = {"mn": "set maintainer name",
                     "me": "set maintainer email",
                     "ln": "set local name (lang:name)",
                     "s": "set summary (lang:summary)",
                     "d": "set description (lang:description)",
                     "m": "main menu",
                     "w": "write",
                     "h": "help"}

        def read_command(m):
            opts = mcommands.keys() if m == "m" else ecommands.keys()
            return (opts, raw_input(":".join(sorted(opts)) + " > ").split())

        def list_components(param, regexp = True):
            res = []
            num = 0
            if not param: param = ".*"
            for c in self.components:
                if regexp and re.search(param, c["cname"]):
                    res.append(c["cname"])
                    print num, c["cname"]
                    num += 1
                elif not regexp and param == c["cname"]:
                    res.append(c["cname"])
                    break
            return res

        def get_component_data(name):
            #print self.components
            for c in self.components:
                if name == c["cname"]: return c
            print "Component %s not found!" % name
            return False

        def print_help(hdict):
            for i in iter(sorted(hdict.iteritems())):
                print i[0] + "\t" + i[1]

        def edit_loop(component):
            def update(key, val, data):
                d = val.split(":")
                if not len(d) == 2: print "Wrong param format! (ln lang:text)"
                else:
                    lexists = -1
                    for i in data[key]:
                        if i.split(":")[0] == d[0]:
                            lexists = data[key].index(i)
                            break
                    if lexists > -1: data[key][lexists] = val
                    else: data[key].append(val)
                return data

            data = get_component_data(component)
            while True:
                print "-" * (len(component) + 8)
                print "Editing " + component
                print "-" * (len(component) + 8)
                print "LocalName:"
                for i in data["clname"]: print "  %s" %i
                print "Summary:"
                for i in data["csummary"]: print "  %s" %i
                print "Description:"
                for i in data["cdesc"]: print "  %s" %i
                print "Group:\n  %s" % data["cgroup"]
                print "Maintainer name:\n  %s" % data["mname"]
                print "Email:\n  %s" % data["memail"]
                o, c = read_command("c")
                if not c[0] in o: continue
                if len(c) == 1: c.append("")
                if c[0] == "m": break
                elif c[0] == "h": print_help(ecommands)
                elif c[0] == "ln": data = update("clname", c[1], data)
                elif c[0] == "s": data = update("csummary", c[1], data)
                elif c[0] == "d": data = update("cdesc", c[1], data)
                elif c[0] == "mn": data["mname"] = c[1]
                elif c[0] == "me": data["memail"] = c[1]
                elif c[0] == "w":  self.write_components()
                else: print"%s is not implemented yet" % c[0]

        def edit_component(param, l):
            try:
                int(param)
                edit_loop(l[int(param)])
            except ValueError:
                l = list_components(param, regexp = False)
            if not len(l) == 1: print "Component %s not found" % param
            else: edit_loop(l[0])

        while True:
            o, c = read_command("m")
            if len(c) == 1: c.append("")
            if not c[0] in o: continue
            elif c[0] == "q": break
            elif c[0] == "l": l = list_components(c[1])
            elif c[0] == "c": edit_component(c[1], l)
            elif c[0] == "h": print_help(mcommands)
            else: print"%s is not implemented yet" % c[0]

    def check(self):
        cs = []
        for root, dirs, files in os.walk(self.path):
            c = root.split(self.path)[1][1:].split("/")
            if "files" in c or "comar" in c: continue
            c = ".".join(c)
            component_xml = "%s/component.xml" % root
            pspec_xml = "%s/pspec.xml" % root
            actions_py = "%s/actions.py" % root
            if not os.path.isfile(component_xml) and not os.path.isfile(pspec_xml):
                if os.path.isfile(actions_py): print "WARNING: %s not exists" % pspec_xml
                else:
                    is_src_repo = False
                    for r, d, f in os.walk(root):
                        if "pspec.xml" in f:
                            is_src_repo = True
                            break
                    if is_src_repo and c:
                        print "%s not exists. creating..." % component_xml
                        write_file(component_xml, self.COMPONENT_XML % c)
            if os.path.isfile(component_xml) and c: cs.append(c)

        mcs = cs[:]
        csfile = read_file(self.components_xml)
        maintainer = False
        new_file = []
        for line in csfile.split("\n"):
            new_file.append(line)
            if re.search(self.mbgn_ptrn, line): maintainer = True
            elif re.search(self.mend_ptrn, line): maintainer = False
            elif re.search(self.csend_ptrn, line):
                for m in mcs:
                    new_file.insert(-1, self.EMPTY_COMPONENT % m)
            if not re.search(self.name_ptrn, line) or maintainer: continue
            cn = re.sub(self.name_ptrn, r"\1", line)
            if cn in mcs: mcs.pop(mcs.index(cn))

        new_file = "\n".join(new_file)
        write_file(self.components_xml, new_file)

if __name__ == "__main__":
    usage = "Usage: %prog [PATH]"
    parser = OptionParser(usage)
    parser.add_option("-c", "--check", action="store_true", dest="check", help="fix missing component.xml files and entries in components.xml")
    parser.add_option("-e", "--edit", action="store_true", dest="edit", help="edit components.xml")
    (options,args) = parser.parse_args()
    try:
        root = args[0]
    except IndexError:
        print "Using ./ as PATH"
        root = "./"

    if root.endswith("/"): root = root[:-1]

    cs = Components(root)
    if not os.path.isfile(cs.components_xml):
        print "%s not exists!" % cs.components_xml
        sys.exit(1)
    if not os.access(cs.components_xml, os.W_OK):
        print "Cannot write to %s" % cs.components_xml
        sys.exit(1)
    cs.read_components()

    if options.check: cs.check()
    if options.edit:
        cs.edit()